J'ai une application Visual Basic 6.0 qui utilise plusieurs composants écrits en .NET. L'application doit s'éteindre gracieusement lorsque Windows est arrêté. Le problème est que si la partie .NET du code affiche une fenêtre, l'application affiche le message "Cannot Quit" et ne parvient pas à quitter. (Il est ensuite terminé par le système d'exploitation.)L'application Visual Basic 6.0 ne s'arrête pas lorsque le formulaire .NET est ouvert. Au lieu de cela, il affiche le message "Can not Quit"
J'ai réussi à reproduire cela dans une application simplifiée.
Le code .NET crée une fenêtre WPF et affiche à l'aide 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();
}
}
Comme vous pouvez voir les blocs d'appel .NET (et est sur le fil GUI), et je soupçonne que cela peut être la racine du problème, mais je ne peux pas faire le tour de tous mes appels non bloquants. J'aurais supposé que lorsque le système d'exploitation se ferme, toutes les fenêtres d'application ouvertes sont terminées.
L'application Visual Basic 6.0 charge et affiche le formulaire .NET à partir d'un clic de bouton. Si vous tentez d'arrêter le PC alors que le formulaire .NET est à l'écran, il échoue. La boîte de message "Impossible de quitter" s'affiche like this.
Pour recréer cela, vous devez marquer l'assemblage comme COM visible (dans le fichier assemblyinfo.cs
):
[assembly: ComVisible(true)]
et vous devez définir les propriétés Projet->> Créer onglet "enregistrer pour COM Interop"
Jeégalement enregistré l'assembly compilé avec:
regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb
Comment puis-je résoudre ce problème?
Mais le système d'exploitation ne doit pas fermer toutes les fenêtres ouvertes. (J'ai pensé qu'il a envoyé les messages QuerySessionEnd et SessionEnd à toutes les fenêtres ouvertes qui les feraient se fermer). Si vous créez une application .net pure avec 2 fenêtres et utilisez ShowDialog(), elle se fermera automatiquement quand le système d'exploitation s'arrêtera. –
Le système d'exploitation envoie cette commande à toutes les fenêtres de niveau supérieur, qui à leur tour ferment leurs enfants. Puisque votre fenêtre de niveau supérieur est VB, elle ne sait probablement pas comment fermer votre fenêtre .Net. Il sait juste que le fil principal est bloqué. – jonathanpeppers