Question

I am extending an existing InstallScript project and need to call a method in an assembly that targets .NET 4.0.

The project already calls a method in another class in the same assembly: so I know that much works.

Mirroring what I see for the existing .NET method call, here is what I have so far:

//////////////////////////////////////////////////////////////////////////////
// SomeFunction
//
// Wraps SomeAssembly.SomeClass.SomeMethod.
//////////////////////////////////////////////////////////////////////////////
prototype number SomeFunction();
function number SomeFunction()
    string szDLL, szAssemblyandClassName;
    OBJECT oSomeClass;
    number nResult;
begin
    ChangeDirectory(SRCDIR); // changed from ChangeDirectory(SUPPORTDIR), which yielded error number -2147219705 in the try-catch below
    szDLL = "SomeAssembly.dll";
    szAssemblyAndClassName = "SomeAssembly.SomeClass";

    try
        SprintfBox(INFORMATION, "Debug", "Calling DotNetCoCreateObject(\"%s\", \"%s\", \"\")..."), szDLL, szAssemblyAndClassName); // FORNOW
        set oSomeClass = DotNetCoCreateObject(szDLL, szAssemblyAndClassName, "");
    catch
        SprintfBox(SEVERE, "Error", "Error %i:\n\n%s\n\n%s", Err.Number, Err.Description, Err.LastDllError);
        abort;
    endcatch;

    SprintfBox(INFORMATION, "Debug", "Calling oSomeClass.SomeMethod()..."); // FORNOW
    nResult = oSomeClass.SomeMethod();
    SprintfBox(INFORMATION, "Debug", "oSomeClass.SomeMethod() returned %i.", nResult); // FORNOW
    
    return nResult;
end;

When SomeFunction() executes in the setup I have built, I see the following output...

Calling DotNetCoCreateObject("SomeAssembly.dll", "SomeAssembly.SomeClass", "")...

Calling oSomeClass.SomeMethod()...

..., but then the setup immediately exits without any apparent error. Getting no indication of what goes wrong makes this frustrating to troubleshoot. Searching for a likely cause, I have found nothing so far.

Why would oSomeClass.SomeMethod() cause the setup to exit immediately with no apparent error?

EDIT:

Per @MichaelUrman's comment asking for more details about what differs between the existing class (OrigClass) that works and the new one (SomeClass) that does not:

  • Both classes are public sealed.
  • Both classes have an implicit default constructor - no explicit constructors.
  • Both methods (OrigMethod and SomeMethod) are public.
  • Neither class or method is marked with the ComVisible attribute; but their assembly (SomeAssembly) has [assembly: ComVisible(true)] in its AssemblyInfo.cs.

The differences between Existing.rul (that successfully integrates with SomeAssembly.OrigClass.OrigMethod) and New.rul (that does not successfully integrate with SomeAssembly.SomeClass.SomeMethod) are as follows (using a patch file):

2c2
< // OrigFunction
---
> // SomeFunction
4c4
< // Wraps SomeAssembly.OrigClass.OrigMethod.
---
> // Wraps SomeAssembly.SomeClass.SomeMethod.
6,7c6,7
< prototype number OrigFunction();
< function number OrigFunction()
---
> prototype number SomeFunction();
> function number SomeFunction()
9c9
<     OBJECT oOrigClass;
---
>     OBJECT oSomeClass;
14c14
<     szAssemblyAndClassName = "SomeAssembly.OrigClass";
---
>     szAssemblyAndClassName = "SomeAssembly.SomeClass";
18c18
<         set oOrigClass = DotNetCoCreateObject(szDLL, szAssemblyAndClassName, "");
---
>         set oSomeClass = DotNetCoCreateObject(szDLL, szAssemblyAndClassName, "");
24,26c24,26
<     SprintfBox(INFORMATION, "Debug", "Calling oOrigClass.OrigMethod()..."); // FORNOW
<     nResult = oOrigClass.OrigMethod();
<     SprintfBox(INFORMATION, "Debug", "oOrigClass.OrigMethod() returned %i.", nResult); // FORNOW
---
>     SprintfBox(INFORMATION, "Debug", "Calling oSomeClass.SomeMethod()..."); // FORNOW
>     nResult = oSomeClass.SomeMethod();
>     SprintfBox(INFORMATION, "Debug", "oSomeClass.SomeMethod() returned %i.", nResult); // FORNOW

OrigFunction and SomeFunction use a try-catch-endcatch to respectively ensure that oOrigClass and oSomeClass are set to a valid reference. The InstallScript Language Reference's DotNetCoCreateObject documentation explains that "[the] function throws an exception if the object cannot be created".

Was it helpful?

Solution

The problem turned out to have a simple explanation.

There was a mismatch between SomeMethod in oSomeClass.SomeMethod() and the actual name of the .NET SomeClass method available to call - i.e. oSomeClass.SomeMethod() should have been oSomeClass.SomeOtherMethod().

In my case, the mismatch was not so drastic and simply due to pluralization I initially overlooked in the defined .NET method's name - e.g. oSomeClass.SomeStringMethod() (singular) where oSomeClass.SomeStringsMethod() (plural) was in order.

That the setup immediately exited without any apparent error made it a booger to identify the simple cause of the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top