Hot News:

Mit Unterstützung durch:

  Foren auf CAD.de
  AutoCAD ObjectARX und .NET
  AutoCad per .Net clever fernsteuern

Antwort erstellen  Neues Thema erstellen
CAD.de Login | Logout | Profil | Profil bearbeiten | Registrieren | Voreinstellungen | Hilfe | Suchen

Anzeige:

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen nächster neuer Beitrag | nächster älterer Beitrag
  
Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte
  
PNY präsentiert die neue NVIDIA RTX A400 und die A1000 Grafikkarte, eine Pressemitteilung
Autor Thema:  AutoCad per .Net clever fernsteuern (5296 mal gelesen)
Boortsneggor
Mitglied
Ingenieur


Sehen Sie sich das Profil von Boortsneggor an!   Senden Sie eine Private Message an Boortsneggor  Schreiben Sie einen Gästebucheintrag für Boortsneggor

Beiträge: 49
Registriert: 27.12.2011

Win7 Prof, Visual Studio 2010/2012,
ObjectARX 2008/2012/2013, ACAD
2008/2012/2013

erstellt am: 26. Aug. 2012 13:13    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Einen schönen guten Tag,

da ich in diesem Forum schon viel Hilfe in Sachen AutoCAD-Entwicklung bekommen habe, möchte ich heute mal ein paar interessante Erfahrungen an euch weiter geben.
Die .Net-Schnittstelle (managed) von AutoCAD ist ziemlich mächtig und vor allem auch sehr schnell, da die Bibliotheken direkt im Speicher von AutoCad geladen werden. Möchte man nun eine Standalone-Anwendung entwickeln, welche vollen Zugriff auf AutoCad hat, so ist man auf COM angewiesen. Dies ist in der Regel um ein vielfaches langsamer.
Es gibt aber auch die Möglichkeit, beides zu kombinieren und somit die Vorteile beider Varianten zu nutzen. Wir bauen eine Klassenbibliothek, die sämtliche Funktionen im Bezug auf den Zugriff auf AutoCAD und dessen Datenbank beinhaltet (in-process), und laden bzw. steuern diese aus einem unabhängigen Programm über die COM-Schnittstelle (out-of-process).
Hier mal eine kleine Anleitung, wie Ihr eine derartige Lösung zum Laufen bekommt.

1.Erstellen einer Klassenbibliothek

Zuerst muss eine neue Klassenbibliothek erstellt werden, welche wir für COM verfügbar machen müssen:

Code:

using System.Runtime.InteropServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System.EnterpriseServices;
using System;

namespace AcadInterface
{
    [Guid("69FCC82A-1C96-40D2-B68F-2D7251B94447")]
    public interface IAcadInterface
    {

        [DispId(1)]
        bool SmartMethode();

    }


    [ProgId("AcadInterface.Commands"),
    Guid("DEA7B308-03E1-456C-ACDF-48A2F6B368BD"),
    ClassInterface(ClassInterfaceType.None)]
    public class Commands : ServicedComponent, IAcadInterface
    {

        private Database _db = HostApplicationServices.WorkingDatabase;
        private Document _doc = Application.DocumentManager.MdiActiveDocument;


        [CommandMethod("TESTCOM")]
        static public void MyCommand()
        {

            _doc.Editor.WriteMessage("\nInterface ist geladen!");
               
        }

        public bool SmartMethode()
        {
            bool result = false;


            DocumentLock loc = _doc.LockDocument();

            using (loc)
            {

              
                //irgendein Zugriff auf die Datenbank des aktuellen Dokumentes
               

            }

            return result;
        }
    }
}


Die GUIDs für das Interface und die Klasse könnt Ihr unter Extras/GUID in Visual Studio automatisch generieren lassen. Die Vererbung von ServicedComponent vereinfacht den Zugriff auf unser in-process-interface über COM.
Damit ist die interne Schnittstelle schon fertig. Wichtig ist noch, dass vor dem ersten Kompilieren unter Assemblyinformationen das Häckchen bei "Assembly COM-sichtbar machen" gesetzt ist. Andernfalls schlägt die Registrierung anschließend fehl.

2.Registrierung des in-process-interfaces

Nach dem ihr die Klassenbibliothek kompiliert habt, müsst ihr sie registrieren, damit sie für den Zugriff über COM verfügbar gemacht wird. Dies kann mit dem Windows-Programm regsam.exe realisiert werden. Hier ist es hilfreich, sich eine kleine batch-Datei anzulegen, welche dann in dem Verzeichnis der zu registrierenden dll ausgeführt wird. Diese beinhaltet bei mir folgende Zeilen:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /codebase GaboCadConverterIP.dll

Der Pfad steht für die 64bit-Variante des .Net 4.0 - Frameworks. Wenn ihr unter 32bit arbeitet müsstet ihr die regsam.exe im Ordner C:\Windows\Microsoft.NET\Framework\v4.0.30319 nehmen. Genauso verhält es sich mit den anderen Versionen des .Net-Frameworks. Jedoch habe ich es bisher nur mit 4.0 und Acad 2012 getestet.
Die Option "/codebase" hinterlegt bei der Registrierung zusätzlich den Pfad der dll. Hier kommt bei der Registrierung auch eine Warnung, die ihr aber getrost ignorieren könnt.
Wichtig ist noch, dass ihr vor er Registrierung die AcMgd.dll und die AcDbMgd.dll aus dem /inc-Ordner der Objectarx-Version kopiert. Diese dlls werden bei der Registrierung benötigt.

3.Automatische Registrierung nach Kompilieren

Jetzt müsst ihr euer in-process-interface-Projekt so konfigurieren, dass die dll beim Kompilieren registriert wird. Bei 32bit geht das ganz einfach, in dem ihr ein Häkchen bei "Für COM-Interop registrieren"  in den Projekteinstellungen/Erstellen setzt.
Bei 64bit klappt diese Variante nicht, da in Visual Studio 2010 nur die 32bit-Version von regsam hinterlegt ist. Hier müsst ihr euch selbst mit einem Post-Build-Eintrag behelfen. Dieser kopiert nach dem Kompilieren die AcMgd.dll und die AcDbMgd.dll in den Release-Ordner, registriert die kompilierte dll und löscht die beiden zusätzlichen dlls wieder. Dafür könnt ihr folgenden Zeilen einfach in das Feld "Befehlszeile für Postbuildereignis:" kopieren:

copy "c:\ObjectARX 2012\inc\acmgd.dll" "$(TargetDir)"
copy "c:\ObjectARX 2012\inc\acdbmgd.dll" "$(TargetDir)"
"c:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" "$(TargetPath)" /tlb:"$(TargetDir)\AcadInterface.tlb"

Hier die Option "/tlb" nicht vergessen, die die Typ Library für das Assembly erzeugt. Ohne diese Option hatte ich immer den COM-Fehler: "E_NOINTERFACE".

Nach dem Hinzufügen des Post-Build-Eintrages könnt ihr nun neu kompilieren und solltet unter "Ausgabe" unten angezeigt bekommen, dass alles ordentlich registriert wurde. Überprüfen könnt ihr das auch mit dem Programm "OLE-COM Object Viewer" welches unter den Tools von Visual Studion zu finden ist.

Damit ist das in-process-interface einsatzbereit.

4.Out-of-process-Komponente

Für das Aufrufende Programm könnt ihr ein neues Projekt erstellen, dies kann zum Beispiel eine Windows.Forms sein oder auch eine WPF-Anwendung, wie in meinem Fall:

Code:

using System.Windows;
using Microsoft.Win32;
using System;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Runtime.InteropServices;

using Autodesk.AutoCAD.Interop;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.Interop.Common;

using AcadInterface; //das in-process-interface

// The IMessageFilter is needed to avoid problems with rejected calls of com operations
// For more information on IMessageFilter:
// http://msdn.microsoft.com/en-us/library/ms693740(VS.85).aspx

namespace AcadOPinterface
{
    [ComImport,
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
       Guid("00000016-0000-0000-C000-000000000046")]
    public interface IMessageFilter
    {
        [PreserveSig]
        int HandleInComingCall(
            int dwCallType, IntPtr hTaskCaller,
            int dwTickCount, IntPtr lpInterfaceInfo);

        [PreserveSig]
        int RetryRejectedCall(
            IntPtr hTaskCallee, int dwTickCount, int dwRejectType);

