.NETで記述された複数のコンポーネントを使用するVisual Basic 6.0アプリケーションがあります。Windows がシャットダウンされると、アプリケーションは正常にシャットダウンする必要があります。問題は、コードの .NET 部分がウィンドウを表示している場合、アプリケーションが「終了できません」というメッセージを表示し、終了に失敗することです。(その後、OSによって終了されます。)
簡略化されたアプリケーションでこれを再現することができました。
.NET コードは、WPFウィンドウを作成し、ShowDialog() を使用して表示します。
[Guid("5F3D0B23-2196-4082-B9DE-B208C61FE89F")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IComShutdownTest
{
[DispId(1)]
void RunTest();
}
[Guid("E6613EDD-D51B-42c0-AA5B-5961AB28D063")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ShutdownTest")]
public class ShutdownTest : IComShutdownTest
{
public ShutdownTest()
{ }
public void RunTest()
{
TestWindow testWindow = new TestWindow();
bool? dialogResult = testWindow.ShowDialog();
}
}
ご覧のとおり、.NET 呼び出しがブロックされ (そして GUI スレッド上にあります)、これが問題の原因であると思われますが、すべての呼び出しを非ブロックにすることはできません。OS がシャットダウンすると、開いているすべてのアプリケーション ウィンドウが終了すると想定していました。
Visual Basic 6.0 アプリケーションは、ボタンをクリックするだけで .NET フォームをロードして表示します。
Private Sub ButtonTest_Click()
LogEventToFile "Starting"
Dim dotNetTestObject As ShutdownTest
LogEventToFile "Creating"
Set dotNetTestObject = New ShutdownTest
LogEventToFile "Running"
dotNetTestObject.RunTest
LogEventToFile "Done"
End Sub
.NET フォームが画面に表示されている間に PC をシャットダウンしようとすると、失敗します。「終了できません」というメッセージ ボックスは次のようになります。
これを再作成するには、アセンブリをCOM可視としてマークする必要があります (ファイル内assemblyinfo.cs
):
[assembly: ComVisible(true)]
Project->Properties>Build タブを「Register for COM interop」に設定する必要があります。
また、コンパイルされたアセンブリを次のように登録しました。
regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb
この問題を解決するにはどうすればよいですか?