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