.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

.Net Plugin Command Unknown Intermittently On Some Machines Running Win 8/8.1

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
kbrown
2382 Views, 5 Replies

.Net Plugin Command Unknown Intermittently On Some Machines Running Win 8/8.1

I have a strange situation where commands I have defined in a .Net plugin unpredictably are not available. I have only observed this behavior on machines running Win8.1 and AutoCAD 2014 SP1, but other configurations may be affected (though a great deal of testing has been done in Windows 7 and this probem has never been reported or observed).

 

My implementation of Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize in the affected class always runs, but sometimes the commands defined are not recognized. I observed today in one case that initially, the commands defined in my class (the only class in my plugin assembly where AutoCAD commands are defined), are consistently available. However, after a very heavy routine is run (which frankly currently seems to leak a large amount of memory), the command becomes unavailable when AutoCAD is restarted and stays that way. If I restart AutoCAD 10 times, the command might be available only once. I have tried restarting Windows as well, with no improvement. There have been reports from users of this same behavior on other machines running Win8x, but never to the extent I observed today. In these other instances, the previously mentioned "heavy routine" is not run. The comamnd just is sometimes not available and restarting AutoCAD is required.

 

I would post code, but the plugin in question has become prohibitively large and complicated. There are likely hundreds of thousands of lines of code in the plugin if you include all assemblies loaded into the app domain. I will gladly post portions of the code if it becomes relevant.

 

I am wondering if any of you who might read this have observed this behavior and have identified a root cause. Any insights are most welcome. I began to wonder today of AutoCAD has a mechanism for detecting misbehaving .Net plugin commands and making them unavailable. Are any of you aware of such a feature? The fact that i have never observed this behavior in my Windows 7 / AutoCAD 2014 development environment, and that no users running Windows 7 / AutoCAD 2014 have reported the behavior doesn't fit with that theory, however.

 

I use the autoloader to load my plugin automatically, but I have tried removing the plugin from affected machines and using the AutoCAD NetLoad command instead with the same results (Command Unknown, does not show up in inteli sense).

 

Again, i would be grateful for any insights at all into what might cause this on any platform, or why this might occur on Win8 and not Win7. I have checked the AutoCAD command console for errors and see none. I've added exception handling and logging to the EventLog to the method implementing Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize, and no errors are ever logged or reported by AutoCAD (that I can find, maybe I am not looking in the right location?).

 

Thank you for your help,
Kevin

5 REPLIES 5
Message 2 of 6
norman.yuan
in reply to: kbrown

I am not sure whether you have investigated the most common reasons that cause "Unknown command" after the .NET DLL being loaded:

 

1. Forgetting to set "Copy Local" to False in project so that the AutoCAD .NET assemblies (accordmgd.dll, acdbmgd.dll, acmgd.dd and possible other DLLs that come with AutoCAD vertical products) from ObjectARX SDK are copied to your DLL loading folder.

 

2. Something going wrong inside the IExtensionApplication.Initialize() and the exception is not caught. If code in Initialize() runs into exception that is not caught, AutoCAD silently aborts the Initialize(), and any command defined in the loaded DLL becomes not available. If you need to implement Initialize() with logical more complicated than 1+1=2, youèd better make sure you place all code in a try...catch... block, and in the catch clause to prompt the user that something went wrong.

 

Since you mentioed that you use IExetnstion.Initialize(), and it seem the issue may related to newer OS (Win8.1), so, if you do have code inside Initialize() that does some thing complicated, then it is where you may want to pay attention before you look into huge amount of code of the large plug-in.

Message 3 of 6
kbrown
in reply to: norman.yuan

Thank you. I will focus on the Initialize method as you suggest. I think I have found a relation between part of the code that runs in Initialize and the behavior on Win8.

 

I do have a Try/Catch wrapping all the code in the Initialize method. If an exception is caught, I write an event to the Application Log. There is never any indication of an exception being caught. However, I run an Agent exe which hosts WCF services called from the plugin from the Initialize method, and for some reason this fails but no error is every displayed and no exception is ever caught. Here is the Initialize code, followed by the RunHost method code it calls:

 

Public Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize
        Try
            Telerik.WinControls.AnimatedPropertySetting.AnimationsEnabled = False
            Drawings = New DrawingModelManagerCollection()
            StateRectifier = New ModelStateRectifier()
            UISynchronizer = New ModelToUISynchronizer(Nothing, Nothing)
            ValidationManager = New DrawingValidationManager()
            AutoPurgeManager = New ACADPurgeManager(AUTO_PURGE_MIN_INTERVAL, AUTO_PURGE_INTERVAL)
            ManagerInitialized = False
            ActivationPromptValues = New Dictionary(Of String, String)
            RunHost()
        Catch ex As System.Exception
            If ex IsNot Nothing Then
                Try
                    EventLog.WriteEntry("NiC.Initialize", ex.Message + Environment.NewLine + ex.StackTrace, EventLogEntryType.Error)
                Catch eex As Exception

                End Try
            Else
                Try
                    EventLog.WriteEntry("NiC.Initialize", "Unknown error.", EventLogEntryType.Error)
                Catch eex As Exception

                End Try
            End If
        End Try
    End Sub

 

    Public Shared Sub RunHost()
        Try
