0

C# アプリケーションから COM+ コンポーネントのコンストラクタ文字列をプログラムで設定しようとしています。次のサンプル コードをオンラインで見つけましたが、例外がスローされます。

        COMAdminCatalogCollection Components;
        COMAdminCatalogClass Catalog = new COMAdminCatalogClass();
        string strConstr;
        string ApplicationName = "ApplicationName"; // case sensitive
        string CompName = "MyComponent.ProgID";
        COMAdminCatalogCollectionClass Applications = (COMAdminCatalogCollectionClass)Catalog.GetCollection("Applications");
        Applications.Populate();
        // find the correct application
        foreach (COMAdminCatalogObjectClass AppObject in Applications)
        {
            if (AppObject.Name == ApplicationName)
            {
                // find matching component
                Components = (COMAdminCatalogCollectionClass)(Applications.GetCollection("Components", AppObject.Key));
                Components.Populate();
                foreach (COMAdminCatalogObjectClass CompObject in Components)
                {
                    if (CompObject.Name.ToString() == CompName)
                    {
                        CompObject.get_Value("ConstructorString").ToString();
                        CompObject.get_Value("ConstructionEnabled").ToString();
                    }
                }
            }
        }

このコードを実行すると、6 行目で次の例外が発生します。

タイプ 'System.__ComObject' の COM オブジェクトをクラス タイプ 'COMAdmin.COMAdminCatalogCollectionClass' にキャストできません。CLR に入り、IProvideClassInfo をサポートしないか、相互運用アセンブリが登録されていない COM コンポーネントは、__ComObject 型にラップされます。この型のインスタンスは、他のクラスにキャストできません。ただし、基になる COM コンポーネントがインターフェイスの IID に対する QueryInterface 呼び出しをサポートしている限り、インターフェイスにキャストできます。

どこが間違っているのか分かりますか?または、これを行う簡単な方法はありますか?

4

2 に答える 2

3

例外を回避する方法を見つけました。これを C# で行うのではなく、VB.NET のオプションの弱い型指定を利用して、すべてのキャストといくつかの変数宣言型を削除できます。結果のコードは次のようになります。

    Dim Components As COMAdminCatalogCollection
    Dim Catalog As New COMAdminCatalogClass()
    Dim ApplicationName As String = "ApplicationName"
    Dim CompName As String = "MyComponent.ProgID"
    Dim Applications = Catalog.GetCollection("Applications")
    Applications.Populate()
    For Each AppObject In Applications

        If (AppObject.Name = ApplicationName) Then

            Components = (Applications.GetCollection("Components", AppObject.Key))
            Components.Populate()
            For Each CompObject In Components

                If (CompObject.Name.ToString() = CompName) Then
                    CompObject.Value("ConstructorString") = "Some new value"

                    Components.SaveChanges()
                End If

            Next
        End If
    Next

これは、VB と C# が大きく異なる 1 つの状況であり、これらのことを知っていると、仕事に適したツールを選択するのに非常に役立ちます。

于 2008-11-19T18:11:04.907 に答える