3

AutoCAD の ObjectARX インターフェイスで COM を使用して、開く、名前を付けて保存などの描画アクションを自動化するアプリケーションを実装しています。

ドキュメントによると、AcadDocument.SaveAs() を呼び出して、ファイル名、「ファイルの種類」、およびセキュリティ パラメータを渡すことができるはずです。ドキュメントには、セキュリティが NULL の場合、セキュリティ関連の操作は試行されないことが明示的に記載されています。ただし、「タイプとして保存」パラメータとして渡す正しいオブジェクト タイプは示されません。

ファイル名を指定し、残りの引数に null を指定して SaveAs を呼び出してみましたが、アプリケーションがそのメソッド呼び出しでハングし、AutoCAD がクラッシュしたように見えます。リボンは引き続き使用できますが、ツールバーで何もできず、閉じることもできません。オートキャド。

ここで悲しみを引き起こしているのは私の NULL パラメーターであると感じていますが、COM/VBA 部門にはドキュメントが大幅に不足しています。実際、AcadDocument クラスには SaveAs メソッドさえないと言われていますが、それは明らかにあります。

ここで誰かが同じことを実装しましたか? ガイダンスはありますか?

別の方法として、SendCommand() メソッドを使用して _SAVEAS コマンドを送信しますが、私のアプリケーションは描画のバッチを管理しており、a) 保存が失敗したかどうか、および b) 保存がいつ完了したかを知る必要があります (これは私が行っていることです)。 EndSave イベントをリッスンします。)

編集

要求されたコードは次のとおりです。実行しているのは、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);
}
4

4 に答える 4

2

Autodeskディスカッション グループから、2 番目のパラメータは保存するタイプのようで、必要になる場合があります。

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 にインクリメントする必要があります。

于 2010-04-28T17:57:48.210 に答える
1

このトピックに関するAutoDeskのフォーラムへのリンクから判断すると、保存後にオブジェクトを閉じる必要があるように思えます...そしてヌルを削除します...私があなただったら、コードをtry/catchブロックにラップします例外がスローされていないことを確認してください。

using 句の使用法について質問する必要Launchがあります。別のコピーを作成しているのですね。つまり、あなたが使用しているOpenDrawingandSave関数内で、this._acadApplicationまたは誤解していますか?

使用 (AutoCad cad = AutoCad.Instance)
{
    試す{
       // AutoCAD を起動
       cad.Launch();

       // 図面を開く
       cad.OpenDrawing(@"C:\Scratch\Drawing01.dwg");

       // それを保存
       cad.SaveAs(@"C:\Scratch\Drawing01B.dwg");
    }catch(COMException ex){
       // ここで例外を処理します
    }
}

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

    試す
    {
        // 実行中のインスタンスに接続
        this._acadApplication = (AcadApplication)Marshal.GetActiveObject(ProgramId);
    }
    キャッチ (COMException)
    {
        /* インスタンスが実行されていません。1 つ起動します */

        試す
        {
            this._acadApplication = (AcadApplication)Activator.CreateInstance(
                Type.GetTypeFromProgID(プログラム ID)、
                真実);
        }
        キャッチ (COMException 例外)
        {
            // 失敗 - AutoCAD がインストールされていますか?
            新しい AutoCadNotFoundException(例外) をスローします。
        }
    }

    /* 必要なイベントをリッスンし、アプリケーションを可視化します */
    this._acadApplication.BeginOpen += this.OnAcadBeginOpen;
    this._acadApplication.BeginSave += this.OnAcadBeginSave;
    this._acadApplication.EndOpen += this.OnAcadEndOpen;
    this._acadApplication.EndSave += this.OnAcadEndSave;

#if デバッグ
    this._acadApplication.Visible = true;
#そうしないと
    this._acadApplication.Visible = false;
#endif

    // アクティブなドキュメントを取得
    // this._acadDocument = this._acadApplication.ActiveDocument;
    // コメント ^^^ アウト? 図面を開くときに以下の ActiveDocument をインスタンス化しているのでしょうか?
}

public void OpenDrawing(文字列パス)
{
    試す{
       // AutoCAD にドキュメントを開くように要求します
       this._acadApplication.Documents.Open(パス、false、null);

       // 新しいドキュメントへの参照を更新します
       this._acadDocument = this._acadApplication.ActiveDocument;
    }catch(COMException ex){
       // ここで例外を処理します
    }
}

public void SaveAs(string fullPath)
{
    試す{
       this._acadDocument.SaveAs(fullPath, null, null);
    }catch(COMException ex){
       // ここで例外を処理します
    }最後に{
       this._acadDocument.Close();
    }
}

あなたの情報のためにいくつかのリンクを含めたいと思いました。

これがお役に立てば幸いです。よろしくお願いします、トム。

于 2010-02-18T13:52:48.453 に答える
0

私はこれを最適ではない非常に不完全な方法で解決することができたので、SaveAs メソッドが AutoCAD をクラッシュさせ、アプリケーションをハングさせる理由を誰かが知っているかどうか聞いてみたいと思います。

これが私がそれをした方法です:

ドキュメントを開くとき、または新しいドキュメントを作成するときは、開く/保存するダイアログ ボックスをオフにします。

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

ドキュメントを保存するときは、_SAVEAS コマンドを発行して、形式とファイル名 (フルパス) として「2010」を渡します。

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

this._acadDocument.SendCommand(commandString);

AutoCAD を終了すると、ファイル ダイアログのプロンプトが再び表示されます (おそらく必要ではありませんが、念のため確認するだけです):

this._acadDocument.SetVariable("FILEDIA", 1);
于 2010-02-18T15:33:46.593 に答える