2019年7月8日月曜日

TeighaShell プログラムの骨格を説明

 Teigha は、C++ のネイティブ API と、オートメーション APIと、Classic と Swig の2種類の .Net API が提供されている。
 このうち、オートメーション API と、Teigha Classic .Net API が AutoCAD 準拠になっている。Swig API は、SWIG (Simplified Wrapper and Interface Generator) によってネイティブ API を .Net Framework に提供したものなので、Teigha 独自の仕様になっている。

2019/7/24
Teigha Classic .Net API のホストサービスを持つクラスライブラリとしてマネージドライブラリを作成しました。
これを、PowerShell コンソールや PowerShell ISE にロードさせることで、Teigha Classic .Net API の機能を、PowerShell コンソールや PowerShell ISE に「公開」することができたので、下記の記述は古いです。
下記の方法で得られた知見もあったので、取り消し線を引いて残しておきます。


最初は PowerShell に、 system.reflection.assembly クラスの LoadFrom(dllファイル名) 手続きで、 Teigha Classic .Net API を提供する TD_Mgd_20.5_15.dll ファイルをロードすればいけるのかと思ったのですが、それだけではうまくいきませんでした。

Teigha のホストアプリケーションを作成して、そこから PowerShell を起動する必要がありました。TeighaShell プログラムは、Teigha .Net Classic API の最低限のホストアプリケーションが、PowerShell を起動しているという骨格になっています。

Teigha .Net Classic ホストアプリケーションの骨格

メインプログラム (Program.cs) からTeigha に関係する部分のみ抜き出すと次のようになります。
[STAThread]
static void Main(string[] args)
{
    // アクティベーションを割り当て
    Services.odActivate(ActivationData.userInfo,
    ActivationData.userSignature);
    using (Services svcs = new Services())
    {
        // アプリケーションサービスを割り当て
        HostApplicationServices.Current = new HostAppServ();
               // 起動時メッセージを表示
        Console.WriteLine("\nTeighaShell developed using {0} ver {1}",
           HostApplicationServices.Current.Product,
           HostApplicationServices.Current.VersionString);
               (略 PowerShell の実行部)
    }//TeighaServiceの終了
}//メインプログラムの終了

最低限のホストアプリケーションサービス(HostAppServ.cs)は、Teighaのサンプルそのままを使用しています。
Teigha.DatabaseServices.HostApplicationService クラスは、FindFile メソッドが抽象メソッド abstract になっているので、これを派生クラス HostAppServ で実装する必要があります。HostAppServクラスのFindFileメソッドの実装は、AutoCADがインストールされたときに存在するレジストリや、ユーザーデータフォルダを調べて、サポートファイルのパス名を解決しているので、自社の環境に合わせて修正するのが望ましい。

PowerShellの起動と実行

メインプログラム (Program.cs) からPowerShell に関係する最低限の部分を抜き出すと次のようになります
[STAThread]
static void Main(string[] args)
{
(略)
// Runspace 実行空間インスタンスを生成
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
  runspace.Open();
  // PowerShell インスタンスを生成
  using (var powershell = PowerShell.Create())
  {
    powershell.Runspace = runspace;
    // メインループ
    while (true)
    {
      // スクリプトの1行入力待ち
      string st = Console.ReadLine();
      // ユーザーが入力した内容をスクリプトとする
      powershell.AddScript(st);
      // コマンドを実行
      Collection<PSObject> psOutput = powershell.Invoke();
      // 実行結果を文字列化
      foreach (PSObject outputItem in psOutput)
      {
      strbuilder.AppendLine(outputItem.ToString());
      }
// 結果をコンソールに出力
Console.Write(strbuilder.ToString());
// コマンドとエラーをクリア
powershell.Commands.Clear();
powershell.Streams.Error.Clear();
}
  }// PowerShellの終了
}// Runspaceの終了
(略)
}//メインプログラムの終了
実行空間を作って、PowerShellエンジンを作って実行空間に割り当てる。
入力した内容を、スクリプトとしてエンジンに渡してから処理を行う。
結果はPSObjectのコレクションに返されるので、それを文字列化して画面に表示する。
という動きになる。

PowerShell で実行した結果エラーになったら、エラーメッセージを表示したいとか、この状態では PowerShell スクリプトが実行できないので、実行できるようにするとか、コンソールの1行入力は、CTRL+C の押下でコンソールアプリケーションが突然死するので、それをやめたいとか、骨格に追加した部分についてはソースプログラムとそのコメントで確認してください。



0 件のコメント:

コメントを投稿

ARESのトリニティ(三位一体)

 ARESのトリニティ戦略、どこがトリニティなんでしょう。 まずはデスクトップCADが、WindowsにもMacにもLinux版もあるというトリニティ。 デスクトップCADと、モバイルCAD(ARES Touch)と、ブラウザとサーバーCAD(ARES Kudo)のトリニティ。 ...