Author Topic: .Net Plugin Command Unknown On Some Machines Running Win 8/8.1  (Read 3161 times)

0 Members and 1 Guest are viewing this topic.

kbrown@wynright.com

  • Guest
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).

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

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: .Net Plugin Command Unknown On Some Machines Running Win 8/8.1
« Reply #1 on: May 13, 2014, 11:41:31 PM »

Welcome to theSwamp Kevin.

I Don't run Win 8.* so can't start to  guess ( from experience)

Sounds like a tricky problem.

Regards,
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MickD

  • King Gator
  • Posts: 3637
  • (x-in)->[process]->(y-out) ... simples!
Re: .Net Plugin Command Unknown On Some Machines Running Win 8/8.1
« Reply #2 on: May 13, 2014, 11:45:12 PM »
I'm just having a stab in the dark here but are the commands dispersed throughout different assemblies?
I've had similar issues with reflection where an assembly wasn't loaded before I tried to create an instance of an object from another assembly only to have it fall over.

Commands are similar in that they won't be loaded unless that referenced assembly is loaded and I've made some 'trigger' methods that force the loading of all assemblies in the IExtension start up to make sure all ref'd assemblies get loaded so all commands are available.

Hope that makes sense, might be worth a look.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: .Net Plugin Command Unknown On Some Machines Running Win 8/8.1
« Reply #3 on: May 13, 2014, 11:55:53 PM »
Quote
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 think the problem are located in your code, but AutoCAD & Windows there is not guilty. I advise to you to do the refactoring of your code (divide it at the little bits). Thus you will narrow a problem area. It is simpler to analyze a small bit of a code.

owenwengerd

  • Bull Frog
  • Posts: 451
Re: .Net Plugin Command Unknown On Some Machines Running Win 8/8.1
« Reply #4 on: May 14, 2014, 09:41:27 AM »
Put all of your IExtensionApplication::Initialize() code inside a try/catch and report the exception, otherwise it will be silently ignored and your commands will not work.

kbrown@wynright.com

  • Guest
Re: .Net Plugin Command Unknown On Some Machines Running Win 8/8.1
« Reply #5 on: May 14, 2014, 11:57:33 AM »
Put all of your IExtensionApplication::Initialize() code inside a try/catch and report the exception, otherwise it will be silently ignored and your commands will not work.

I believe I have located the problem. Owenwengerd correctly pointed to the Initialize method implementation being the likely cause. From initialize, I call a method responsible for executing an agent process which supports the plugin and hosts WCF services (this is a legacy of the need to support ACAD 2010-2011 but requiring .net 4.0 features (I needed WF 4, and I wanted EF 4). I hope to move most of the code called via WCF services into the plugin and eliminate the Agent exe all together in the future now that we have dropped support for ACAD 2010-2011.

I did have all code in Initialize wrapped in a Try/Catch, but no exceptions were ever caught. I have a theory that something about the Win8 environment and the AutoCAD runtime configuration of .net combined to produce an exception-less error when I started the agent process from ACAD plugin code, and this somehow interrupted the process performed by ACAD when it initially looks for methods with the <CommandMethod("")> attribute, as Owenwengerd suggested. I'm experimenting with this now on an affected machine. I'll report back my findings in case someone finds this thread helpful in the future. I have also altered the manifest for the Agent exe so that it does not ask for escalated privileges (highest available).

All commands for the plugin are defined in a single class, which I have added <Assembly: CommandClass(GetType(Automotion.AutoPrice.CADUI.AutoPriceApp))> to in order to speed up the load time as much as possible. The code for the implementation of Initialialize, as well as the method called to run the Agent process follows. Just in case this makes the thread more complete or is helpful in some other way.

Code: [Select]
    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

Code: [Select]
    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

Best regards,
Kevin