Cancel
Showing results for 
Search instead for 
Did you mean: 

Error when calling GetMaterialListFromLibrary more times

Creator
Creator

SolidEdge version 219.00.06.004 is used.  

I need to get a list of all materials in all libraries. For this, I tried to use the following code:

 

// libFileList contains items
// C:\Siemens\Preferences\Materials\Materials.mtl
// C:\Siemens\Preferences\Materials\Materials-DIN.mtl
// C:\Siemens\Preferences\Materials\Materials-GOST.mtl
private Dictionary<string, List<string>> GetMatMap(List<string> libFileList) {
    var res = new Dictionary<string, List<string>>();
    try {
        // create application instance, register message filter, etc.
        matTable = app.GetMaterialTable();
        foreach(string libPath in libFileList) {
            // next line works only first time
            matTable.GetMaterialListFromLibrary(libPath, out int numMaterials, out object listOfMaterials);
            var matList = ((object[])listOfMaterials).Select(x => x.ToString()).ToList();
            res.Add(libPath, matList);
        }
        return res;
    }
    catch (Exception ex) {
        logger.Error(() => ex);
        throw;
    }
    finally {
        // unregister message filter, etc.
    }
}

 

The above code works, but only the first time you call the GetMaterialListFromLibrary method.  Subsequent calls to the method throw an exception:

Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE)
// StackTrace:
// at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
// at SolidEdgeFramework.MatTable.GetMaterialListFromLibrary(String bstrLibraryName, Int32& plNumMaterials, Object& listOfMaterials)

 

But if the cycle is transferred from the method to the external code, then the code works without problems:

// somewhere in another method
var matMap = new Dictionary<string, List<string>>();
foreach(string path in libFileList) {
    matMap.Add(path, GetMatMap(path));
}
// ... anything

private List<string> GetMatMap(string libPath) {
    var res = new Dictionary<string, List<string>>();
    try {
        // create application instance, register message filter, etc.
        matTable = app.GetMaterialTable();
        matTable.GetMaterialListFromLibrary(libPath, out int numMaterials, out object listOfMaterials);
        return ((object[])listOfMaterials).Select(x => x.ToString()).ToList();
    }
    catch (Exception ex) {
        logger.Error(() => ex);
        throw;
    }
    finally {
        // unregister message filter, etc.
    }
}

Why, when calling the GetMaterialListFromLibrary method several times, it works only the first time, and throws an exception on all subsequent calls?

2 REPLIES 2
Highlighted

Re: Error when calling GetMaterialListFromLibrary more times

Solution Partner Phenom Solution Partner Phenom
Solution Partner Phenom

@Demin,

 

you may try to set the out variables numMaterials and listOfMaterials explicitely to null before recalling matTable.GetMaterialListFromLibrary.

 

The reason: Out parameters must not be initialized.

Kind regards,
Wolfgang Kunert - www.wksyspro.de

Re: Error when calling GetMaterialListFromLibrary more times

Creator
Creator

@wku  thanks for your reply and advice! 

You were right, initializing the variables before re-calling solved the problem:

private Dictionary<string, List<string>> GetMatMap(List<string> libFileList) {
    var res = new Dictionary<string, List<string>>();
    try {
        // create application instance, register message filter, etc.
        matTable = app.GetMaterialTable();
        foreach(string libPath in libFileList) {
            int numMaterials = 0;
            object listOfMaterials = null;
            matTable.GetMaterialListFromLibrary(libPath, out numMaterials, out listOfMaterials);
            var matList = ((object[])listOfMaterials).Select(x => x.ToString()).ToList();
            res.Add(libPath, matList);
        }
        return res;
    }
    catch (Exception ex) {
        logger.Error(() => ex);
        throw;
    }
    finally {
        // unregister message filter, etc.
    }
}