vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Brandneu! sevEingabe v3.0 - Das Eingabecontrol der Superlative!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2020
 
zurück
Rubrik:    |   VB-Versionen: VB604.01.13
Die eigene Anwendung "sauber" beenden

Vermeidung von Microsoft Problemreports beim Beenden der eigenen VB6 Anwendung

Autor:   Ralf SchlegelBewertung:     [ Jetzt bewerten ]Views:  1.671 
http://www.vb-zentrum.de/System:  WinXP, Vista, Win7, Win8, Win10kein Beispielprojekt 

Kennen Sie das: Sie haben eine aufwendige Applikation geschrieben, in der IDE getestet und alles scheint zu funktionieren. Nach dem Kompilieren läuft die Anwendung auch als EXE, bis sie beendet wird und nun das:
Nach kurzer Zeit meldet sich der Windows Problemreport und meckert Ihre Anwendung an!

Sie öffnen den Taskmanager, wechsel auf die Registerkarte "Prozesse" und starten Ihre Anwendung erneut. Ihre Anwendung wird im Taskmanager sichtbar. Nun beenden Sie Ihre Anwendung und...
...sie bleibt im Taskmanger sichtbar! Nach einiger Zeit erscheint dann wieder der Problemreport. In der IDE tritt der Fehler aber nicht auf - was läuft hier falsch?

Möglichkeit A:
Der Grund liegt mit höchster Wahrscheinlichkeit am "unsauberen" Einsatz von API Funktionen!
Nutzen Sie z.B. die API-Funktion "hMod = LoadLibrary(DllName)" und geben das erhaltene Handle nicht mit "FreeLibrary(hMod)" wieder frei, so haben Sie eine Ursache gefunden!
Gleiches kann auch bei Öffnen von Dateien über das API passieren - um nur 2 Möglichkeiten zu nennen...
Was die IDE hier noch locker wegsteckt, führt in der EXE zu o.g. Fehlverhalten.
Wenn Sie den Fehler nicht ermitteln können (er kann auch in einem eingebundenen Control liegen, das Sie von Dritten erhalten haben), so gibt es dennoch eine Möglichkeit das Programm sauber zu beenden - und zwar wiederum mit Hilfe des API und der Funktion ExitProcess. Diese Funktion macht in der EXE das, was die IDE beim Beenden des Testprogramms macht: sie schließt alle zum Prozess gehörigen Dateien. Zusätzlich trennt sie alle offenen DLL-Verbindungen und Threads und sorgt so für ein sauberes Ende ohne Datenverlust.

Deklarieren Sie die folgenden 3 API Funktionen und erweitern Sie die Enderoutine Ihrer Applikation:

Public Declare Sub ExitProcess Lib "kernel32" ( _
  ByVal uExitCode As Long)
 
Public Declare Function GetExitCodeProcess Lib "kernel32" ( _
  ByVal hProcess As Long, _
  lpExitCode As Long) As Long
 
Public Declare Function GetCurrentProcess Lib "kernel32" () As Long
If App.LogMode Then     ' do this only in compiled code
  ExitProcess GetExitCodeProcess(GetCurrentProcess, 0)
End If

Nach dieser Anweisung darf kein Programmcode mehr folgen. Die Abfrage auf App.LogMode ergibt in der IDE immer '0' und sorgt so dafür, dass der nachfolgende Code nur in der compilierten Fassung abgearbeitet wird, anderenfalls wird die IDE auch beendet, da sie zu diesem Zeitpunkt noch der "CurrentProcess" ist.

Möglichkeit B:
Sie machen keine Fehler bei der Programmierung? Nun - dann sind Sie das Opfer der Microsoft ComCtl32.DLL!
Die ist nämlich in der Version 6 nicht mit VB6 kompatibel wenn ihr Projekt folgende Funktionen beinhaltet:

  1. Sie setzen User Controls ein
  2. Sie verwenden Visual Styles mit Hilfe des API "InitCommonControls"

Microsoft hält hierfür folgende Lösung bereit:
"Visual Basic 6.0 unterstützt kein Theming und keine Visual Styles..."
siehe: http://support.microsoft.com/default.aspx?scid=kb;en-us;309366

Das ist uns dann doch etwas zu einfach! Auch hier können Sie ihren Quellcode um Möglichkeit A erweitern, denn das Problem liegt an nicht getrennten Verbindungen zur shell32.dll, oder Sie laden die shell32.dll vor der Initialisierung der Controls und halten das Handle bis zum Beenden Ihrer Anwendung offen, zum Beispiel so:

Public Declare Sub InitCommonControls Lib "comctl32.dll" ()
 
Public Declare Function LoadLibraryA Lib "kernel32" ( _
  ByVal lpFileName As String) As Long
 
Public Declare Function FreeLibrary Lib "kernel32" ( _
  ByVal hModule As Long) As Long
 
Public hShell As Long
' in der Hauptform (oder alternativ in der Sub Main Routine):
Private Sub Form_Initialize()
  hShell = LoadLibraryA("shell32.dll")
  InitCommonControls
End Sub
Private Sub Form_Unload(Cancel As Integer)
  ' Ihr Code:
  ' .
  ' .
  FreeLibrary hShell
End Sub

Dieser Tipp wurde bereits 1.671 mal aufgerufen.

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2020 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel