C# で COM コンポーネントを使用するときに問題が発生します。
私は古い (~2001 年から 2003 年に開発された) VB6 COM コンポーネントを持っていますが、残念ながらそのソース コードはありません。サービス プログラムと対話するコンポーネント (ソースもありません)。メインのアプリケーションは VB6 で書かれており、現在は .Net で書き直しています。
(TblImp を使用して) コンポーネントを C# にインポートし、それを呼び出しました。
using System;
using System.Threading;
using System.Collections.Generic;
using System.Text;
using System.Runtime.CompilerServices;
using SrvCommDCG;
class Program
{
[STAThread]
static void Main(string[] args)
{
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
{
System.Console.WriteLine("calling com");
clsCommDCGService srv = new clsCommDCGService();
srv.Check();
System.Console.ReadKey();
}
}
}
Windows 7 で実行すると、何も起こりません (チェックが完了すると、コンポーネントはメッセージ ボックスを表示するはずです)。
Windows 8 で実行すると、例外なくプログラムがクラッシュします。
さまざまなスレッド モデルを試しました: MTA、STA ([STAThread]
または のいずれかを使用SetApartmentState()
)、呼び出しDisableComObjectEagerCleanup()
- 何も役に立ちませんでした。
1 週間結果が得られなかった後、Python でコンポーネントを使用しようとしましたが、次のようになりました。
import win32com.client
tst = win32com.client.Dispatch("SrvCommDCG.clsCommDCGService")
tst.Check()
すべてが機能しており、チェックはOKで、MessageBoxが表示されました。
もちろん、VB 6.0からも動作します。
問題は、python がシングルスレッドの win32 アプリであり、C# がマルチスレッドのマネージ コードであることだと思います。そして、それを機能させるために、C#コードに何を追加する必要があるかを理解するためのポイントがありませんか? 残念ながら、.Net から呼び出す必要があります。
編集#1:.Net 4.0と4.5、および.Net 2.0フレームワークでも試しました
編集#2:Windows 8でプログラムがクラッシュした場合、有用なメッセージはありません(VS C#デバッガーからプログラムを実行した場合でも)、「プログラムで問題が発生したため、閉じられます」と書くだけです(ロシアのWin8を持っていて、できませんWindows で正確なメッセージを伝えます)。Win8 のイベント ログには、アドレス 012E72CC で未処理の例外 c0000005 が原因でプロセスが強制終了されました。単純なアクセス違反です。
edit#3: C# プログラムは Win7/8 ではうまく動作しませんが、Windows XP では正常に動作します。ミステリオもの。