AutoCAD 2014 - Automatic dll loading

AutoCAD 2014 - Automatic dll loading

andre_adc-dao
Advocate Advocate
8,474 Views
9 Replies
Message 1 of 10

AutoCAD 2014 - Automatic dll loading

andre_adc-dao
Advocate
Advocate

Hello everybody,

 

I used to add registry key to automatically load DLL at AutoCAD startup:

 

Example:

I add a key like this:

HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R19.1\ACAD-D005:40C\Applications\CustomApplicationName

And add the following value:

Description (string value): Description of application

LOADCTRLS (REG_DWWORD): 2

LOADER (string value): Complete path to the DLL to load

MANAGED (REG_DWORD): 0 (I also try 1)

 

This work very well with previous release but not with 2014. I add the folder of the DLL to the trust search path but it doesn't change anything. Curiously, if the path is not specified, I have a message to confirm the loading of my dll but it doesn't load. If I load the DLL manually everything work fine.

 

Anybody have an idea?

 

Regards,

 

André

 

 

 

0 Likes
Accepted solutions (1)
8,475 Views
9 Replies
Replies (9)
Message 2 of 10

dgorsman
Consultant
Consultant

I beleive MANAGED should be set to 1.  Is your DLL local to the computer or on a network?

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 3 of 10

andre_adc-dao
Advocate
Advocate

I try with 0 and 1. The DLL is local. It is not working only with AutoCAD 2014. It is working well with previous release.

 

Regards,

 

André

 

0 Likes
Message 4 of 10

owenwengerd
Advisor
Advisor

It sounds like your DLL is throwing an exception during initialization.

--
Owen Wengerd
ManuSoft
0 Likes
Message 5 of 10

andre_adc-dao
Advocate
Advocate

When loaded manually, it is working very well.

0 Likes
Message 6 of 10

philippe.leefsma
Alumni
Alumni

Hi Andred,

 

The MANAGED flag has to be set to one only if you are dealing with a managed (ie .Net) dll. The demand loading mechanism happens at a time AutoCAD may not be fully initialized, make sure you are not doing anything in the Initialize (IExtensionApplication) callback of your dll.

 

The following C# code illustrates how to write demand loading info into registry when run from the calling dll. You could eventually run it and see the result that it produces in the registry and also test if it can set up your dll for demand loading:

 

public void RegisterMe()
{
    //AutoCAD (or vertical) and Application keys
    Microsoft.Win32.RegistryKey acadKey =
        Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
            HostApplicationServices.Current.MachineRegistryProductRootKey);

    Microsoft.Win32.RegistryKey acadAppKey = acadKey.OpenSubKey("Applications", true);

    string curAssemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
    string curAssemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
    string curAssemblyFullName = System.Reflection.Assembly.GetExecutingAssembly().GetName().FullName;

    //already registered?
    String[] subKeyNames = acadAppKey.GetSubKeyNames();

    foreach (String subKeyName in subKeyNames)
    {
        if (subKeyName.Equals(curAssemblyName))
        {
            Microsoft.Win32.RegistryKey subkey = acadAppKey.OpenSubKey(subKeyName, true);
            subkey.SetValue("LOADER", curAssemblyPath, Microsoft.Win32.RegistryValueKind.String);
            subkey.Close();
            acadAppKey.Close();
            return;
        }
    }

    //create the addin key
    Microsoft.Win32.RegistryKey acadAppAddInKey = acadAppKey.CreateSubKey(curAssemblyName);

    acadAppAddInKey.SetValue("DESCRIPTION", curAssemblyFullName, Microsoft.Win32.RegistryValueKind.String);
    acadAppAddInKey.SetValue("LOADCTRLS", 14, Microsoft.Win32.RegistryValueKind.DWord);
    acadAppAddInKey.SetValue("LOADER", curAssemblyPath, Microsoft.Win32.RegistryValueKind.String);
    acadAppAddInKey.SetValue("MANAGED", 1, Microsoft.Win32.RegistryValueKind.DWord);

    acadAppKey.Close();
}

 

