代码之家  ›  专栏  ›  技术社区  ›  Simon P Stevens

Visual Basic 6.0应用程序在启动时不会关闭。网络表单打开。相反,它会显示消息“无法退出”

  •  4
  • Simon P Stevens  · 技术社区  · 15 年前

    我有一个 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窗体出现在屏幕上,它会失败。“无法退出”消息框显示 like this .

    要重新创建,必须将程序集标记为 COM 可见(在文件中) assemblyinfo.cs ):

    [assembly: ComVisible(true)]
    

    您必须设置项目->房地产>“注册COM互操作”的“生成”选项卡

    我还将编译后的程序集注册到:

    regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb
    

    我如何解决这个问题?

    3 回复  |  直到 11 年前
        1
  •  1
  •   Peter Mortensen stimpy    11 年前

    如果在任何窗口上调用ShowDialog(),它会阻塞该线程,直到窗口关闭(从用户或代码)。

    您可能需要在COM接口上创建一个方法来关闭窗口 .NET ,或者以某种方式在Visual Basic中获取窗口句柄以关闭窗口。

        2
  •  0
  •   Peter Mortensen stimpy    11 年前

    以下其中一项可以解决您的问题:

    • 确保你的 .NET 窗口设置了文本/名称属性。我知道这有时会引发类似的问题。
    • 设置文件的所有者。NET窗口到您的Visual Basic窗口。在中使用SetParent函数 user32.dll .
    • 与微软联手。Win32。系统事件。在你的教室里上课。NET库并关闭窗口。
        3
  •  0
  •   Peter Mortensen stimpy    11 年前

    您可以尝试将父窗口作为 .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)