Приложение Visual Basic 6.0 не закрывается при открытии формы .NET. Вместо этого отображается сообщение «Cannot Quit» - PullRequest
4 голосов
/ 10 августа 2009

У меня есть Visual Basic 6.0 приложение, которое использует несколько компонентов, написанных на .NET . Приложение должно корректно завершать работу при закрытии окон. Проблема заключается в том, что если в .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 (и в потоке графического интерфейса), и я подозреваю, что это может быть причиной проблемы, но я не могу сделать все мои вызовы неблокирующими. Я бы предположил, что, когда ОС закрывается, все открытые окна приложений закрываются.

Приложение 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, произойдет сбой. Окно сообщения «Не удается выйти» выглядит следующим образом .

Чтобы воссоздать это, необходимо пометить сборку как COM видимый (в файле assemblyinfo.cs):

[assembly: ComVisible(true)]

и вы должны установить вкладку "Проект-> Свойства> Сборка" на "Регистрация для взаимодействия COM"

Я также зарегистрировал скомпилированную сборку с:

regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb

Как я могу решить эту проблему?

Ответы [ 3 ]

1 голос
/ 10 августа 2009

Если вы вызываете ShowDialog () для любого окна, оно блокируется в этом потоке до тех пор, пока окно не закроется (от пользователя или из кода).

Возможно, вам придется создать метод на вашем COM-интерфейсе, чтобы закрыть окно в .NET , или каким-либо образом получить дескриптор окна в Visual Basic, чтобы закрыть окно.

0 голосов
/ 11 сентября 2009

Можно попытаться использовать родительское окно в качестве параметра для метода .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)
0 голосов
/ 11 августа 2009

Одна из следующих проблем должна решить вашу проблему:

  • Убедитесь, что в вашем .NET окне установлены свойства «Текст / имя». Я знаю, что это иногда вызывает такие проблемы.
  • Установите владельца окна .NET для вашего окна Visual Basic. Используйте функцию SetParent в user32.dll.
  • Подключитесь к Microsoft.Win32.SystemEvents.SessionEnding в библиотеке .NET и закройте окно.
...