I assume you are not trying to load from a remote/network location? there have been security features added since 2014, take a look there for further info:

 

http://adndevblog.typepad.com/autocad/2013/07/all-you-need-to-know-about-autocad-secureload-au.html

 

http://adndevblog.typepad.com/autocad/2013/03/autocad-2014-and-security.html

 

I hope it helps.

 

Regards,

Philippe.



Philippe Leefsma
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 7 of 10

andre_adc-dao
Advocate
Advocate

Thank you for your reply,

 

I try both MANAGED flag set to 0 and 1 with no difference. As I said, it works very well from release 2010 to 2013 inclusively but not in 2014. I can load the DLL manually with no problem. The DLL was compiled using VS 2010 (not VS 2012 but it is supposed to support both version).

 

I'm using AutoCAD 2014 in French, maybe it is the problem because I found many bugs in 2014 relative to the language. Maybe, I will install an English version to see if there a difference.

 

Regards,

 

André

 

 

 

0 Likes
Message 8 of 10

andre_adc-dao
Advocate
Advocate

For your information, here is my routine in VB .NET.

 

    Private Sub AddLoader(ByVal Version As String, ByVal AppName As String, ByVal Description As String, ByVal DllName As String)

        Dim i As Integer
        Dim j As Integer

        Dim regAdsk As Microsoft.Win32.RegistryKey
        Dim regSubKey As Microsoft.Win32.RegistryKey
        Dim regKeyList() As String
        Dim regKeyApplications As Microsoft.Win32.RegistryKey
        Dim regKeyApplicationsList() As String
        Dim strProductName As String
        Dim strAcadRegKeyNamePrefix As String
        Dim bApplicationFound As Boolean = False

        strAcadRegKeyNamePrefix = "SOFTWARE\Autodesk\AutoCAD\" & Version

        regAdsk = My.Computer.Registry.LocalMachine.OpenSubKey(strAcadRegKeyNamePrefix)
        regKeyList = regAdsk.GetSubKeyNames

        For i = 0 To UBound(regKeyList)
            regSubKey = My.Computer.Registry.LocalMachine.OpenSubKey(strAcadRegKeyNamePrefix & _
                "\" & regKeyList(i))
            strProductName = My.Computer.Registry.GetValue("HKEY_Local_Machine\" & _
                strAcadRegKeyNamePrefix & "\" & regKeyList(i), "ProductName", "")

            If strProductName <> "" Then
                If Label3.Text = "" Then
                    Label3.Text = strProductName
                Else
                    Label3.Text = Label3.Text & ";" & strProductName
                End If
            End If

            regKeyApplications = My.Computer.Registry.LocalMachine.OpenSubKey(strAcadRegKeyNamePrefix & _
                "\" & regKeyList(i) & "\Applications")

            If Not regKeyApplications Is Nothing Then
                regKeyApplicationsList = regKeyApplications.GetSubKeyNames
                For j = 0 To UBound(regKeyApplicationsList)
                    If regKeyApplicationsList(i).Trim = AppName.Trim Then
                        bApplicationFound = True
                    End If
                Next

                If bApplicationFound = False Then
                    My.Computer.Registry.LocalMachine.CreateSubKey(strAcadRegKeyNamePrefix & _
                        "\" & regKeyList(i) & "\Applications\" & AppName.Trim)
                    My.Computer.Registry.SetValue("HKEY_Local_Machine\" & strAcadRegKeyNamePrefix & _
                        "\" & regKeyList(i) & "\Applications\" & AppName.Trim, "Description", _
                            Description, Microsoft.Win32.RegistryValueKind.String)
                    My.Computer.Registry.SetValue("HKEY_Local_Machine\" & strAcadRegKeyNamePrefix & _
                        "\" & regKeyList(i) & "\Applications\" & AppName.Trim, "LOADCTRLS", _
                            2, Microsoft.Win32.RegistryValueKind.DWord)
                    My.Computer.Registry.SetValue("HKEY_Local_Machine\" & strAcadRegKeyNamePrefix & _
                        "\" & regKeyList(i) & "\Applications\" & AppName.Trim, "MANAGED", _
                            0, Microsoft.Win32.RegistryValueKind.DWord)
                    My.Computer.Registry.SetValue("HKEY_Local_Machine\" & strAcadRegKeyNamePrefix & _
                        "\" & regKeyList(i) & "\Applications\" & AppName.Trim, "LOADER", _
                            DllName, Microsoft.Win32.RegistryValueKind.String)
                End If
            End If
        Next

    End Sub

 

Even with MANAGED is set to 0, it is working on older version of AutoCAD.

 

Regards,

 

André

 

 

0 Likes
Message 9 of 10

Balaji_Ram
Alumni
Alumni

Hi Andre,

 

Have you tried the sample code that my colleague Philippe had posted earlier ?

 

Here is the VB.Net equivalent of the code. I tested it with AutoCAD 2014 and it worked ok.

 

        <CommandMethod("RegMe")> _
        Public Sub RegisterMe()
            'AutoCAD (or vertical) and Application keys
            Dim acadKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(HostApplicationServices.Current.MachineRegistryProductRootKey)

            Dim acadAppKey As Microsoft.Win32.RegistryKey = acadKey.OpenSubKey("Applications", True)

            Dim curAssemblyName As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
            Dim curAssemblyPath As String = System.Reflection.Assembly.GetExecutingAssembly().Location
            Dim curAssemblyFullName As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().FullName

            'already registered?
            Dim subKeyNames As [String]() = acadAppKey.GetSubKeyNames()

            For Each subKeyName As [String] In subKeyNames
                If subKeyName.Equals(curAssemblyName) Then
                    Dim subkey As Microsoft.Win32.RegistryKey = acadAppKey.OpenSubKey(subKeyName, True)
                    subkey.SetValue("LOADER", curAssemblyPath, Microsoft.Win32.RegistryValueKind.[String])
                    subkey.Close()
                    acadAppKey.Close()
                    Return
                End If
            Next

            'create the addin key
            Dim acadAppAddInKey As Microsoft.Win32.RegistryKey = acadAppKey.CreateSubKey(curAssemblyName)

            acadAppAddInKey.SetValue("DESCRIPTION", curAssemblyFullName, Microsoft.Win32.RegistryValueKind.[String])
            acadAppAddInKey.SetValue("LOADCTRLS", 14, Microsoft.Win32.RegistryValueKind.DWord)
            acadAppAddInKey.SetValue("LOADER", curAssemblyPath, Microsoft.Win32.RegistryValueKind.[String])
            acadAppAddInKey.SetValue("MANAGED", 1, Microsoft.Win32.RegistryValueKind.DWord)

            acadAppKey.Close()
        End Sub

 Netload the dll and run the "regme" command. Now close AutoCAD and the plugin should be loaded on startup every time.



Balaji
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 10 of 10

andre_adc-dao
Advocate
Advocate
Accepted solution

Thank you Balaji,

 

I try your code and it is working. So I try to see why my code was not working and I found the problem.First I notice that your code use HKEY_CURRENT_USER. I modifiy your code to use HKEY_LOCAL_MACHINE and it always work. So this is not the problem.

 

Next, in previous release I was using 2 for LOADCTRLS and 0 for MANAGED and it is working well but not in 2014, but if I set LOADCTRLS to 14 (Decimal) and 1 to MANAGED, it was also working in previous release. But my code was always not working.

 

At a moment I notice, in my code I leave the key DESCRIPTION to blank. In previous release it is optional but not in 2014. You absolutely have to put some description in this key. I remove the content of DESCRIPTION key and the DLL not load automatically. I put any description and it is working again.

 

Thank you again and have a nice day,

 

André

 

0 Likes