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

netloaded dll error in app keeps acad from closing

15 REPLIES 15
Reply
Message 1 of 16
mpropst
658 Views, 15 Replies

netloaded dll error in app keeps acad from closing

vbdotnet express 2008 acad 2009 netloaded dll using acad com

 

am i the only one who experiences this?

if i create a dll that errors out (trapped with try/catch)

when i close acad to edit and rebuild dll acad process hangs in task mgr

acad variable gotten with

Private Function GetAutoCADInstance() As AcadApplication
    Try
      m_AcadApp = DirectCast(Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication, AcadApplication)
    Catch ex As Exception
      Me.Logentry("Failed to get acad application " + ex.Message)
      m_AcadApp = Nothing
    End Try

    Return m_AcadApp

  End Function

 

is there something i should do to allow acad to close properly after program run(even if it errors)

acad will close after prog run if no errors occur(and i'm pretty sure i'm trapping them all with try but i must not be releasing the acad object somehow)

i'm trying to close acad in Dispose() by making the clasees implement iDisposable

shouldn't that be running at the end of the app whether it errors or not?

thanks

mark

 

15 REPLIES 15
Message 2 of 16
caddzone
in reply to: mpropst

Again, you're not reading my posts or you're just ignoring them.

 

You don't need any Dispose() and you don't need to release

any AutoCAD COM objects from a NETLOADed DLL.

 

The problem of AutoCAD not shutting down has nothing to

do with any of that.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 3 of 16
mpropst
in reply to: caddzone

I am reading your posts and not ignoring them! 🙂

I'm just stuck in the concept that the reason acad isn't closing is because i have a reference to it hung in the background

so yes, due to my stupidity and stubbornness I can see why it would seem i'm ignoring it.

so if i get rid of dispose and get rid of setting acad = nothing that will fix my problem?

thanks

mark

 

Message 4 of 16
caddzone
in reply to: mpropst

No, getting rid of Dispose and not bothering to release COM objects

will not solve the problem of AutoCAD not shutting down. I can't tell

you why that's happening without seeing your code, and what it

does, or doesn't do when an exception occurs.

 

Usually, when I'm debugging AutoCAD, I don't bother closing it,

I just hit the Stop Debugging button in Visual Studio, which kills

the debug process (acad.exe) dead in its tracks, and that's that.

 

If you choose to do that, make sure that you routinely clear out

your temp folder, because when you terminate AutoCAD from

Visual Studio, it leaves all open temporary files (e.g., *.ac$ and

so on) in the temp folder, and when the number of objects in

that folder becomes large, it impacts performance.

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 5 of 16
mpropst
in reply to: caddzone

well you probably wouldn't have time to look through the code, though i'd be thrilled to send it if you did. I don't know how to post up a whole project.

 

almost all my catch expressions follow this pattern:

 

catch ex as exception

m_util.logentry ("Error ", ex.Message) '<---writes to log file

return False (or Return Nothing) ..if it's a function

End try

 

i'm not sure what i should be doing in those actually.  i'm just notifying myself where the errors are(via log file)

 

i haven't been debugging throughthe ide for some reason(not sure why) I tend to rebuild the dll, start acad, netload, then run as enduser would be doing.  maybe i'll try the debug in ide way again.

Message 6 of 16
mpropst
in reply to: caddzone

this is interesting.

if i debug from the ide, it opens acad, i open my testdwg, netload the new dll, call the commands and get Unknown command.

 

If i open acad, netload the dll, call the commands, they are there.

 

is that normal?

I'm guessing not

🙂

mark

 

Message 7 of 16
caddzone
in reply to: mpropst

Make sure that 'CopyLocal' is set to false for all AutoCAD assembliy references.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 8 of 16
caddzone
in reply to: mpropst

Code that is designed that way is fatally flawed because it traps errors

and allows the program to continue to run.

 

When an unexpected error occurs, the program should stop, it should

not continue running, whether you log the error or not.

 

My guess is that AutoCAD isn't shutting down because of something

related to your error logging.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 9 of 16
mpropst
in reply to: caddzone

Tony, thanks for hangin in with me on this...

hope this isn't too long...i don't know the length protocol on this web forum.

 

so how do i make the program stop after i log the error?

i thought try/catch was a recommended method.

 

basic program form

i have 3 classes in this app

one defines the acad commands

the acad command calls the "main" class

the main class creates the "utility" class

the "utility" class creates the reference to acad and provides it to "main" via .Acad and .AcadDoc properties

the "utility" class also logs all activity so i can see where things go south.

which they obviously do a lot of around here. 🙂

 

the logging sub in mcsutil.vb

 Sub Logentry(ByVal strMsg As String, Optional ByVal BracketInfo As String = "", Optional ByVal bAddTimeStamp As Boolean = False)
    If m_Debug Then
      If Not m_acadDoc Is Nothing Then
        If userIsDeveloper() Then
                    m_acadDoc.Utility.Prompt(vbCrLf & strMsg)
                    If Len(BracketInfo) > 0 Then
                        m_acadDoc.Utility.Prompt("<" & BracketInfo & ">")
                    End If
        End If
      End If

      Debug.Print(vbCrLf & strMsg)
      Try

       Dim sw As StreamWriter = New StreamWriter(m_DebugFileName, True)
        If bAddTimeStamp Then
          sw.WriteLine(Now)
        End If

        sw.WriteLine(strMsg)

        If Len(BracketInfo) > 0 Then
          sw.WriteLine("<" & BracketInfo & ">")
        End If

        sw.Close()
      Catch ex As Exception
        If userIsDeveloper() Then
          MsgBox(ex.Message)

        End If
      End Try


    End If

End Sub

the userIsDeveloper() function just keeps debug dialogs from popping up on users machines while i'm in the process of tweaking an app in progress

 

an example of the command.vb file

Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports System.IO


Public Class AcadCommands

  Private inst As New MCSdxf

  <CommandMethod("Cnc", CommandFlags.Session)> _
Public Sub CncPartList()

    If inst Is Nothing Then inst = New MCSdxf
        inst.Init()

        inst.CNC_FormPartList()

        inst = Nothing

  End Sub

 

 

the mcsdxf.init function

   Function Init() As Boolean
        m_Util = New MCSUtil(True)
        m_Util.Init2(True)

        If m_acad Is Nothing Then
            m_acad = m_Util.ACAD

        End If
        If m_acad Is Nothing Then
            MsgBox("Can not get AutoCAD instance.", MsgBoxStyle.Exclamation, "")
            Exit Function
        End If

        m_acadDoc = m_acad.ActiveDocument
        If m_acadDoc Is Nothing Then
            MsgBox("No active document.", MsgBoxStyle.Information, "")
            Exit Function
        End If


        Init = True
    End Function

 

the mcsutil.init2 function

Function Init2(ByVal bDebug As Boolean) As Boolean
    m_Debug = bDebug
    Try
      m_AcadApp = DirectCast(Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication, AcadApplication)

      m_acadDoc = m_AcadApp.ActiveDocument
      Return True

    Catch ex As Exception
      Return False


    End Try
  End Function

 

any advice?

my plan was for the init functions to return bool

then each level would check

If m_Util.Init2(True) then
...

else

Return False

End if

so that way any failure would percolate up to the top level to end the program.

i'm not currently doing that as i havent' had any failures yet at that level(of init)

 

but most of the internal calls check the return values of functions and if they failed i don't continue with normal operation, but again try to percolate up the error state up the stack of calls to the main level.

 

most of my problems have been getting all the casting right after i decided to go with option strict on

lots of acad functions will not retun a value even if there's no error if i don't get all my casting back and forth from object to arrays or specific acadobjects etc(depending on the acad method i'm calling)

 

thanks for all your time and guidance.

mark

 

 

Message 10 of 16
caddzone
in reply to: mpropst

You can re-raise the exception after logging it using 'throw':

 

try
{
    SomethingDangerous();
}
catch{ System.Exception ex )
{
    LogError( ex );
    throw;            // <- re-raises the exception
}

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 11 of 16
mpropst
in reply to: caddzone

tony,

another question if i may.

i confirmed copy local is false, btw i'm reffing the objectarx sdk versions of the acad dlls if that makes any diff.

 

one thing i was wondering, looking at the vbproj file in notepad, is why i ended up with two <NoWarn> sections

i don't know if that's normal or because i started with someone elses' app as a skeleton and did massive changes to convert to what i wanted to do.  (the only thing left from the orig is the format of the command defs)

 

i'm posting this in case you can see something in the call to startaction / startprogram lines that i may have not gotten right.

when i try the debug from the ide, and then manually netload the dll after acad starts(via lisp call), the commands are not defined in that acad session.  If i start acad and netload the dll in the same way, the commands are defined.

 

here's part of the vbproj file:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{4C427581-4C44-4F77-95F1-5A2D8B1E8D7B}</ProjectGuid>
    <OutputType>Library</OutputType>
    <StartupObject>
    </StartupObject>
    <RootNamespace>MCS_DXF</RootNamespace>
    <AssemblyName>MCS_DXF</AssemblyName>
    <FileAlignment>512</FileAlignment>
    <MyType>Windows</MyType>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <OptionExplicit>On</OptionExplicit>
    <OptionCompare>Binary</OptionCompare>
    <OptionStrict>Off</OptionStrict>
    <OptionInfer>On</OptionInfer>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <StartAction>Program</StartAction>
    <StartProgram>C:\Program Files\AutoCAD 2009\acad.exe</StartProgram>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <DefineDebug>true</DefineDebug>
    <DefineTrace>true</DefineTrace>
    <OutputPath>bin\Debug\</OutputPath>
    <DocumentationFile>MCS_DXF.xml</DocumentationFile>
    <NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</NoWarn>
    <RegisterForComInterop>false</RegisterForComInterop>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <WarningsAsErrors>
    </WarningsAsErrors>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <DefineDebug>false</DefineDebug>
    <DefineTrace>true</DefineTrace>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DocumentationFile>MCS_DXF.xml</DocumentationFile>
    <NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</NoWarn>
    <RegisterForComInterop>false</RegisterForComInterop>
    <WarningsAsErrors>
    </WarningsAsErrors>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="AcDbMgd, Version=18.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>C:\ObjectARX 2010\inc-win32\AcDbMgd.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="AcMgd, Version=18.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>C:\ObjectARX 2010\inc-win32\AcMgd.dll</HintPath>
      <Private>False</Private>

Message 12 of 16
caddzone
in reply to: mpropst

The <NoWarn> sections are the supressed warnings.

 

There are two because there are two configurations for debug and release builds.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 13 of 16
mpropst
in reply to: caddzone

thanks for that info.

so does it look correct for debugging in acad?

i don't know why when i debug run from the vbexpress ide acad opens, i net load the dll, but the commands aren't available

if i start acad and netload the dll the commands are avilable.

what am i doing wrong?

Message 14 of 16
caddzone
in reply to: mpropst

Usually, commands not available while debugging is because

the referenced AutoCAD assemblies do not have the CopyLocal

set to false.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 15 of 16
mpropst
in reply to: caddzone

so given in this case they are set to false, what else could it be?

i wonder if it's related to my logging, as you mentioned that may be what's keeping acad alive after trying to close acad following an error in the dll app.

the only thing i'm doing in the logging that touches acad is writing to the command line

maybe 'll drop that and see if it helps.

any other ideas?

Message 16 of 16
caddzone
in reply to: mpropst

No, but disabling the logging function so it does nothing should

be simple enough to do, and answer your question.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


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