2009-09-17 24 views
9

Estoy terminando una aplicación de oficina (VBA) que realiza una llamada a una aplicación de consola C# para realizar algunas de las tareas más pesadas de la aplicación (gran programa de simulación). Me gustaría poder hacer que la aplicación VBA espere a que se complete la aplicación de la consola, así como recuperar el código de salida de la aplicación de la consola. He podido hacer lo anterior, pero aún no he podido recuperar el código de salida de la aplicación. ¿Hay alguna manera de que puedo usar algo comoShell VBA y código de espera con salida

Diagnostics.Process.Start(filePath) 

He visto esto en VB, pero no está seguro acerca de VBA. De lo contrario, ¿alguna otra sugerencia?

Respuesta

12

Eche un vistazo a las funciones WaitForSingleObject y GetExitCodeProcess.

Ejemplo de 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

No estoy seguro de seguir. Estoy buscando la función VBA para recuperar el código de salida de la aplicación de la consola C#, parece que es al revés. –

+1

esas son llamadas API de Windows, puede usarlas en una aplicación VBA. – James

+1

Lo siento, lo investigaré más a fondo. Gracias –

3

Esta funcionalidad se ha envuelto en la función ShellAndWait.

Excelente escribe en él here.

+2

Gracias por el artículo. Yo había revisado esto en el pasado; no devuelve el código de salida de la aplicación llamada. Solo devuelve un código basado en si la aplicación sin shell finaliza correctamente, no representa el código de salida enviado por la aplicación. Por ejemplo, si la aplicación de la consola no puede encontrar un archivo, termina con un código de salida de 1, sin embargo, el shell y el código de espera serán exitosos porque la aplicación finalizó correctamente. –

+0

Ahh, mi mal, no lo revisé lo suficientemente cerca. Sin embargo, no me preocupa, creo que James lo tiene arriba. – Mark

Cuestiones relacionadas