在COM挂起AutoCAD中保存(SaveAs in COM hanging AutoCAD)
我正在实现一个在AutoCAD的ObjectARX界面中使用COM来自动执行绘图操作的应用程序,例如open和save as。
根据文档,我应该能够调用AcadDocument.SaveAs()并传入文件名,“另存为类型”和安全参数。 文档明确声明如果安全性为NULL,则不会尝试与安全性相关的操作。 但是,它不会指示要传递的正确对象类型作为“另存为类型”参数。
我尝试使用文件名调用SaveAs并为其余参数调用null,但我的应用程序挂起该方法调用并且AutoCAD似乎崩溃 - 您仍然可以使用功能区但无法对工具栏执行任何操作且无法关闭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); }
I'm implementing an application which uses COM in AutoCAD's ObjectARX interface to automate drawing actions, such as open and save as.
According to the documentation, I should be able to call AcadDocument.SaveAs() and pass in a filename, a "save as type" and a security parameter. The documentation explicitly statses that if security is NULL, no security related operation is attempted. It doesn't, however, give any indication of the correct object type to pass as the "save as type" parameter.
I've tried calling SaveAs with a filename and null for the remaining arguments, but my application hangs on that method call and AutoCAD appears to crash - you can still use the ribbon but can't do anything with the toolbar and can't close AutoCAD.
I've got a feeling that it's my NULL parameters causing grief here, but the documentation is severely lacking in the COM/VBA department. In fact it says the AcadDocument class doesn't even have a SaveAs method, which it clearly does.
Has anyone here implemented the same thing? Any guidance?
The alternative is I use the SendCommand() method to send a _SAVEAS command, but my application is managing a batch of drawing and needs to know a) if the save fails, and b) when the save completes (which I'm doing by listening to the EndSave event.)
EDIT
Here's the code as requested - all it's doing is launching AutoCAD (or connecting to the running instance if it's already running), opening an existing drawing, then saving the document to a new location (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"); }
Then in my AutoCad class (this._acadDocument is an instance of the AcadDocument class.)
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); }
原文:https://stackoverflow.com/questions/2287864
最满意答案
你必须使用equals方法进行String的比较。
if (ISPP.equals("A"))
此外,您可以使用compareTo方法
if (ISPP.compareTo("A") == 0)
You have to make comparision of String with equals method.
if (ISPP.equals("A"))
Also, you can use compareTo method
if (ISPP.compareTo("A") == 0)
相关问答
更多-
TCP/IP模型是一个________。[2023-10-02]
a -
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
为什么C ++中的“按Enter继续”代码不起作用?(Why is this “Press Enter to Continue” code in C++ not working?)[2022-03-04]
在为ans提供一些数据后,您可能已经输入了“enter”。 在这种情况下, cin.ignore()将读取“enter”并立即返回。 因此,您需要另一个cin.ignore()来等待另一个“enter”。 You may have already entered "enter" after providing some data for ans. In that case, the cin.ignore() will read the "enter" and immediately return. Ther ... -
为什么“B”不等于“B”?(Why is “B” not equal to “B”?)[2023-10-17]
您将换行符包含在从文件中读取的字符串中。 你要 x = file.readline().strip() You're including the newline in the string you read from the file. You want x = file.readline().strip() -
你必须使用equals方法进行String的比较。 if (ISPP.equals("A")) 此外,您可以使用compareTo方法 if (ISPP.compareTo("A") == 0) You have to make comparision of String with equals method. if (ISPP.equals("A")) Also, you can use compareTo method if (ISPP.compareTo("A") == 0)
-
你不需要两个嵌套循环,你需要一个循环同时迭代两个数组: for (int i = 0 ; i < Math.min(numbers.length, letters.length) ; i++) { Log.i("sas","Result " + numbers[i] + letters[i]); } 如果您确定两个数组都具有相同数量的元素,则可以使用其中一个数组的length (即numbers.length或letters.length ,因为它们相等而无关紧要)for for循环的停止条 ...
-
让我们一起简化它 int a = 1; int b = 2; a ^= (b ^= (a ^= b)); System.out.println(a + " " + b); 就像说的一样 int a = 1; int b = 2; int a_tmp = a; a = a_tmp ^ (b ^= (a ^= b)); System.out.println(a + " " + b); 你的代码假设我们在^ = (b ^ =(a ^ = b))之前处理^ =(b ^ =( a ^ = b ))但这是错误的。 ...
-
Java,选择子序列(Java, choose subsequence)[2021-08-27]
你得到***aaaaaaaaaaaaaaaaaaa和这个循环的结果 index = 0; for(int d = 1; d < 27; d++){ if(occurrences[d] > occurrences[index]) index = d; } 表示occurrence出现数组中的每个项目都为0.这意味着您的算法默认将array[0]附加到text_generated字符串。 这意味着问题出在这个块中 for(int c = 0; c <= text_formatted.length( ... -
您可以使用Scanner类。 添加此导入: import java.util.Scanner; 然后在你的main方法中执行以下操作: public static void main(String args[]){ Scanner keyboard = new Scanner(System.in); System.out.println("Enter your text"); String textToEncrypt = keyboard.next(); String ...
-
您不需要重新声明变量,只需重新分配它(在标记的行中): student1 = input.next().charAt(0); 无论如何,您应该将其实现为循环,因为用户可能会再次输入错误的值... You don't need to redeclare the variable, just re-assign to it (in the marked line): student1 = input.next().charAt(0); Anyway, you should probably implemen ...