#If _DEBUG_RUNAP Then
        HOST_SERVICE_EXE_PATH = "C:\Users\kbrown\Documents\Visual Studio 2008\Projects\Automotion.AutoPrice.SystemManager\trunk\Automotion.AutoPrice.AgentServiceHost\bin\Debug\Automotion.AutoPrice.AgentServiceHost.exe"
#Else
            Dim regReader As RegistryReader = RegistryReaderSingleton.Instance()
            HOST_SERVICE_EXE_PATH = regReader.GetServiceHostExePath()
#End If
            If Process.GetProcessesByName("Automotion.AutoPrice.AgentServiceHost").Count = 0 AndAlso Process.GetProcessesByName("Automotion.AutoPrice.AgentServiceHost.exe").Count = 0 AndAlso Process.GetProcessesByName("Automotion.AutoPrice.AgentServiceHost.vshost").Count = 0 AndAlso Process.GetProcessesByName("Automotion.AutoPrice.AgentServiceHost.vshost.exe").Count = 0 Then
                Dim cd As String = Environment.CurrentDirectory
                Environment.CurrentDirectory = Path.GetDirectoryName(HOST_SERVICE_EXE_PATH)
                Dim proc As Process = Process.Start(HOST_SERVICE_EXE_PATH)
                Environment.CurrentDirectory = cd
                proc.WaitForInputIdle()
            End If
        Catch ex As System.Exception
            Try
                EventLog.WriteEntry("AutoPrice.RunHost", ex.Message + Environment.NewLine + ex.StackTrace, EventLogEntryType.Error)
            Catch eex As Exception

            End Try
        End Try
    End Sub

 

A registry key value is also read in this method; the key is located in HKEY_CURRENT_USER\Software\... in read only mode, so i don't think this is the problem. I'm going to move this call out of Initialize and into the AutoCAD Command used to initialize the plugin application. I'm also going to alter the manifest of the Agent exe so that no long asks for highest available User Account escalation.

 

Thank you for your help. I will come back and assign kudos after confirming the issue is indeed caused by code in the Initialize method running the agent process from the plugin code under Win8. I'll attempt to describe any changes I make for the benefit of others who might find this thread helpful in the future.

 

Best regards,

Kevin

Message 4 of 6
norman.yuan
in reply to: kbrown

Your code in Initialize() is indeed quite complicated. IMO, Initialize() is meant for, well, initializing stuff. It may be too much to start other processes in the Initialize(), which may takes unknown lengthy time and is complete;y out of the control of AutoCAD process. Seeing your code, I am more convinced that the issue is likely caused by the code inside Initialize().

 

To determine if the issue is really caused by code inside Initialize(), you can move the code inside Initialize() into a new command method (e.g leaving Initialize() empty), and then load the .NET DLL, run the new command first before running your main command. Now you can be certain if the "Unknown command" is caused by the code inside Initialize().

 

Actually, you can even consider to use this 2-command approach for real work: just make sure the command that does the heavy initializing work runs after the nET DLL loads (via acad.lsp, for example).

Message 5 of 6
kbrown
in reply to: norman.yuan

Norman, thank you for your advice and insights. You were indeed correct that the probem occured in the Initialize method of my command defining class. It turned out that I had forgotten to disable the creation of the http based discovery service WCF can optionally host. I forgot to set a compiler variable to false and as a result the WCF discovery service was created. This resulted in an exception due to security policy in windows 8.

 

When I moved the call to RunHost, repsonsible for creating a new process, out of Initialize and into my command, I was able to catch the exception. For some reason the exception was somehow supressed when it occurred in Initialize. I have done some testing and confirmed that my command is now always available.

 

Thanks again,

Kevin

Message 6 of 6
kbrown
in reply to: norman.yuan

Strangely, after I marked your reply as an accepted solution, I received an email congratulating me on providing an accepted solution. Must be a bug in the forums. Here is the relevant part of the message:

 

Hi kbrown,

Great job! ${solution.actor.login} marked your answer to a question as an accepted solution!


Subject

Re: .Net Plugin Command Unknown Intermittently On Some Machines Running Win 8/8.

Date:

05-13-2014 08:29 PM

I am not sure whether you have investigated the most common reasons that cause "Unknown command" after the .NET DLL being loaded:

 

1. Forgetting to set "Copy Local" to False in project so that the AutoCAD .NET assemblies (accordmgd.dll, acdbmgd.dll, acmgd.dd and possible other DLLs that come with AutoCAD vertical products) from ObjectARX SDK are copied to your DLL loading folder.

 

2. Something going wrong inside the IExtensionApplication.Initialize() and the exception is not caught. If code in Initialize() runs into exception that is not caught, AutoCAD silently aborts the Initialize(), and any command defined in the loaded DLL becomes not available. If you need to implement Initialize() with logical more complicated than 1+1=2, youèd better make sure you place all code in a try...catch... block, and in the catch clause to prompt the user that something went wrong.

 

Since you mentioed that you use IExetnstion.Initialize(), and it seem the issue may related to newer OS (Win8.1), so, if you do have code inside Initialize() that does some thing complicated, then it is where you may want to pay attention before you look into huge amount of code of the large plug-in.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost