2016-08-28 7 views
0

COMオブジェクトでC#リフレクションを見つけて、コード内で多くの実験を行い、サンプルコードを分析して理解を深めてみるために、ここ数日を読んでいました。私はちょうど十分知らないので、私はコミュニティの助けを求めています。C#COMオブジェクトでのリフレクションの不一致

System._COMオブジェクトとしてラップされた遅延バインドされたCOMオブジェクトのプロパティにアクセスして更新する必要があります。

私はすべての標準的な反射物を成功させずに試しましたが、IDispatchを使って見ましたが、ポインタを使用するのは快適ではないので、通常のインターフェイスではかなり簡単なものを見逃してしまいました。私はMSDN上で私が必要とすることを行う方法を示している論文を見つけましたが、すべての例はC++であり、それは私の頭の上です。

期待通りに次のような単純なC#のコードがうまく動作しない理由を誰かが説明できるならば、それは本当に参考になる:

  try 
     { 
      // late binding: 
      // localCB is a COM object (System._COMObject) created by Activator.CreateInstance() from 
      // the ProgID of a registered COM .DLL. 
      // 
      // The original .DLL has a string PROPERTY called 
      // "TESTEXTERNAL1". localCB has an IDispatch Interface. The original COM .DLL has a separate Typelib, 
      // and, although I did not register the typelib separately, I can see from OLEView on the COM object 
      // that the GUID for the typelib is included in it. 

      // Here's the code that is puzzling me... 
      var vv = localCB.GetType().InvokeMember("TESTEXTERNAL1", BindingFlags.GetProperty, 
        null, localCB, null); 
      string rt = vv.ToString(); 
      // works exactly as expected and returns the value of TESTEXTERNAL1 - OK. 

      // now try and update the SAME PROPERTY, on the SAME COM object... 
      Parameters = new Object[1]; 
      Parameters[0] = "Hello, World!"; 
      localCB.GetType().InvokeMember("TESTEXTERNAL1", BindingFlags.SetProperty, 
        null, localCB, Parameters); 
      // throws an (inner) exception: HRESULT 0x8002003 DISP_E_MEMBERNOTFOUND !!! 

     } 
     catch (Exception xa) 
     { 
      string xam = xa.Message; 
     } 

はすでに見つかっや財産を提供しているオブジェクトを期待することは無理があります、同じプロパティを更新できるようにするには?私が気づいていない "代替更新"戦略がありますか?

多くのありがとうございました。

ピート。

はUPDATE:Jonの要求に応じて、

、ここでOLEVIEWの抜粋です: (私は申し訳ありませんが、OLEVIEWは私が&ペーストを切ることはできないだろうので、画像を使用していた...)

OleView of the COM .DLL

OLEView typelib view

ジョンは、私はあなたが正しく、問題はsetterメソッドであることを確認したと思います。 DLLはFujitsu COBOLで書かれており、PROPERTYとして識別されたフィールドにはGETとSETの下に "カバーの下に"あります。 C#またはCOBOLからCOMコンポーネントにアクセスすると、うまくいきますが、わかるように、リフレクションを使用してSETにアクセスしようとすると、動作しません。私は反射を使用することに慣れていないので、私は構文の権利があるかどうか疑問だったので、私は可能な限りGETにSETを近づけようとしました。私はCOBOLに(各プロパティの)私自身のSETメソッドを生成し、次に「BindingFlags.InvokeMember」であることを私の「BindingFlags.SetProperty」を変更する必要があると思います。 (私はBindingFlagsの宿題をして、あなたが "SetProperty"を指定すると、あなたが言及した他の2つのフラグを自動的に暗示することを発見しました)。

私はその問題が富士通* COMクラスSET、それはあなたの経験豊かな目を見ました。どうもありがとう。あなたがでOLEViewを見た後、他の意見を持っている、または設定されたプロパティを取得するために、任意の代替アプローチを提案することができる場合、私は非常に興味があると思います。 (私はすべてのプロパティのセッターメソッドを生成することを楽しみにしていないよ。それは、ブルートフォースの萌芽... :-))

おかげで再び、

ピートを。

+1

これは、OleViewの出力で見つかったプロパティの宣言をコピー/貼り付けするときに、正確に答えるのが簡単です。最初の説明は、プロパティにはセッターがないことです。次に、BindingFlags.PutDispPropertyとBindingFlags.PutRefDispPropertyを区別して、プロパティに2つの異なるセッター(putとputref)を指定できるということです。 –

+0

ジョン、ご意見ありがとうございます。私は今は別のマシンにいますが、明日の記事はOLEViewのプロパティの説明で更新します。したがって、更新のためにポストされた構文はOKですか?あなたが言及したBindingフラグについていくつかの宿題をします。 – Morepork

+0

HansPassantに心からお詫び申し上げます。私はコメントのポスター(StackOverflowや他の場所でのものを櫛を切った日)を間違って読んで、それがJon Skeetだと思った。だから非常に非常に残念ハンスと本当にあなたが提供していただきありがとうございます。 – Morepork

答えて

0

ハンスは正しかったです。問題はセッターメソッドで問題だった。私は、元のCOBOL COMコンポーネントで、特性の各々についてセッターを生成するためのコードを書かれています。それは私が思うように面倒でも醜いものでもなく(それぞれの財産に対して約7行のCOBOL)、それは今とてもうまくいっています。コミュニティ、特にHans Passantのサポートに感謝します。

関連する問題