Пытаясь получить коды ошибок из исполняемого файла .NET, я запускаю из VB6 - PullRequest
0 голосов
/ 28 марта 2011

Я запускаю консольное приложение .NET из wihin VB6, используя API-вызов ShellExecute:

ExitCode = ShellExecute(Me.hWnd, "open", GetAppPath & "\SQL Utilities\" & "DocXferClient.exe", strFlags, vbNull, SW_HIDE)

В приложении .NET (DocXFerClient) я отправляю попытку вернуть «код ошибки» с помощью Environment.ExitCode:

Sub Main()
    BuildConnectionObject()
    ProcessRequest()

    Environment.ExitCode = 55 
End Sub

Однако, какой бы код ошибки я не пытался вернуть (в данном случае «55»), ExitCode в VB6 всегда равен «42». Я что-то не так делаю на стороне VB6, на стороне .NET или на обоих?

Ответы [ 2 ]

4 голосов
/ 28 марта 2011

ShellExecute не возвращает код выхода. Возвращает успех (значение больше 32) или сбой (32 или меньше). Это можно выяснить, либо прочитав документацию , либо заметив тот факт, что ShellExecute возвращает свое значение до завершения процесса.

Обязательная ссылка Раймонда Чена: Что я могу сделать с HINSTANCE, возвращаемым функцией ShellExecute?


Чтобы получить код выхода, используйте GetExitCodeProcess.

Чтобы получить дескриптор процесса, запустите ваше приложение с CreateProcess, а не ShellExecute.

Не забудьте вызвать CloseHandle для обоих процессов и обработчиков потоков, которые он возвращает.

0 голосов
/ 14 июня 2016

Для тех, кто все еще подвергается VB6 в наше продвинутое время, я хотел бы опубликовать наиболее полный пример. Код, приведенный на следующем сайте, великолепен: http://vbnet.mvps.org/index.html?code/faq/waitforsingleobject2.htm,, но вы должны соединить 2 примера вместе, чтобы получить рабочий бит, который будет ожидать выхода очищенного приложения, не входя в цикл с интенсивным использованием ЦП, и получить правильный код выхода.

Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Const SYNCHRONIZE = &H100000
Private Const WAIT_INFINITE = -1&
Private Const PROCESS_QUERY_INFORMATION = &H400

ProcessId = Shell("D:\iwCode\dev\proj\appmanager\MoveIniFileUtil\bin\Debug\MoveIniFileUtil.exe 5", vbNormalFocus)
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or SYNCHRONIZE, True, ProcessId)
dummyRet = WaitForSingleObject(hProcess, WAIT_INFINITE)
GetExitCodeProcess hProcess, exitCode
CloseHandle hProcess
MsgBox exitCode

Важным моментом, который не был для меня сразу очевидным, было то, что вы должны вызывать функцию OpenProcess с флагами SYNCHRONIZE и PROCESS_QUERY_INFORMATION Or вместе, чтобы это работало.

...