visual sub que .net vb6 process

.net - sub - ¿Puedo engendrar un proceso sincrónico en VB6 y recuperar su valor de retorno?



function procedure (3)

¿Es posible engendrar un proceso sincrónico en VB6 (es decir, llamar a un .exe externo), esperar a que termine y tomar el valor de retorno?

Tenemos código heredado (en VB6 obviamente) que necesitamos llamar a una aplicación .NET para realizar algunas tareas complicadas y, en función del valor de retorno de la aplicación .NET, procedamos o fallamos. ¿Hay una mejor manera de hacer tal cosa?


Podrías usar:

Option Explicit Private Const INFINITE = &HFFFF& Private Const SYNCHRONIZE = &H100000 Private Const PROCESS_QUERY_INFORMATION = &H400& Private Declare Function CloseHandle Lib "kernel32" ( _ ByVal hObject As Long) As Long Private Declare Function GetExitCodeProcess Lib "kernel32" ( _ ByVal hProcess As Long, _ lpExitCode 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 WaitForSingleObject Lib "kernel32" ( _ ByVal hHandle As Long, _ ByVal dwMilliseconds As Long) As Long Private Function SyncShell( _ ByVal PathName As String, _ ByVal WindowStyle As VbAppWinStyle) As Long ''Shell and wait. Return exit code result, raise an ''exception on any error. Dim lngPid As Long Dim lngHandle As Long Dim lngExitCode As Long lngPid = Shell(PathName, WindowStyle) If lngPid <> 0 Then lngHandle = OpenProcess(SYNCHRONIZE _ Or PROCESS_QUERY_INFORMATION, 0, lngPid) If lngHandle <> 0 Then WaitForSingleObject lngHandle, INFINITE If GetExitCodeProcess(lngHandle, lngExitCode) <> 0 Then SyncShell = lngExitCode CloseHandle lngHandle Else CloseHandle lngHandle Err.Raise &H8004AA00, "SyncShell", _ "Failed to retrieve exit code, error " _ & CStr(Err.LastDllError) End If Else Err.Raise &H8004AA01, "SyncShell", _ "Failed to open child process" End If Else Err.Raise &H8004AA02, "SyncShell", _ "Failed to Shell child process" End If End Function


Su primera opción probablemente sea exponer una interfaz para exponer las interfaces .NET a COM y usar eso (es mucho más limpio), pero si por alguna razón tiene que hacerlo a través de un proceso engendrado, use este código VB6.

Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessID As Long dwThreadID As Long End Type Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Private Declare Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As Long, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long Private Const NORMAL_PRIORITY_CLASS = &H20& Private Const INFINITE = -1& Private Const SW_HIDE = 0 Private Const SW_SHOWMINNOACTIVE = 7 Public Function ExecCmd(cmdline As String, workdir As String) As Integer Dim proc As PROCESS_INFORMATION Dim start As STARTUPINFO Dim ret as Long ChDrive Left(workdir, 1) & ":" ChDir workdir start.cb = Len(start) start.wShowWindow = SW_SHOWMINNOACTIVE Call CreateProcessA(0&, cmdline, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc) Call WaitForSingleObject(proc.hProcess, INFINITE) Call GetExitCodeProcess(proc.hProcess, ret) Call CloseHandle(proc.hThread) Call CloseHandle(proc.hProcess) ExecCmd=ret End Function


'' References: "Windows Script Host Shell Object Model" '' Function ExecuteCommand(cmd As String, ExpectedResult as Long) As Boolean Dim shell As New IWshRuntimeLibrary.WshShell Dim Result As Long Result = shell.Run(Command:=cmd, WindowStyle:=WshHide, WaitOnReturn:=True) ExecuteCommand = (Result = ExpectedResult) End Function