2009-09-17 2 views
9

C# 콘솔 응용 프로그램을 호출하여 응용 프로그램에 대한 과중한 수행 (대규모 시뮬레이션 프로그램)을 수행하는 Office 응용 프로그램 (VBA)을 래핑합니다. VBA 응용 프로그램에서 콘솔 응용 프로그램이 종료 될 때까지 기다릴 수 있고 콘솔 응용 프로그램에서 종료 코드를 검색 할 수 있기를 원합니다. 나는 이전을 할 수 있었지만 아직 응용 프로그램에서 종료 코드를 검색 할 수 있어야합니다. 내가 VB에서 본 적 있지만 VBA 확실하지 않은VBA 셸 및 종료 코드로 대기

Diagnostics.Process.Start(filePath) 

같은 것을 사용할 수있는 방법이 있습니까. 그렇지 않으면 다른 제안 사항이 있습니까?

답변

12

WaitForSingleObjectGetExitCodeProcess 기능을 살펴보십시오.

사용 예는 :

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

나는 내가 따라야할지 확신하지 못한다. C# 콘솔 응용 프로그램에서 종료 코드를 검색 할 VBA 함수를 찾고 있는데, 다른 방법은 것 같습니다. –

+1

이러한 API는 Windows API 호출이므로 VBA 응용 프로그램에서 사용할 수 있습니다. – James

+1

죄송합니다. 더 자세히 살펴 보겠습니다. 감사합니다 –

3

이 기능은 ShellAndWait 기능에 싸서되었습니다.

우수 작성 here.

+2

기사 주셔서 감사합니다. 나는 이것을 과거에 검토했다. 호출 된 응용 프로그램에서 종료 코드를 리턴하지 않습니다. 셸 응용 프로그램이 성공적으로 종료되면 응용 프로그램이 보낸 종료 코드를 고려하지 않은 코드 만 반환합니다. 예를 들어 콘솔 응용 프로그램에서 파일을 찾을 수없는 경우 종료 코드 1로 종료되지만 응용 프로그램이 올바르게 종료되었으므로 셸과 대기 코드가 성공적으로 반환됩니다. –

+0

아, 제 잘못, 충분히 자세히 검토하지 않았습니다. 아무 걱정도, 제임스가 그것을 가지고 있다고 생각합니다. – Mark