        [PreserveSig]
        int MessagePending(
            IntPtr hTaskCallee, int dwTickCount, int dwPendingType);
    }

    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, IMessageFilter
    {
        [DllImport("ole32.dll")]
        static extern int CoRegisterMessageFilter(IMessageFilter lpMessageFilter, out IMessageFilter lplpMessageFilter);

        const string acadProgID = "AutoCAD.Application.18"; //Instanzname von AutoCAD 2012
        const string interfaceProgID = "AcadInterface.Commands"; //Instanzname der in-process-interface-Klasse

        private AcadApplication _acApp;
        private IAcadInterface _iPinterface;

        public MainWindow()
        {  
            InitializeComponent();
            IMessageFilter oldFilter;
            CoRegisterMessageFilter(this, out oldFilter);

            _acApp = null;
            _iPinterface = null;

        }

        //methode which is called by clicking the open button
        private void btStart_Click(object sender, RoutedEventArgs e)
        {
             try
            {
                _acApp = (AcadApplication)Marshal.GetActiveObject(acadProgID);
                _acApp.Visible = true;
            }
            catch
            {
                try
                {
                    Type acType = Type.GetTypeFromProgID(acadProgID);
                    _acApp = (AcadApplication)Activator.CreateInstance(acType, true);

                    _acApp.Visible = true;

                }
                catch
                {
                    MessageBox.Show("AutoCad 2012 konnte nicht gestartet werden!");
                }
                Finally
                {
                   //dieser eventhandler ist wichtig, damit ihr die lokale Variable _acApp wieder auf null setzen könnt
                    _acApp.BeginQuit += new _DAcadApplicationEvents_BeginQuitEventHandler(ACAD_BeginQuit);
                }
                if(_acApp != null){

                          _iPinterface = (IAcadInterface)_acApp.GetInterfaceObject(interfaceProgID);

                          bool res = _iPinterface.SmartMethode();

                }
           
            }
        }

        //methode which was called by quitting acad
        public void ACAD_BeginQuit(ref bool cancel) {

            _acApp.BeginQuit -= new _DAcadApplicationEvents_BeginQuitEventHandler(ACAD_BeginQuit);
            //jedes mal wenn AutoCad geschlossen wird, muss die lokale Variable auf null gesetzt werden ansonsten
            //kann kommt es beim erneuten Start von ACAD aus der Anwendung heraus zum Fehler
            _acApp = null;
        }

        #region IMessageFilter Members
  
       int IMessageFilter.HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo)
       {
         return 0; // SERVERCALL_ISHANDLED
       }
  
       int IMessageFilter.RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
       {
         return 1000; // Retry in a second
       }
  
       int IMessageFilter.MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
       {
         return 1; // PENDINGMSG_WAITNOPROCESS
       }
  
       #endregion
    }
}


Das Interface IMessageFilter ist zwingend notwendig, damit die Kommunikation zwischen ACAD und der Anwendung reibungsfrei und stabil funktioniert. Andernfalls kommt es ständig zu E_CALL_REJECTED-Fehlern, weil Nachrichten gar nicht oder nur verzögert durchkommen. Vielen Dank an der Stelle an Kean Walmsley (http://through-the-interface.typepad.com/through_the_interface/2010/02/handling-com-calls-rejected-by-autocad-from-an-external-net-application.html     ) .

Nun könnt ihr kompilieren. Beim Klick auf den Button "Start" sollte sich nun eine Instanz von AutoCad öffnen, euer in-process-interface laden und die Methode "SmartMethode()" ausführen. Ob das interface im Autocar geladen wurde könnt ihr mit dem "TESTCOM"-Befehl überprüfen.

Ich hoffe, mit dieser kleinen Anleitung dem einen oder anderen von euch ein paar mühsame Recherche-Stunden im Netz zu ersparen.
Ich selbst habe auf diese Weise eine Anwendung entwickelt, welche eine Stapelverarbeitung vieler Dateien mit recht vielen Zugriffe auf die Datenbank einer einzelnen Zeichnung in sehr akzeptabler Zeit umsetzt.

Ich wünsche euch viel Spaß beim Testen, und stehe euch bei Fragen und Anregungen gern zur Verfügung!

Einen schönen Rest-Sonntag noch!


------------------
Robert Menger
Gabo Engineering GmbH
Entwicklung

[Diese Nachricht wurde von Boortsneggor am 26. Aug. 2012 editiert.]

[Diese Nachricht wurde von Boortsneggor am 26. Aug. 2012 editiert.]

[Diese Nachricht wurde von Boortsneggor am 26. Aug. 2012 editiert.]

[Diese Nachricht wurde von Boortsneggor am 26. Aug. 2012 editiert.]

[Diese Nachricht wurde von Boortsneggor am 26. Aug. 2012 editiert.]

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Andreas Widmann
Mitglied
ATHENA Support/Training


Sehen Sie sich das Profil von Andreas Widmann an!   Senden Sie eine Private Message an Andreas Widmann  Schreiben Sie einen Gästebucheintrag für Andreas Widmann

Beiträge: 218
Registriert: 24.08.2005

erstellt am: 06. Feb. 2013 08:30    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Hallo CAD-Gemeinde,

Erstmal riesen Dank an Boortsneggor dass du deine Erfahrung mit uns hier teilst.

ABER: ich brauche dringend eure Hilfe!!!
Ich habe versucht den CODE von Boortsneggor in VB.Net zu übersetzen aber irgendwas klappt nicht so richtig bei mir.

Lade ich die DLL in AutoCAD und gebe den Befehl "Rapid_E" ein, funktioniert alles prima und es werden die passenden Infos ausgegeben.
Verbinde ich jedoch mit der Standalone zu ACAD und lasse von der Standalone "Rapid_E" ausführen, rennt er in dieser Zeile in einen Fehler:

Code:
Dim acBlkTblRec As BlockTableRecord = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)

Nebenbei bemerkt, die Funktion "TestCOM" lässt sich einwandfrei von der Standalone ausführen.

Zuerst die In-Prozess Komponente mit der für COM sichtbar gemachten Schnittstelle:

Code:
Imports System
Imports Autodesk.AutoCAD.Runtime
Imports System.Runtime.InteropServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports System.Diagnostics
Imports System.IO
Imports System.Windows
Imports System.EnterpriseServices

Namespace Rapid_E_AcadInterface

    <Guid("17909FF0-FC7A-4E6F-AE3E-3F88E8D39441")>
    Public Interface IACADInterface
        <DispIdAttribute(1)> _
        Sub Rapid_E()
        <DispIdAttribute(2)> _
        Sub testcom()
    End Interface

    <ProgId("Rapid_E.Rapid_E_AcadInterface"),
    Guid("430FDBC9-F7F5-4F9F-864B-11F1A83D49C9"),
    ClassInterface(ClassInterfaceType.None)>
    Public Class Rapid_E_AcadInterface
        Inherits ServicedComponent
        Implements IACADInterface

        <CommandMethod("TESTCOM")>
        Public Sub testcom() Implements IACADInterface.testcom
            Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nInterface ist geladen")
        End Sub
       
        Public myprofile As RapidProfile

        <CommandMethod("Rapid_E")>
        Public Sub Rapid_E() Implements IACADInterface.Rapid_E
            'Meine In-Prozess-Anwendung bestehend aus zwei Objektklassen die eine Auswahl im ACAD abrufen und diese weiterverarbeiten
            'In
        End Sub

    End Class
End Namespace



Und hier meine Standalone EXE:

Code:
Imports Autodesk.AutoCAD.Interop
Imports System.Runtime.InteropServices
Imports Rapid_E.Rapid_E_AcadInterface

Imports System.Reflection
Imports System

<ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid("8DE23EAB-C14C-458A-A780-06A64E477227")>
Public Interface IMessageFilter
    <PreserveSig()> Function HandleInComingCall(ByVal dwCallType As Int64, ByVal HTaskCaller As IntPtr, ByVal dwTickCount As Int64, ByVal lpInterfaceInfo As IntPtr) As Int64
    <PreserveSig()> Function MessagePending(ByVal hTaskCallee As IntPtr, ByVal dwTickCount As Int64, ByVal dwPendingType As Int64) As Int64
    <PreserveSig()> Function RetryRejectedCall(ByVal hTaskCallee As IntPtr, ByVal dwTickCount As Int64, ByVal dwRejectType As Int64) As Int64
End Interface

Public Class Form1
    Implements IMessageFilter
    Const interfaceProgID = "Rapid_E.Rapid_E_AcadInterface"

    Dim acapp As Autodesk.AutoCAD.Interop.AcadApplication = Nothing
    Dim iPinterface As IACADInterface = Nothing

    <DllImport("ole32.dll")>
    Public Shared Function CoRegisterMessageFilter(Optional ByVal lpMessageFilter As IMessageFilter = Nothing, Optional ByRef lplpMessageFilter As IMessageFilter = Nothing) As Integer

    End Function

#Region "IMessageFilter Members"

    Public Function HandleInComingCall(ByVal dwCallType As Int64, ByVal HTaskCaller As System.IntPtr, ByVal dwTickCount As Int64, ByVal lpInterfaceInfo As System.IntPtr) As Int64 Implements IMessageFilter.HandleInComingCall
        MsgBox("incoming")  'Nur zu Testzwecken
        Return 0 'SERVERCALL_ISHANDLED
    End Function

    Public Function MessagePending(ByVal hTaskCallee As System.IntPtr, ByVal dwTickCount As Int64, ByVal dwPendingType As Int64) As Int64 Implements IMessageFilter.MessagePending
        MsgBox("pending")  'Nur zu Testzwecken
        Return 1 'PENDINGMSG_WAITNOPROCESS
    End Function

    Public Function RetryRejectedCall(ByVal hTaskCallee As System.IntPtr, ByVal dwTickCount As Int64, ByVal dwRejectType As Int64) As Int64 Implements IMessageFilter.RetryRejectedCall
        MsgBox("recected")  'Nur zu Testzwecken
        Return 1000 'Retry in a second
    End Function

#End Region

    Public Sub New()

        ' Dieser Aufruf ist für den Designer erforderlich.
        InitializeComponent()

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
        Dim oldFilter As IMessageFilter = Nothing
        CoRegisterMessageFilter(Me, oldFilter)
    End Sub


Ich bin um jede Hilfe Dankbar!!!

------------------
Gruß Andreas

------------------------------------------------------------------------------------------------------------------------------------
Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste...

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Andreas Widmann
Mitglied
ATHENA Support/Training


Sehen Sie sich das Profil von Andreas Widmann an!   Senden Sie eine Private Message an Andreas Widmann  Schreiben Sie einen Gästebucheintrag für Andreas Widmann

Beiträge: 218
Registriert: 24.08.2005

Windows 10
Autocad 2015 - 2018
Athena 2015 - 2017 Aufsatz

erstellt am: 13. Feb. 2013 09:42    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Um das Thema noch etwas aufleben zu lassen,

auch diese Variante verursacht einen Fehler:

Code:
            Dim acBlkTblRec As BlockTableRecord = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)
            acBlkTblRec.UpgradeOpen()

Warum darf ich den BlockTableRecord, über Interface aufgerufen, nicht zum schreiben öffnen?

------------------
Gruß Andreas

------------------------------------------------------------------------------------------------------------------------------------
Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste...

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Boortsneggor
Mitglied
Ingenieur


Sehen Sie sich das Profil von Boortsneggor an!   Senden Sie eine Private Message an Boortsneggor  Schreiben Sie einen Gästebucheintrag für Boortsneggor

Beiträge: 49
Registriert: 27.12.2011

Win7 Prof, Visual Studio 2010/2012,
ObjectARX 2008/2012/2013, ACAD
2008/2012/2013

erstellt am: 16. Feb. 2013 11:14    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Andreas,

in VB stecke ich leider nicht so tief drin. Aber bei mir war die Geschichte mit dem DocumentLock auch wichtig. Bei jedem Eingriff des IP-Interfaces locke ich zuerst das aktuelle Dokument bevor ich die Funktionen anwende. Ich kann mich erinnern, dass es ohne diese Sperre zu Problemen kam.

Ich hoffe, dass hilft dir weiter. Viel Glück und ein schönes WE!

Grüße Robert

------------------
Robert Menger
Gabo Engineering GmbH
Entwicklung

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Andreas Widmann
Mitglied
ATHENA Support/Training


Sehen Sie sich das Profil von Andreas Widmann an!   Senden Sie eine Private Message an Andreas Widmann  Schreiben Sie einen Gästebucheintrag für Andreas Widmann

Beiträge: 218
Registriert: 24.08.2005

erstellt am: 21. Feb. 2013 09:53    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich


FatalExecutionEngineError.jpg

 
Hallo,

super, danke Robert, den DocumentLock hab ich total übersehen und jetzt eingebaut.
Dass du in VB (und ich in C) nicht so drin bist ist glaub ich kein Problem, es wird ja beides in die selbe Sprache kompiliiert und es sollte daher auch meist einen jeweils gleichbedeutenden Codeschnipsel in der anderen Sprache geben, oder nicht?

Also, jedenfalls hat der DocumentLock über den Fehler beim Schreib-Öffnen des BlocktableRecord hinweggeholfen.

Das Programm läuft weiter und ACAD fordert mich auf die erste Auswahl zu treffen... und schon steck ich leider in einem neuen Fehler:
Ich bekommen einen    " FatalExecutionEngineError "  vorgestellt.

Interessanterweise stürzt hierbei meine Standalone-Exe ab während, nachdem ich die Standalone beendet habe, mich AutoCAD anschließend souverän die Auswahl machen lässt und den In-Process Code einwandfrei vollständig ausführt.

Diese Code-Zeile ruft das Interfacecommand auf, und hier wird mir der Error gezeigt (siehe angehängtes Bild):

Code:
If Not acapp Is Nothing And Not iPinterface Is Nothing Then iPinterface.Rapid_E()

Muss ich hier den DokumentLock vorübergehend wieder aufheben? Und wie würde ich das machen?

@robert: In deiner PM hast du gemeint ich solle das Interface direkt in ACAD laden, was hast du damit gemeint? Oder ist das nun hinfällig?

------------------
Gruß Andreas

------------------------------------------------------------------------------------------------------------------------------------
Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste...

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Boortsneggor
Mitglied
Ingenieur


Sehen Sie sich das Profil von Boortsneggor an!   Senden Sie eine Private Message an Boortsneggor  Schreiben Sie einen Gästebucheintrag für Boortsneggor

Beiträge: 49
Registriert: 27.12.2011

Win7 Prof, Visual Studio 2010/2012,
ObjectARX 2008/2012/2013, ACAD
2008/2012/2013

erstellt am: 21. Feb. 2013 16:08    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Andreas,

wenn ich in meinem IP-Interface eine neue Funktion implementiere, dann teste ich diese zuerst direkt im AutoCAD. Das IP-Interface ist ja eine für AutoCAD kompilierte dll. Ich habe mir zum Test eine Command-Method implementiert, über die ich die Funktionalität des Interfaces testen kann.

Code:

//methode to test the interface
        [CommandMethod("TESTCOMMAND")]
        public void TestCommand()
        {

            Database _db = HostApplicationServices.WorkingDatabase;
            Document _doc = Application.DocumentManager.MdiActiveDocument;

            DocumentLock loc = _doc.LockDocument();

            using (loc)
            {
                //do something you want to test...
            }
        }


Sprich einfach im AutoCAD NETLOAD und direkt deine IP-Interface-dll laden. Meist handelt es sich um Fehler, die im AutoCAD entstehen und nicht über die COM-Schnittstelle weitergereicht werden.

Grüße robert

------------------
Robert Menger
Gabo Engineering GmbH
Entwicklung

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Andreas Widmann
Mitglied
ATHENA Support/Training


Sehen Sie sich das Profil von Andreas Widmann an!   Senden Sie eine Private Message an Andreas Widmann  Schreiben Sie einen Gästebucheintrag für Andreas Widmann

Beiträge: 218
Registriert: 24.08.2005

erstellt am: 21. Feb. 2013 16:14    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Hallo Robert,

das kann es in diesem Fall nicht sein denn ich habe das ganze erst als AutoCAD CommandMethod ausgearbeitet und getestet und danach dann das Interface implementiert um es von "aussen" ansprechen zu können.

Wenn ich die DLL im ACAD lade und den Befehl eingebe funktioniert alles einwandfrei. ..... oder gibt es Probleme wenn die Sub in meiner Dll vom Interface aufgerufen werden soll, gleichzeitig aber mit dem CommandMethod Attribut versehen ist??

Code:
        <CommandMethod("Rapid_E")>
        Function Rapid_E() As String Implements IACADInterface.Rapid_E
        ...
        End Sub

------------------
Gruß Andreas

------------------------------------------------------------------------------------------------------------------------------------
Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste...

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Brischke
Moderator
CAD on demand GmbH




Sehen Sie sich das Profil von Brischke an!   Senden Sie eine Private Message an Brischke  Schreiben Sie einen Gästebucheintrag für Brischke

Beiträge: 4191
Registriert: 17.05.2001

AutoCAD 20XX, defun-tools

erstellt am: 21. Feb. 2013 16:16    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Hallo Robert,

irgendwie fehlt mir die Fantasie, wozu man dies überhaupt benötigt.

Du willst von irgendeiner Anwendung außerhalb vom AutoCAD im AutoCAD irgendetwas machen. Klar, das geht nur via Com.
Warum lädtst du aber im AutoCAD nicht einfach die DLL's, die es braucht, um deine Funktionen auszuführen?
Dann kannst du mit einfachem SendCommand von deiner externen Anwendung ebenfalls die .Net-Programme laufen lassen.

Mich würde jetzt wirklich interessieren, was du damit anstellst.

Grüße!
Holger

------------------
Holger Brischke
FREIE SCHULUNGSPLÄTZE -- C#.NET-Schulung im Mai 2013 Bei Interesse bitte melden!
CAD on demand GmbH
Individuelle Lösungen von Heute auf Morgen.


defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!


Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Andreas Widmann
Mitglied
ATHENA Support/Training


Sehen Sie sich das Profil von Andreas Widmann an!   Senden Sie eine Private Message an Andreas Widmann  Schreiben Sie einen Gästebucheintrag für Andreas Widmann

Beiträge: 218
Registriert: 24.08.2005

erstellt am: 21. Feb. 2013 16:39    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Hallo Holger,

*Humor an* weils einfach cooler is  *Humor aus*

das kann ich dir einfach erklären.
Wie du sicher weist, ist die In-Process-Variante (DLL) zum einen wesentlich schneller und zum anderen kommt man "tiefer" als mit COM.

Der Grund für das aufwendige Interface ist, dass man von einem per "SendCommand" aufgerufenen Routine keinerlei Rückmeldung erwarten kann (bin mir nicht mal sicher ob man mitbekommt wann der Befehl fertig ist).
Über ein richtig implementiertes Interface kannst du aber Ergebnisse wie Strings, Integer, Boolean oder gar ganze Objekte zurückgeben und weiterverarbeiten.

Bei mir wird das ganze in einer Art Konfigurator enden der bei manchen Aktionen auf die DWG-Datenbanken zugreift und Informationen extrahiert und als Strukturierte Objekte mit Eigenschaften zurückgibt. Generell muss das Ding aber ohne ACAD laufen.
=> .Net-Dll wegen Schnelligkeit und tiefem Datenbankzugriff
=> Exe und Interface zur DLL wegen "Eigentständigkeit" und Rückgabewerten (Objekte)

------------------
Gruß Andreas

------------------------------------------------------------------------------------------------------------------------------------
Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste...

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Brischke
Moderator
CAD on demand GmbH




Sehen Sie sich das Profil von Brischke an!   Senden Sie eine Private Message an Brischke  Schreiben Sie einen Gästebucheintrag für Brischke

Beiträge: 4191
Registriert: 17.05.2001

AutoCAD 20XX, defun-tools

erstellt am: 21. Feb. 2013 17:01    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Zitat:
Original erstellt von Andreas Widmann:
... *Humor an* weils einfach cooler is   *Humor aus*

das kann ich nachvollziehen. Es gibt so Dinge, da ist der Weg das Ziel.


Um die Nachteile deiner weiteren Begründung aus dem Weg zu gehen, verfahre ich anders, wohl weniger aufwändig.
Der ganze Zugriff über Com auf AutoCAD geht nur dann, wenn auch ein AutoCAD auf'm Rechner drauf ist. Also kann ich auch gleich alles von AutoCAD aus machen.
Um aber die ganze Applikation, die außerhalb vom AutoCAD läuft nicht ein zweites mal für die Verwenung innerhalb vom AutoCAD programmieren zu müssen, habe ich mir angewöhnt, die eigentlichen Dialoge lediglich als Usercontrol zu programmieren. Die Windows-Anwendung und AutoCAD-Applikation implementiert dieses UserControl bzw. implementiert eine Vererbung davon, in der dann die AutoCAD-Funktionen an die Buttons, Listen etc... gebunden sind.

Einziger Nachteil, den ich sehe, der Anwender kann nicht spontan! aus der Windows-Anwenung auf AutoCAD-Inhalte zugreifen. Aber das lässt sich den Anwendern wohl vermitteln, dass bestimmte Funktionen nur vom AutoCAD aus gehen.

Ich denke, das ist eine Prinzipfrage.

Grüße!
Holger

------------------
Holger Brischke
FREIE SCHULUNGSPLÄTZE -- C#.NET-Schulung im Mai 2013 Bei Interesse bitte melden!
CAD on demand GmbH
Individuelle Lösungen von Heute auf Morgen.


defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!


Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Boortsneggor
Mitglied
Ingenieur


Sehen Sie sich das Profil von Boortsneggor an!   Senden Sie eine Private Message an Boortsneggor  Schreiben Sie einen Gästebucheintrag für Boortsneggor

Beiträge: 49
Registriert: 27.12.2011

Win7 Prof, Visual Studio 2010/2012,
ObjectARX 2008/2012/2013, ACAD
2008/2012/2013

erstellt am: 21. Feb. 2013 19:39    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Holger,

ich persönlich habe mich für die Com-Dll-Variante entschieden, weil man im AutoCAD zeichnungsübergreifend eingeschränkt ist. Das Interface wird immer erst beim Öffnen einer Zeichnung geladen.
Meine Anwendung ist so eine Art Konverter. Ich öffne nacheinander eine Reihe von dwgs, Ersetze und manipuliere Objekte, und speichere diese wieder. Der Vorteil bei meiner Variante ist, dass ich das AutoCAD sichtbar schalten kann und somit die Vorgänge auf den einzelnen Zeichnungen live verfolgen kann.
Du hast natürlich recht, man könnte das auch mit SendCommands lösen, aber das ist ja im Grunde das Gleiche. Allerdings können die Commands meiner Erfahrung nach bei dem Ablaufen direkt nacheinander folgender, von einander abhängiger Befehle Probleme machen. Außerdem steht noch der Vorteil, mit den Rückgabewerten, den Andreas angesprochen hat.

@Andreas
Konntest du dein Problem schon lösen. Ich hab dich wahrscheinlich falsch verstanden. Du hast quasi die Funktionen deines IP-Interfaces bereits direkt getestet. Ob man die com-veröffentlichten Methoden gleichzeitig als Command-Methods verwenden kann, weis ich nicht. Aber ich habe diese bei mir von einander getrennt. Es könnte schon sein, dass das die Ursache deines Fehlers ist.

Einen schönen Abend!

Grüße Robert

------------------
Robert Menger
Gabo Engineering GmbH
Entwicklung

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Brischke
Moderator
CAD on demand GmbH




Sehen Sie sich das Profil von Brischke an!   Senden Sie eine Private Message an Brischke  Schreiben Sie einen Gästebucheintrag für Brischke

Beiträge: 4191
Registriert: 17.05.2001

AutoCAD 20XX, defun-tools

erstellt am: 21. Feb. 2013 19:57    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Zitat:
Original erstellt von Boortsneggor:
... weil man im AutoCAD zeichnungsübergreifend eingeschränkt ist. <snip> Ich öffne nacheinander eine Reihe von dwgs, Ersetze und manipuliere Objekte, und speichere diese wieder. ...

