当 .NET 窗体打开时,Visual Basic 6.0 应用程序不会关闭。相反,它会显示消息“无法退出”。
我有一个 Visual Basic 6.0 应用程序,它使用用 .NET。当 Windows 关闭时,应用程序必须正常关闭。问题是,如果代码的 .NET 部分显示窗口,则应用程序会显示消息 “无法退出”并且无法退出。 (然后它被操作系统终止。)
我已经成功地在一个简化的应用程序中重现了这一点。
.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,则会失败。 “无法退出”消息框看起来像这样。
要重新创建它,您必须将程序集标记为 COM 可见(在文件 assemblyinfo.cs 中)
):
[assembly: ComVisible(true)]
并且您必须将“项目”->“属性”>“构建”选项卡设置为“注册 COM 互操作”
我还注册了已编译的程序集:
regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb
如何解决此问题?
I have a Visual Basic 6.0 application that uses several components written in .NET. The application must shutdown gracefully when windows is shut down. The problem is that if the .NET part of the code is displaying a window, the application displays the message "Cannot Quit" and fails to exit. (It is then terminated by the OS.)
I've managed to reproduce this in a simplified application.
The .NET code creates a WPF window and displays it using 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();
}
}
As you can see the .NET call blocks (and is on the GUI thread), and I suspect this may be the root of the problem, but I can't go round making all my calls non-blocking. I would have assumed that when the OS shuts down, that all of the open application windows are terminated.
The Visual Basic 6.0 application loads and displays the .NET form from a button click.
Private Sub ButtonTest_Click()
LogEventToFile "Starting"
Dim dotNetTestObject As ShutdownTest
LogEventToFile "Creating"
Set dotNetTestObject = New ShutdownTest
LogEventToFile "Running"
dotNetTestObject.RunTest
LogEventToFile "Done"
End Sub
If you attempt to shutdown the PC while the .NET form is on the screen, it fails. The "Cannot quit" message box looks like this.
To recreate this you must mark the assembly as COM visible (in file assemblyinfo.cs
):
[assembly: ComVisible(true)]
and you must set the Project->Properties>Build tab to "Register for COM interop"
I also registered the compiled assembly with:
regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb
How can I fix this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您在任何窗口上调用 ShowDialog(),它将在该线程上阻塞,直到窗口关闭(从用户或代码)。
您可能需要在 COM 接口上创建一个方法来关闭 .NET 中的窗口,或者以某种方式在 Visual Basic 中获取窗口句柄来关闭窗口。
If you call ShowDialog() on any window, it blocks on that thread until the window closes (from the user or from code).
You will probably have to make a method on your COM interface to close the window in .NET, or somehow get the window's handle in Visual Basic to close the window.
以下方法之一应该可以解决您的问题:
user32.dll
中的SetParent函数。One of the following should solve your issue:
user32.dll
.您可以尝试将父窗口作为 .NET 方法的参数,这样当父组件尝试关闭时,.NET 组件会收到通知。
在您的 Visual Basic 6.0 代码中:
You could try to take the parent window as parameter to the .NET method, that way the .NET component gets notified when the parent tries to close.
And in your Visual Basic 6.0 code: