Search code examples
c#interopnavisiondynamics-navdynamics-nav-2009

Navision C/AL Create error with C# COM dll


I'm developing a report for Navision 2009 SP1 (Classic Client), where the need for extra functionality unavailable in NAV has arisen.

I have created a COM dll in C#, installed it (using InstallShield "free" vs version) and created an automation variable in NAV. The class and interface are visible and I see the Print method, but when I try to CREATE the variable, I get the following error:

"Could not create an instance of the OLE control or Automation server identified by..... Check that the OLE control or Automation server is correctly installed and registered."

This is the code (just trying to get a connection going):

[ComVisible(true), Guid("080a97fb-321c-4a2f-b948-dd52ce263415"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IPrinterTest
{
    [DispId(1)]
    bool Print(string test, string bytesInStringRepresentation);
}

[ClassInterface(ClassInterfaceType.None), ComVisible(true), Guid("8d7b85a9-1a20-4ea0-a7d4-decf26632eee"), ProgId("Printer.PrinterTest")]
public class PrinterTest : IPrinterTest
{
    public PrinterTest()
    {

    }

    public bool Print(string test, string bytesInStringRepresentation)
    {
        return true;
    }
}

The production environment only has .NET Framework Client Profile (3.5 and 4.0), this means that Regasm is available (in 4.0) and that gacutil is not.

I'm assuming that there's something wrong with my code and not InstallShield, since the dll is available for selection in Navision,- and that the issue arises when I try to create the nav automation variable.

Best regards Marcus


Solution

  • Alright, so there's nothing wrong with the above code, and apparently Visual Studio also has an installer toolset.

    I created a new solution, recreated the library project and added the VS installer project instead of the InstallShield one. I made sure that the library assembly was strong signed and I added a TLB file that I generated to the "FileSystem" in the installer project. The installer project will automatically register the TLB file as a dependency, so the TLB file can be deleted from the "FileSystem" afterwards.

    With that setup I was able to correctly register the DLL for COM interop.

    So the key points to remember are:

    • If you have the same setup as I do (interface and class), make sure that both of them are ComVisible and public. Furthermore they need to have matching names, e.g. "IPrinterTest" & "PrinterTest".
    • Make sure that the assembly is strong signed.
    • You have to generate a TLB file for the DLL and add it to the installer "FileSystem".

    I'll edit this answer later with a blog post detailing the whole process.