Läuft eine Anwendung in der Visual Basic Entwicklungsumgebung?
Veröffentlicht: 03. Apr 2002 | Aktualisiert: 21. Jun 2004
Von Mathias Schiffer
Mit Hilfe weniger Zeilen Code stellt Ihre Anwendung fest, ob sie innerhalb der Entwicklungsumgebung oder in compilierter Form läuft. Dafür nutzen Sie Umstand, dass eine Debug.Print-Anweisung in einem Compilat nicht ausgeführt wird.
In einem Debug.Print-Statement aufgeführte Funktionsaufrufe, deren Ergebnisse in das Direktfenster ausgegeben werden sollen, werden jedoch auch in compiliertem Zustand ausgeführt!
Private Function RunningInIDE() As Boolean On Error Resume Next Debug.Print 1 / 0 RunningInIDE = (Err.Number <> 11) End Function
Da die fehlerhafte Division nur in der Entwicklungsumgebung zu einem Laufzeitfehler führt, lässt sich der dort auftretende Fehler Nr. 11 (Division durch Null) zur Unterscheidung zwischen Entwicklungsumgebung und Compilat nutzen.
Weniger hilfreich ist dieses Vorgehen allerdings für einen komponentenbasierten Ansatz, etwa in einer ActiveX-DLL: Ist die Komponente selbst compiliert, wirkt der obige Trick nicht mehr. Die DLL selbst wird in einem solchen Szenario als Compilat verwendet, folgerichtig würde sie jederzeit zutreffend berichten, dass sie compiliert eingesetzt wird.Die folgende Routine nutzt daher ein anderes Vorgehen:
Die Funktion FindWindowExsucht auf Basis des Klassennamens "wndclass_desked_gsk" alle Hauptfenster der Visual-Basic-Entwicklungsumgebung. wndclass_desked_gsk ist der Klassenname des Hauptfensters der Visual Basic Entwicklungsumgebung. Andere Entwicklungsumgebungen berücksichtigt die vorliegende Form nicht. Einer entsprechenden Erweiterung oder Änderung steht jedoch nichts im Wege. Bei erfolgreicher Suche vergleicht die Routine die mittels GetWindowThreadProcessId ermittelte Prozess-ID jedes gefundenen Visual-Basic-Hauptfensters sodann mit der Prozess-ID, die durch GetCurrentProcessId für den Prozess der DLL ermittelt wurde:
' --- API-Deklarationen Private Declare Function FindWindowEx _ Lib "user32" Alias "FindWindowExA" ( _ Optional ByVal hWndParent As Long = 0, _ Optional ByVal hWndChildAfter As Long = 0, _ Optional ByVal ClassName As String = vbNullString, _ Optional ByVal WindowTitle As String = vbNullString _ ) As Long Private Declare Function GetCurrentProcessId _ Lib "kernel32" ( _ ) As Long Private Declare Function GetWindowThreadProcessId _ Lib "user32" ( _ ByVal hwnd As Long, _ ByRef lpdwProcessId As Long _ ) As Long ' --- Funktion für ActiveX-DLLs Private Function UserInIDE() As Boolean Dim hWnd As Long Dim MyPID As Long Dim WindowPID As Long ' Die Prozess-ID des aktuellen Prozesses ermitteln MyPID = GetCurrentProcessId() ' Hauptfenster der Visual Basic Entwicklungsumgebung suchen Do hWnd = FindWindowEx(0, hWnd, "wndclass_desked_gsk", vbNullString) If hWnd <> 0 Then ' Vergleich der Prozess-IDs GetWindowThreadProcessId hWnd, WindowPID If WindowPID = MyPID Then UserInIDE = True Exit Function End If End If Loop Until hWnd = 0 End Function