2009-09-17 14 views
9

Sto avviando una applicazione per ufficio (VBA) che effettua una chiamata a un'applicazione di console C# per eseguire alcuni lavori pesanti per l'applicazione (programma di simulazione di grandi dimensioni). Vorrei essere in grado di avere l'applicazione VBA in attesa che l'applicazione della console si completi e recuperare il codice di uscita dall'applicazione della console. Sono stato in grado di fare il primo, ma devo ancora essere in grado di recuperare il codice di uscita dall'applicazione. C'è un modo per utilizzare qualcosa comeVBA Shell e Wait con codice di uscita

Diagnostics.Process.Start(filePath) 

Ho visto questo in VB ma non sono sicuro di VBA. Altrimenti, altri suggerimenti?

risposta

12

Dai un'occhiata alle funzioni WaitForSingleObject e GetExitCodeProcess.

Esempio Uso:

Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long 
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long 
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long 
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long 
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long 

Public Const INFINITE = &HFFFF 
Public Const PROCESS_ALL_ACCESS = &H1F0FFF 

Sub RunApplication(ByVal Cmd as String) 

    lTaskID = Shell(Cmd, vbNormalFocus) 
    //Get process handle 
    lPID = OpenProcess(PROCESS_ALL_ACCESS, True, lTaskID) 
    If lPID Then 
     //Wait for process to finish 
     Call WaitForSingleObject(lPID, INFINITE) 
     //Get Exit Process 
     If GetExitCodeProcess(lPID, lExitCode) Then 
      //Received value 
      MsgBox "Successfully returned " & lExitCode, vbInformation 
     Else 
      MsgBox "Failed: " & DLLErrorText(Err.LastDllError), vbCritical 
     End If 
    Else 
     MsgBox "Failed: " & DLLErrorText(Err.LastDllError), vbCritical 
    End If 
    lTaskID = CloseHandle(lPID) 
End Sub 

Public Function DLLErrorText(ByVal lLastDLLError As Long) As String 
    Dim sBuff As String * 256 
    Dim lCount As Long 
    Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100, FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000 
    Const FORMAT_MESSAGE_FROM_HMODULE = &H800, FORMAT_MESSAGE_FROM_STRING = &H400 
    Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000, FORMAT_MESSAGE_IGNORE_INSERTS = &H200 
    Const FORMAT_MESSAGE_MAX_WIDTH_MASK = &HFF 

    lCount = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, 0, lLastDLLError, 0&, sBuff, Len(sBuff), ByVal 0) 
    If lCount Then 
     DLLErrorText = Left$(sBuff, lCount - 2) \\Remove line feeds 
    End If 

End Function 
+1

Non sono sicuro di seguirmi. Sto cercando la funzione VBA per recuperare il codice di uscita dall'applicazione console C#, questo sembra essere il contrario. –

+1

quelle sono chiamate API Windows, è possibile utilizzarle in un'applicazione VBA. – James

+1

Mi dispiace, lo esaminerò ulteriormente. Grazie –

3

Questa funzionalità è stata avvolta nella funzione ShellAndWait.

Eccellente scrivere su di esso here.

+2

Grazie per l'articolo. L'avevo rivisto in passato; non restituisce il codice di uscita dall'applicazione chiamata. Restituisce solo un codice basato su se l'applicazione con shell termina correttamente, non tiene conto del codice di uscita inviato dall'applicazione. Ad esempio, se l'applicazione della console non riesce a trovare un file, termina con un codice di uscita di 1, tuttavia la shell e il codice di attesa verranno restituiti correttamente perché l'applicazione è stata terminata correttamente. –

+0

Ah, mio ​​male, non l'ho recensito abbastanza vicino. Nessun problema, penso che James lo abbia sopra. – Mark

Problemi correlati