0

既にネイティブ コードの COM オブジェクトがあり、C# からインスタンス化しようとしています。Com は、DCOM コンポーネントとレジストリに登録されます。

これは私がやろうとしていることです:

public static void Main(string[] args)
{
    Type t = Type.GetTypeFromProgID("CaseConsole.Application");

    dynamic app = Activator.CreateInstance(t);
    dynamic c = app.Case;

    c.OpenCase("17-16", 0);
}

com-type をインスタンス化しようとすると、次のようになります。

NotImplementedException

execption は次の行でスローされます。

dynamic c = app.Case;

この行にブレークポイントを設定したので、「アプリ」を調べたところ、エラーは既に存在していました

Type t を調べたところ、IsCOMObject = true と表示されました。

VBSとしてはうまく機能します:

Dim App
Dim c

Set App = CreateObject ("CaseConsole.Application")
Set c = App.Case

c.OpenCase "17-16", 0

VB.netとして動作します

Sub Main()
    Dim App
    Dim c

    App = CreateObject("CaseConsole.Application")
    c = App.Case

    c.OpenCase("17-16", 0)
End Sub

ただし、C# ではありません

C# の例では、次のソースを調べました。

http://www.codeproject.com/Articles/990/Understanding-Classic-COM-Interoperability-With-NE

https://msdn.microsoft.com/en-us/library/aa645736%28v=vs.71%29.aspx

C# の CreateObject の同等のコード

私の推測では、InvokeMember またはセキュリティ機能を使用してメソッドを呼び出さなければならないということです...

C# の例を機能させるのを手伝ってくれませんか?

名前の変更ケースを c に更新しましたが、それは問題ではありませんでした。

4

2 に答える 2

0

Your C# program is subtly different from the VBS and VB.NET programs. The apartment state of the thread that runs this code is different. The exception comes from the proxy, it should be interpreted as "running this code from a worker thread is not supported". Nicely done. Fix:

[STAThread]
public static void Main(string[] args)
{
   // etc..
}

Note the added [STAThread] attribute. It is technically not correct to do this, a console mode app does not provide the correct kind of runtime environment for single-threaded COM objects but if the VB.NET app works then you have little to fear. If you ever notice deadlock then you'll know what to look for. It worked when you used late-binding through InvokeMember because that uses IDispatch and it has a different proxy.

于 2015-04-25T07:46:31.170 に答える
-1

Sami Kuhmonenに感謝します。解決策は次のとおりです。

object c = t.InvokeMember("Case", BindingFlags.GetProperty, null, app, null);
t.InvokeMember("OpenCase", BindingFlags.InvokeMethod, null, c, new object[] { "17-16", 0 });

そのため、「Case」がプロパティであることを認識していませんでした。

解決済み

于 2015-04-25T06:33:03.260 に答える