auch da sehe ich keinen Grund, das ganze nicht direkt in der AutoCAD-Umgebung zu machen.
Gerade wenn es auf Geschwindigkeit ankommt, wenn mehrere Zeichnungen bearbeitet werden sollen, lade ich diese Zeichnungen nur als Database und bearbeite diese ohne anzuzeigen. Es gibt auch Situationen, da kommt man um ein SendStringToExecute nicht umhin. Diesgeht ja bekanntlich nur in aktiven Zeichnungen. Für diese Fälle ist mit 3 Zeilen ein DocumentCreated-Reaktor geschrieben, der die auszuführenden Befehle absetzt.

Naja, egal. Ich werde nicht den Weg über Com gehen. Zumal ich ohnehin auch unter .Net auf das Einbinden von Com-Objekten verzichte, da spätestens dadurch die Versions-unabhängigkeit verloren geht (leider ist aber noch nicht alles in der .Net-API enthalten). Das ist bei mir aber vielleicht auch etwas anderes, da meine Kunden imgrunde alle auf dem MArkt verfügbaren AutoCAD-Versionen im Einsatz haben - ich also keinesfalls auf nur eine Version bezogen programmieren kann/will.

Grüße!
Holger

------------------
Holger Brischke
FREIE SCHULUNGSPLÄTZE -- C#.NET-Schulung im Mai 2013 Bei Interesse bitte melden!
CAD on demand GmbH
Individuelle Lösungen von Heute auf Morgen.


defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!


Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Boortsneggor
Mitglied
Ingenieur


Sehen Sie sich das Profil von Boortsneggor an!   Senden Sie eine Private Message an Boortsneggor  Schreiben Sie einen Gästebucheintrag für Boortsneggor

Beiträge: 49
Registriert: 27.12.2011

Win7 Prof, Visual Studio 2010/2012,
ObjectARX 2008/2012/2013, ACAD
2008/2012/2013

erstellt am: 21. Feb. 2013 20:29    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Da hast du wohl ein wichtiges Argument von mir ignoriert. Live-Verfolgung! 
Außerdem benötigen manche grafische Änderungen die geöffnete Zeichnung. Beispiel Positionierung.
Auf das Thema Versionsunabhängigkeit bei AutoCad möchte ich nicht weiter eingehen.

Grüße robert

------------------
Robert Menger
Gabo Engineering GmbH
Entwicklung

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Brischke
Moderator
CAD on demand GmbH




Sehen Sie sich das Profil von Brischke an!   Senden Sie eine Private Message an Brischke  Schreiben Sie einen Gästebucheintrag für Brischke

Beiträge: 4191
Registriert: 17.05.2001

AutoCAD 20XX, defun-tools

erstellt am: 21. Feb. 2013 20:37    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Boortsneggor 10 Unities + Antwort hilfreich

Zitat:
Original erstellt von Boortsneggor:
Da hast du wohl ein wichtiges Argument von mir ignoriert. Live-Verfolgung!  

ok, manchmal sind die Operationen so langsam, dass man ja tatsächlich schon eine Sichtprüfung während der Bearbeitung machen könnte ;)
Zitat:
Original erstellt von Boortsneggor:
Außerdem benötigen manche grafische Änderungen die geöffnete Zeichnung. Beispiel Positionierung.

... das ist ja ohne weiteres möglich, wenn man es schafft den Befehl automatisiert anzuwerfen. Dafür der oben genannte Reactor, der den Befehl dann anwirft.
Zitat:
Original erstellt von Boortsneggor:
Auf das Thema Versionsunabhängigkeit bei AutoCad möchte ich nicht weiter eingehen. 

Das ist sicher gut .. denn das könnte einen weitern Thread füllen.

Danke für deine Ausführungen!
Grüße!
Holger

------------------
Holger Brischke
FREIE SCHULUNGSPLÄTZE -- C#.NET-Schulung im Mai 2013 Bei Interesse bitte melden!
CAD on demand GmbH
Individuelle Lösungen von Heute auf Morgen.


defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!


Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Anzeige.:

Anzeige: (Infos zum Werbeplatz >>)

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen

nächster neuerer Beitrag | nächster älterer Beitrag
Antwort erstellen


Diesen Beitrag mit Lesezeichen versehen ... | Nach anderen Beiträgen suchen | CAD.de-Newsletter

Administrative Optionen: Beitrag schliessen | Archivieren/Bewegen | Beitrag melden!

Fragen und Anregungen: Kritik-Forum | Neues aus der Community: Community-Forum

(c)2025 CAD.de | Impressum | Datenschutz