开发者

Trying to obtain error codes from a .NET executable I run from VB6

I execute a .NET console app from wihin VB6 using the ShellExecute API call:

ExitCode = ShellExecute(Me.hWnd, "open", Get开发者_运维问答AppPath & "\SQL Utilities\" & "DocXferClient.exe", strFlags, vbNull, SW_HIDE)

Within the .NET app (DocXFerClient), I send attempt to return an "error code" using Environment.ExitCode:

Sub Main()
    BuildConnectionObject()
    ProcessRequest()

    Environment.ExitCode = 55 
End Sub

However, whatever error code I try returning (in this case "55"), the ExitCode within VB6 is always "42." Am I doing something wrong on the VB6 side, the .NET side, or both?


ShellExecute does not return an exit code. It returs a success (value greater than 32) or a failure (32 or less). One could figure that out either by reading the documentation or observing the fact that ShellExecute returns its value before the process exits.

Obligatory Raymond Chen link: What can I do with the HINSTANCE returned by the ShellExecute function?


To get the exit code, use GetExitCodeProcess.

To get the process handle, run your app with CreateProcess, not ShellExecute.

Do not forget calling CloseHandle on both process and thread handles it returns.


For those still subjected to VB6 in our advanced times I would like to post a mostly-complete example. The code given at the following site is great: http://vbnet.mvps.org/index.html?code/faq/waitforsingleobject2.htm, but you have to put 2 of the examples together to get a working bit that will wait for the shelled app to exit without entering a CPU intensive loop and get a correct exit code.

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

The important bit here that wasn't immediately apparent to me was that you must call the OpenProcess function with the SYNCHRONIZE and PROCESS_QUERY_INFORMATION flags Or'ed together to get this to work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