Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0671: Auf vollständiges Starten einer anderen Anwendung warten

 von 

Beschreibung 

Mit Hilfe der WaitForInputIdle API-Funktion der Win32-Api kann man feststellen, ob ein Prozess bereit ist Benutzereingaben zu verarbeiten. Dadurch ist es möglich, nach dem Starten eines anderen Prozesses solange mit der Verarbeitung des eigenen Programms zu warten, bis die gewünschte Anwendung vollständig geladen ist.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

CreateProcessA (CreateProcess), WaitForInputIdle

Download:

Download des Beispielprojektes [4,61 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------- Anfang Projektdatei WaitForStartAppDemo.vbp  -------
'------- Anfang Formular "frmMain" alias frmMain.frm  -------
' Steuerelement: Rahmensteuerelement "Frame1"
' Steuerelement: Kontrollkästchen-Steuerelement "chkDoEv" auf Frame1
' Steuerelement: Textfeld "txtTimeOut" auf Frame1
' Steuerelement: Kombinationsliste "cboWinStyle" auf Frame1
' Steuerelement: Textfeld "txtPath" auf Frame1
' Steuerelement: Beschriftungsfeld "Label5" auf Frame1
' Steuerelement: Beschriftungsfeld "Label4" auf Frame1
' Steuerelement: Beschriftungsfeld "Label1" auf Frame1
' Steuerelement: Schaltfläche "cmdCallWaitForStartApp"
' Steuerelement: Beschriftungsfeld "lblResult"
' Steuerelement: Beschriftungsfeld "Label2"
Option Explicit



' Der Ursprungscode wurde von Georg Mühlberger geschrieben
'   (angelehnt an die MSDN Library).

Private Sub cmdCallWaitForStartApp_Click()
    Dim lngResult As wsaErrors
    Dim strRes As String
    
    cmdCallWaitForStartApp.Enabled = False
    lblResult.Caption = "Anwendung wird gestartet..."
    
    lngResult = WaitForStartApp(txtPath.Text, _
                             cboWinStyle.ListIndex + 1, _
                             txtTimeOut.Text, _
                             chkDoEv.Value)
    Select Case lngResult
    Case wsaNoError
        strRes = "Die Anwendung wurde gestartet."
    Case wsaStartError
        strRes = "Anwendung konnte nicht gestartet werden."
    Case wsaTimeOut
        strRes = "TimeOut erreicht."
    Case wsaOtherError
        strRes = "Sonstiger Fehler."
    End Select
    
    lblResult.Caption = strRes
    cmdCallWaitForStartApp.Enabled = True
    Beep
End Sub

Private Sub Form_Load()
    With cboWinStyle
        .AddItem "vbNormalFocus"
        .AddItem "vbMinimizedFocus"
        .AddItem "vbMaximizedFocus"
        .AddItem "vbNormalNoFocus"
        
        .ListIndex = 0
    End With
    
End Sub

'-------- Ende Formular "frmMain" alias frmMain.frm  --------
'--- Anfang Modul "modWaitForStartApp" alias modWaitForStartApp.bas ---
Option Explicit



' Der Ursprungscode wurde von Georg Mühlberger geschrieben
'   (angelehnt an die MSDN Library).

Private Declare Function CreateProcess Lib "kernel32" Alias _
    "CreateProcessA" (ByVal lpApplicationName As String, _
    ByVal lpCommandLine As String, lpProcessAttributes As Any, _
    lpThreadAttributes As Any, ByVal bInheritHandles As Long, _
    ByVal dwCreationFlags As Long, lpEnvironment As Any, _
    ByVal lpCurrentDriectory As String, lpStartUpInfo As STARTUPINFO, _
    lpProcessInformation As PROCESS_INFORMATION) As Long

Private Declare Function WaitForInputIdle Lib "user32" ( _
    ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long

Private Type PROCESS_INFORMATION
   hProcess As Long
   hThread As Long
   dwProcessId As Long
   dwThreadId As Long
End Type

Private Type STARTUPINFO
   cb As Long
   lpReserved As String
   lpDesktop As String
   lpTitle As String
   dwX As Long
   dwY As Long
   dwXSize As Long
   dwYSize As Long
   dwXCountChars As Long
   dwYCountChars As Long
   dwFillAttribute As Long
   dwFlags As Long
   wShowWindow As Integer
   cbReserved2 As Integer
   lpReserved2 As Long
   hStdInput As Long
   hStdOutput As Long
   hStdError As Long
End Type

Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const STARTF_USESHOWWINDOW As Long = &H1&
Private Const INFINITE As Long = -1&
Private Const WAIT_OBJECT_0 As Long = 0
Private Const WAIT_TIMEOUT As Long = &H102&
Private Const WAIT_FAILED As Long = -1&

Public Enum wsaErrors
    wsaNoError = 0
    wsaStartError = 1
    wsaTimeOut = 2
    wsaOtherError = 3
End Enum

' Funktion WaitForStartApp
' ========================
'   Startet eine Anwendung und wartet, bis diese auf Benutzereingaben
'   reagiert, also vollständig gestartet wurde.
'
'   Parameter:
'       o Path               Programmpfad inkl. Kommandozeilenparameter
'                              der zu startenden Anwendung.
'       o WinStyle           Gibt an, wie die Anwendung gestartet
'                              werden soll.
'       o TimeOut            Zeit die maximal gewartet werden soll
'                              bis die Funktion zurückkehrt
'       o DoEv               Gibt an ob während dem Anwendungsstart
'                              Ereignisse verarbeitet werden können
'                              (DoEvents)
'
'   Mögliche Rückgabewerte:
'       o wsaNoError    Anwendung wurde erfolgreich gestartet.
'       o wsaStartError Anwendung konnte nicht gestartet werden.
'       o wsaTimeOut    TimeOut-Zeit erreicht.
'       o wsaOtherError Sonstiger Fehler.

Public Function WaitForStartApp(Path As String, _
        Optional WinStyle As VbAppWinStyle, _
        Optional TimeOut As Long = 10000, _
        Optional DoEv As Boolean = True) As wsaErrors
        
    Dim lngRet As Long
    Dim udtSInfo As STARTUPINFO
    Dim lngWaitTime As Long
    Dim udtPInfo As PROCESS_INFORMATION
    
    ' Prozessstruktur initialisieren
    With udtSInfo
        .cb = LenB(udtSInfo)
        .dwFlags = STARTF_USESHOWWINDOW
        .wShowWindow = WinStyle
    End With

    ' Anwendung starten
    lngRet = CreateProcess(vbNullString, Path, ByVal 0&, _
        ByVal 0&, 1&, NORMAL_PRIORITY_CLASS, ByVal 0&, _
        vbNullString, udtSInfo, udtPInfo)
        
    If lngRet = 0 Then
        ' Fehler beim Starten der Anwendung aufgetreten
        WaitForStartApp = wsaStartError
        Exit Function
    End If
    
    ' Warten, bis Anwendung reagiert oder TimeOut erreicht ist
    Do
        ' Anwendung auf Reaktion prüfen
        lngRet = WaitForInputIdle(udtPInfo.hProcess, 50)
        
        If lngRet = WAIT_TIMEOUT Then
            'Anwendung reagiert noch nicht
            If DoEv Then DoEvents           ' Falls erwünscht, DoEvents
            lngWaitTime = lngWaitTime + 50  ' Verstrichene Zeit erhöhen
        End If
            
        
    Loop Until lngRet <> WAIT_TIMEOUT Or lngWaitTime > TimeOut
    
    ' Evtl. Fehler auswerten
    Select Case lngRet
    Case WAIT_OBJECT_0
        WaitForStartApp = wsaNoError     ' Kein Fehler
    Case WAIT_TIMEOUT
        WaitForStartApp = wsaTimeOut     ' TimeOut erreicht
    Case WAIT_FAILED
        WaitForStartApp = wsaOtherError  ' Sonstiger Fehler
    End Select
End Function

'--- Ende Modul "modWaitForStartApp" alias modWaitForStartApp.bas ---
'-------- Ende Projektdatei WaitForStartAppDemo.vbp  --------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 2 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Georg Baukelmann am 11.11.2009 um 22:56

With Info
.cb = LenB(SInfo)
.dwFlags = STARTF_USESHOWWINDOW
.wShowWindow = WinStyle
End With
Ich erhalte immer die Meldung für "STARTF_USESHOWWINDOW", dass die Variable nicht definiert ist.
Ich möchte einfach nur, dass das "Batch-Window" hidden ist und habe anstatt "WinStyle" eine "0" eingegeben, aber das hat mit obiger Meldung wohl nichts zu tun.

Gruß
Georg

Kommentar von markus am 26.11.2006 um 14:13

Leider funzt das Ding nicht beim Media Player, wenn dieser im Bibliotheks-Mode gestartet wird.