SaveAs in COM hangs AutoCAD

I am implementing an application that uses COM in the AutoCAD ObjectARX interface to automate drawing actions such as opening and saving as.

According to the documentation, I should be able to call AcadDocument.SaveAs () and pass the file name, "save as type" and security parameter. The documentation explicitly states that if the security value is NULL, no security-related operation is undertaken. However, this does not indicate that the correct type of the object is passed as the "save as type" parameter.

I tried calling SaveAs with the file name and null for the remaining arguments, but my application hangs in this method call, and AutoCAD crashes - you can still use the ribbon, but you can’t do anything using the toolbar and you can’t close AutoCAD.

I have the feeling that my NULL parameters are sad here, but the documentation in the COM / VBA department is very lacking. In fact, he says that the AcadDocument class does not even have a SaveAs method, which it explicitly does.

Has anyone here implemented the same thing? Any guidance?

An alternative is to use the SendCommand () method to send the _SAVEAS command, but my application controls the drawing batch and should know: a) if the failure fails, and b) when the save completes (that I'm listening to the EndSave event.)

EDIT

- , , AutoCAD ( , ), , (C:\Scratch\Document01B.dwg.)

using (AutoCad cad = AutoCad.Instance)
{
    // Launch AutoCAD
    cad.Launch();

    // Open drawing
    cad.OpenDrawing(@"C:\Scratch\Drawing01.dwg");

    // Save it
    cad.SaveAs(@"C:\Scratch\Drawing01B.dwg");
}

AutoCad (this._acadDocument AcadDocument.)

public void Launch()
{
    this._acadApplication = null;
    const string ProgramId = "AutoCAD.Application.18";

    try
    {
        // Connect to a running instance
        this._acadApplication = (AcadApplication)Marshal.GetActiveObject(ProgramId);
    }
    catch (COMException)
    {
        /* No instance running, launch one */

        try
        {
            this._acadApplication = (AcadApplication)Activator.CreateInstance(
                Type.GetTypeFromProgID(ProgramId), 
                true);
        }
        catch (COMException exception)
        {
            // Failed - is AutoCAD installed?
            throw new AutoCadNotFoundException(exception);
        }
    }

    /* Listen for the events we need and make the application visible */
    this._acadApplication.BeginOpen += this.OnAcadBeginOpen;
    this._acadApplication.BeginSave += this.OnAcadBeginSave;
    this._acadApplication.EndOpen += this.OnAcadEndOpen;
    this._acadApplication.EndSave += this.OnAcadEndSave;

#if DEBUG
    this._acadApplication.Visible = true;
#else
    this._acadApplication.Visible = false;
#endif

    // Get the active document
    this._acadDocument = this._acadApplication.ActiveDocument;
}

public void OpenDrawing(string path)
{
    // Request AutoCAD to open the document
    this._acadApplication.Documents.Open(path, false, null);

    // Update our reference to the new document
    this._acadDocument = this._acadApplication.ActiveDocument;
}

public void SaveAs(string fullPath)
{
    this._acadDocument.SaveAs(fullPath, null, null);
}
+3
4

, , , -, SaveAs AutoCAD .

:

, /:

this._acadDocument.SetVariable("FILEDIA", 0);

_SAVEAS, "2010", (fullPath):

string commandString = string.Format(
    "(command \"_SAVEAS\" \"{0}\" \"{1}\") ",
    "2010",
    fullPath.Replace('\\', '/'));

this._acadDocument.SendCommand(commandString);

AutoCAD (, , ):

this._acadDocument.SetVariable("FILEDIA", 1);
0

Autodesk , , , :

app = new AcadApplicationClass();
AcadDocument doc = app.ActiveDocument; doc.SaveAs("d:\Sam.dwg",AcSaveAsType.acR15_dwg,new Autodesk.AutoCAD.DatabaseServices.SecurityParameters());

AutoCAD 2010, acR17_dwg acR18_dwg.

+2

AutoDesk , , .. ... , try/catch, , !

, Launch , ? OpenDrawing Save, this._acadApplication, ?

using (AutoCad cad = AutoCad.Instance)
{
    try{
       // Launch AutoCAD
       cad.Launch();

       // Open drawing
       cad.OpenDrawing(@"C:\Scratch\Drawing01.dwg");

       // Save it
       cad.SaveAs(@"C:\Scratch\Drawing01B.dwg");
    }catch(COMException ex){
       // Handle the exception here
    }
}

public void Launch()
{
    this._acadApplication = null;
    const string ProgramId = "AutoCAD.Application.18";

    try
    {
        // Connect to a running instance
        this._acadApplication = (AcadApplication)Marshal.GetActiveObject(ProgramId);
    }
    catch (COMException)
    {
        /* No instance running, launch one */

        try
        {
            this._acadApplication = (AcadApplication)Activator.CreateInstance(
                Type.GetTypeFromProgID(ProgramId), 
                true);
        }
        catch (COMException exception)
        {
            // Failed - is AutoCAD installed?
            throw new AutoCadNotFoundException(exception);
        }
    }

    /* Listen for the events we need and make the application visible */
    this._acadApplication.BeginOpen += this.OnAcadBeginOpen;
    this._acadApplication.BeginSave += this.OnAcadBeginSave;
    this._acadApplication.EndOpen += this.OnAcadEndOpen;
    this._acadApplication.EndSave += this.OnAcadEndSave;

#if DEBUG
    this._acadApplication.Visible = true;
#else
    this._acadApplication.Visible = false;
#endif

    // Get the active document
    // this._acadDocument = this._acadApplication.ActiveDocument; 
    // Comment ^^^ out? as you're instantiating an ActiveDocument below when opening the drawing?
}

public void OpenDrawing(string path)
{
    try{
       // Request AutoCAD to open the document
       this._acadApplication.Documents.Open(path, false, null);

       // Update our reference to the new document
       this._acadDocument = this._acadApplication.ActiveDocument;
    }catch(COMException ex){
       // Handle the exception here
    }
}

public void SaveAs(string fullPath)
{
    try{
       this._acadDocument.SaveAs(fullPath, null, null);
    }catch(COMException ex){
       // Handle the exception here
    }finally{
       this._acadDocument.Close();
    }
}

, .

, , , .

+1

With C # and COM, when there are additional arguments, you need to use Type.Missingnull instead:

this._acadDocument.SaveAs(fullPath, Type.Missing, Type.Missing);

But with Visual Studio 2010, you can simply omit the optional arguments:

this._acadDocument.SaveAs(fullPath);
0
source

Source: https://habr.com/ru/post/1733329/


All Articles