2010年7月11日日曜日

.NET - 「他の図面にバックグラウンドでアクセス」(AutoCAD 2011)

今開いている図面以外の図面に対してバックグラウンドでアクセスできるか試してみました。

ReadDwgFile メソッドで今開いていない図面を読み込むことができるようです。

試しに作成したコードは こちら で、ビルドした DLL は こちら です。

AVDO_CheckLayer コマンドを実行して、図面ファイルを選択すると、選択した図面にあって今開いている図面にない画層があれば、それが表示されます。

動画も作ってみましたので、見てみてください。



これと同じ方法で、2つの図面のシステム変数の比較ができるかもしれません。
そうすれば、特定の図面でのみ発生する現象がシステム変数の影響かどうかを確認しやすくなりそうなので、後日チャレンジしてみたいと思います。

2010年7月6日火曜日

.NET - 「AutoCAD をバックグラウンドで実行する方法見つからず」(AutoCAD 2011)

Twitter でもつぶやいていたんですが、Windows アプリから AutoCAD をバックグラウンドで起動して何か実行することをやろうと思ったのですが、残念ながら方法を見つけることができませんでした。

今回はギブアップだったのですが、一応履歴としてどんなことしたか書いとこうかと思います。



「AutoCAD .NET デベロッパガイド」を参考に、CreateObjec を使ってこんな感じで AutoCAD を起動することができました。
Dim acAppComObj As AcadApplication
acAppComObj = CreateObject("AutoCAD.Application.18.1")

で、起動したあとにこんな感じで NETLOAD コマンドを実行してロードしたあとコマンドを実行します。
acDocComObj.SendCommand("(command " & Chr(34) & "NETLOAD" & Chr(34) & " " & _
Chr(34) & "c:/myapps/mycommands.dll" & Chr(34) & ") ")

acDocComObj.SendCommand("MyCommand ")

実行するコマンドで、最後に図面を保存して AutoCAD を終了するようにしておけば、勝手に作業を初めて勝手に終了するという動作になります。


【できなかったこと】
CreateObject で AutoCAD を起動できたんですが、AutoCAD のウインドウを表示することなくバックグラウンドで動かすことができませんでした。

acAppComObj.Visible = False とすれば非表示になるんですが、一旦 AutoCAD が起動してくるのが見えて、その後非表示という動きになりました。また、その後 SendCommand を実行すると、また AutoCAD のウインドウが表示されてしまいました。


ということで、AutoCAD を起動する方法として探してみたら、こんな方法がありました。
Dim regKey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Autodesk\AutoCAD\R18.1\ACAD-9001:411")
Dim acadLoc As String = DirectCast(regKey.GetValue("Location"), String)

Dim acad As ProcessStartInfo = New ProcessStartInfo(acadLoc & "\acad.exe")
acad.Arguments = "/nologo"
'acad.WindowStyle = ProcessWindowStyle.Hidden

Dim pro As Process
pro = Process.Start(acad)

この後、こんな感じで AutoCAD のインスタンスを取得することができます。
Dim acAppComObj() As AcadApplication
acAppComObj = GetObject(, "AutoCAD.Application.18.1")

でも、これだとプログラムが AutoCAD が起動してくるまで待ってくれないで先に進んでしまうので、ちゃんと動きません。

WaitForInputIdle っていうので待ってくれるかなと思ったんですが、待ってくれませんでした。

そこで、WaitForExit(20000) で 20 秒間待つようにしてみたところ、ちゃんと動くようになりました。
でも、もし AutoCAD が起動するまで 20 秒以上たったらちゃんと動かないし、安全のためもっと長くしても時間がかかってもったいないですよね。

また、もっと大きな問題で、AutoCAD が他に起動されていると、そっちに SendCommand で指定したコマンドが送られてしまうのでおかしなことになってしまいます。

複数 AutoCAD が起動しているときに識別する方法がないかググッてみたのですが、残念ながらその方法を見つけることができませんでした。(VB.NET では無理なのかも???)

ということで、今回はギブアップしてしまいました…残念。

2010年7月2日金曜日

.NET(サンプル プログラム) - 「図面で実行されたコマンドを集計」(AutoCAD 2011)

ディクショナリの使い方を勉強してみました。

ディクショナリを作って、情報を保存して、その情報を取得してといった一通りを試してみました。

どんな動作にしようかと思ったのですが、とりあえず作ってみたコマンドと関数はこんな感じです。
  • AVDO_StartCountCommands : コマンドが開始されたときのイベントを登録し、ディクショナリを追加するコマンド
  • CommandStarted : コマンドが開始されたときに実行する関数
  • AVDO_EndCountCommands : コマンドが開始されたときのイベントの登録を解除するコマンド
  • AVDO_RemoveCountCommandsDictionary : 追加したディクショナリを削除するコマンド
  • AVDO_ShowCommandsCount : 各コマンドの実行回数を表示するコマンド
コードは こちら で、ビルドした DLL は こちらです。

【使い方の例】
  1. NETLOAD コマンドで CountCommands.dll をロード
  2. AVDO_StartCountCommands コマンドを実行
  3. いくつかコマンドを実行した後、AVDO_ShowCommandsCount コマンドを実行すると、どのコマンドを何回実行したか表示されます。
※ AutoCAD が自動的に実行しているコマンドも表示されます。
※ REDRAW、REDRAWALL、QVDRAWING、QVLAYOUT コマンドに対してはうまく動かなかったので、除外しました。

使ってみた動画も作ってみました。