4

.NET 4.0 アプリケーションから Adob​​e InDesign CS3 のいくつかのタスクを自動化する必要があります。Visual Studio の [参照の追加] ダイアログを使用して、InDesign タイプ ライブラリへの参照を追加しました。これは、タイプ ライブラリで宣言されたすべてのインターフェイスと型を正しく含む相互運用アセンブリを生成します。タイプ ライブラリは、Adobe InDesign CS3 以外は何もインストールせずに Visual Studio で使用できるため、Adobe SDK はインストールしていません。

現在私にとって相互運用アセンブリで興味深い型は、 interfaces_ApplicationApplication、および classApplicationClassです。それらの定義は次のとおりです。したがって、それらの関係を確認できます。

public interface _Application
{
    // Lots of properties and methods
}

public interface Application : _Application
{
    // Empty
}

public class ApplicationClass : _Application, Application
{
    // The same properties and methods as declared in _Application
}

次のように COM オブジェクトをインスタンス化しようとします。

Type oType = Type.GetTypeFromProgID("InDesign.Application.CS3");
if (oType != null)
{
    object instance = Activator.CreateInstance(oType);
}

このコードは成功します。インスタンスを取得しますが、タイプは__ComObject. 私の知る限り、これは完全に正常です。

さあ、ここからが楽しみの始まりです。このインスタンスを使用できるようにするには、正しいインターフェイスにキャストする必要があります。ネット上の他の例と、ここで入手可能なドキュメントから、インターフェイスにキャストする必要があることがわかりApplicationます。しかし、それを行うと、型がこのインターフェースをサポートしていないという厄介なInvalidCastException発言が返ってきます。またはインターフェイスSystem.__ComObjectにキャストしようとすると、同じ例外が発生します。ApplicationClass_Application

おそらく間違ったインターフェイスを使用しているのではないかと思ったので、ここにリストされているユーティリティ関数を実装してみました。この関数は、interop アセンブリで宣言されているすべてのインターフェイスをループ処理し、IUnknown インターフェイスが実装されているかどうかを照会します。

その関数を使用すると、null が返されます。これは、取得したインスタンスが相互運用アセンブリのインターフェイスをCreateInstanceサポートしていないことを意味します。きっと、そんなはずない!?

しかし、instanceVisual Studio デバッガーで変数を調べると、「動的ビュー」と呼ばれるものがあります。それを展開すると、オブジェクトのすべてのプロパティが一覧表示され、すべてのプロパティがApplicationClassクラスおよび_Applicationインターフェイスのプロパティと一致します。だから私は使っType.InvokeMemberてみましたが、うまくいきます:

oType.InvokeMember("DoScript", BindingFlags.InvokeMethod, null, instance, oArguments, CultureInfo.InvariantCulture);

これは実際には機能しますが、このように COM オブジェクトと対話するのは非常に面倒です。また、COM オブジェクトと多くの対話を行う必要があるため、実際には使用できません。COM オブジェクトのラッパーを作成できると思いますが、それでは相互運用アセンブリの目的が無効になるため、700 以上のラッパー クラスを作成したくありません。

私はたくさん検索しましたが、InDesign COM オブジェクトを使用するチュートリアルと例を見つけましたが、それらはすべて、返されたインスタンスを Application インターフェイスにキャストするだけですが、説明したように、これは私の場合は機能しません。

上記のコードの代わりに、次のコードも試しました。

InDesign.Application app = new InDesign.Application();
app.Activate();

最初の行は成功し、 のインスタンスを取得しますがApplicationClass、2 行目を実行しようとするとApplicationClass、インターフェイスに変換できないことを示す InvalidCastException が発生します_Application

私はここで本当に追い詰められており、次に何を試すべきかわかりません. COM と .NET の経験が豊富な人が、私が間違っている可能性があることを理解してくれることを心から願っています。

事前に感謝します。長い投稿で申し訳ありません。

4

3 に答える 3

2

Runtime Callable Wrapperを使用する必要があります

あなたが必要とする方法はこれです

これを試して :

    Type oType = Type.GetTypeFromProgID("InDesign.Application.CS3");
    if (oType != null)
    {
        object instance = Activator.CreateInstance(oType);// or any other way you can get it
        Application app = 
            (Application)System.Runtime.InteropServices.Marshal.CreateWrapperOfType(instance, typeof(ApplicationClass));
    }
于 2011-10-18T14:25:28.483 に答える
1

@Seb ソリューションは正しいソリューションですが、作業中に「必要なすべてのインターフェイスをサポートしていないため、ソース オブジェクトを宛先タイプに変換できません」というエラーが発生しました。(@MikeKeskinovがコメントで書いたように)。

そのエラーを取り除くには、次の手順を実行して COM オブジェクトを登録する必要があります (既にここで説明されています) - これは InDesign CC2021 v16.0 用です (他のバージョンでも同様です)。

  • タスク マネージャーを使用して InDesign のすべてのインスタンスを閉じる
  • に移動してC:\ProgramData\Adobe\InDesign\Version 16.0\en_US\Scripting Support\16.0、tlb ファイルの名前を tlb.bak に変更します (または同様のものでかまいません)。
  • 管理者としてコマンド ウィンドウ (CMD) を開く
  • InDesign EXE フォルダーに移動します。C:\Program Files\Adobe\Adobe InDesign 2021
  • 開始コマンドindesign.exe -type
  • 新しく作成した tlb ファイルをプロジェクトに参照する

そしてその後、それはうまくいくはずです。誰かの役に立てば幸いです!

于 2021-01-11T12:30:28.120 に答える
0

私は最近COMを使用していませんでしたが、私が覚えている限り(そしてあなたの問題を理解している限り)、次のようにComObjectをキャストすることはできません:

   Application app = (Application)comObject;

ただし、演​​算子として使用する必要があります:

    Application = comObject as Application;
于 2011-10-18T13:59:52.190 に答える