我有一个Visual Basic 6.0应用程序,它使用.NET中编写的几个组件。当Windows关闭时,应用程序必须正常关闭。问题是,如果代码的.NET部分显示窗口,则应用程序显示消息"Cannot Quit"并且无法退出。 (然后由操作系统终止。)
我已经设法在简化的应用程序中重现了这一点。
.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线程上),我怀疑这可能是问题的根源,但我无法绕过使所有调用无阻塞。我会假设当操作系统关闭时,所有打开的应用程序窗口都会终止。
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,则会失败。 “无法退出”消息框显示like this。
要重新创建此项,您必须将程序集标记为COM可见(在文件assemblyinfo.cs
中):
[assembly: ComVisible(true)]
您必须将Project-> Properties> Build标签设置为“Register for COM interop”
我还注册了编译的程序集:
regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb
如何解决此问题?
答案 0 :(得分:1)
如果在任何窗口上调用ShowDialog(),它会在该窗口上阻塞,直到窗口关闭(来自用户或代码)。
您可能必须在COM接口上创建一个方法来关闭.NET中的窗口,或以某种方式在Visual Basic中获取窗口的句柄以关闭窗口。
答案 1 :(得分:0)
以下其中一项应解决您的问题:
user32.dll
中的SetParent函数。答案 2 :(得分:0)
您可以尝试将父窗口作为.NET方法的参数,这样当父级尝试关闭时,.NET组件会收到通知。
public void RunTest(IWin32Window owner)
{
TestWindow testWindow = new TestWindow();
bool? dialogResult = testWindow.ShowDialog(owner);
}
在Visual Basic 6.0代码中:
Call dotNetTestObject.RunTest(Me.hWnd)