Hi,
I would like to call "pkunzip.exe" with parameters, so it can unzip a file for my application. Does anyone have an example of calling an exe file with parameters from Smalltalk ? Thanks, Theo |
ShellLibrary>>shellOpen: might be what you want.
"Theo Pronk" <[hidden email]> wrote in message news:c3p2o7$29u2i8$[hidden email]... > Hi, > > I would like to call "pkunzip.exe" with parameters, so it can unzip a > file for my application. > > Does anyone have an example of calling an exe file with parameters from > Smalltalk ? > > Thanks, > Theo > > |
In reply to this post by Theo Pronk
Theo Pronk <[hidden email]> wrote in message news:<c3p2o7$29u2i8$[hidden email]>...
> Hi, > > I would like to call "pkunzip.exe" with parameters, so it can unzip a > file for my application. > > Does anyone have an example of calling an exe file with parameters from > Smalltalk ? Try the ExternalProcess class in my goodies collection. http://www.nls.net/mp/jarvis/Bob/DolphinGoodies.htm I hope this helps. |
In reply to this post by Theo Pronk
"Theo Pronk" <[hidden email]> wrote in message
news:c3p2o7$29u2i8$[hidden email]... > I would like to call "pkunzip.exe" with parameters, so it can unzip a > file for my application. > > Does anyone have an example of calling an exe file with parameters from > Smalltalk ? I think Bob's package may be best for what you are actually doing. However for more generic use I use some variations on shellOpen:, see the methods I added bellow. I think it might be handy if something like the methods bellow found their way into the base system. The text between the bars can filed in and will add two methods to ShellLibrary. ======================= !ShellLibrary methodsFor! shellOpen: fileString directory: dirString parameters: aParameter "Opens the specified file, which can be an executable or document file. Simplified wrapper around ShellExecute() to open a document." | hInst | hInst := self shellExecute: nil lpOperation: 'open' lpFile: fileString lpParameters: aParameter lpDirectory: dirString nShowCmd: SW_SHOWNORMAL. ^hInst asInteger <= 32 ifTrue: [self systemError] ifFalse: [hInst]! ! !ShellLibrary categoriesFor: #shellOpen:directory:parameters:!public!win32 functions-shell library! ! !ShellLibrary methodsFor! shellOpen: fileString parameters: aParameter "Opens the specified file, which can be an executable or document file. Simplified wrapper around ShellExecute() to open a document." ^self shellOpen: fileString directory: nil parameters: aParameter ! ! !ShellLibrary categoriesFor: #shellOpen:parameters:!must not strip!public!win32 functions-shell library! ! ======================= Chris |
Here is some generic S# code that gives you the Win32 sequences...
exec: cmdLine inheritHandles: bInheritHandles <$lang=c++> bool doInherit = bInheritHandles != false_oop; STARTUPINFO startInfo; startInfo.cb = sizeof(startInfo); memset(&startInfo,0,sizeof(startInfo)); PROCESS_INFORMATION processInfo; BOOL bOk = CreateProcess( (LPCTSTR)NULL, (LPTSTR)cmdLine->pBytes(), NULL, NULL, doInherit, (doInherit ? NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW), NULL, NULL, &startInfo, &processInfo ); if (bOk) WaitForSingleObject(processInfo.hProcess,INFINITE); DWORD exitCode; GetExitCodeProcess(processInfo.hProcess, &exitCode); return AsNumber(exitCode); ----------------- OR ----------------- shellExec: commandLine verb: verb show: showFlags ^Shell32::ShellExecute( 0, verb, commandLine, 0, 0, showFlags). ----------------- OR If you need finer grain control, like monitoring state and capturing the console (stdin/stdout/stderr) i/o in realtime as the spawned program runs... ----------------- ###################################################### # Copyright(c) Smallscript Corporation 1999-2004 # # Environment: # AOS Framework Core Library and Services # # Author(s): # David Simmons [Portions(c) DAS 1987-2004] ###################################################### """"""""""""""""""""""""""""""""""""""""" "" Services for spawning an executable "" and capturing its console output. """"""""""""""""""""""""""""""""""""""""" ""Project name: _ shared_fields: Class ref.name: Public add.shared_fields: alias[DWORD] HANDLE, alias[UInt16] WORD, alias[UInt32] BOOL, alias[UInt32] LPVOID, alias[DWORD] LPBYTE. Struct name: Standard.IO.SECURITY_ATTRIBUTES fields: auto struct DWORD nLength, LPVOID lpSecurityDescriptor, BOOL bInheritHandle; { Function [ <::()> new ^__new() nLength(md_nsbytes) ] } Struct name: Standard.IO.STARTUPINFO fields: auto struct DWORD cb, LPTSTR lpReserved, lpDesktop, lpTitle, DWORD dwX, dwY, dwXSize, dwYSize, dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags, WORD wShowWindow, cbReserved2, LPBYTE lpReserved2, HANDLE hStdInput, hStdOutput, hStdError; { } Struct name: Standard.IO.PROCESS_INFORMATION fields: auto struct HANDLE hProcess, hThread, DWORD dwProcessId, dwThreadId; { } Enum name: Standard.IO.K_IO { // These should already be somewhere #define MINCHAR 0x80 #define MAXCHAR 0x7f #define MINSHORT 0x8000 #define MAXSHORT 0x7fff #define MINLONG 0x80000000 #define MAXLONG 0x7fffffff #define MAXBYTE 0xff #define MAXWORD 0xffff #define MAXDWORD 0xffffffff // File IO Options #define FILE_TYPE_UNKNOWN 0x0000 #define FILE_TYPE_DISK 0x0001 #define FILE_TYPE_CHAR 0x0002 #define FILE_TYPE_PIPE 0x0003 #define FILE_TYPE_REMOTE 0x8000 #define STD_INPUT_HANDLE (-10) #define STD_OUTPUT_HANDLE (-11) #define STD_ERROR_HANDLE (-12) ///////////////// // Permissions ///////////////// #define DELETE (0x00010000L) #define READ_CONTROL (0x00020000L) #define WRITE_DAC (0x00040000L) #define WRITE_OWNER (0x00080000L) #define SYNCHRONIZE (0x00100000L) #define STANDARD_RIGHTS_REQUIRED (0x000F0000L) #define STANDARD_RIGHTS_READ (READ_CONTROL) #define STANDARD_RIGHTS_WRITE (READ_CONTROL) #define STANDARD_RIGHTS_EXECUTE (READ_CONTROL) #define STANDARD_RIGHTS_ALL (0x001F0000L) #define SPECIFIC_RIGHTS_ALL (0x0000FFFFL) // // AccessSystemAcl access type // #define ACCESS_SYSTEM_SECURITY (0x01000000L) // // MaximumAllowed access type // #define MAXIMUM_ALLOWED (0x02000000L) // // These are the generic rights. // #define GENERIC_READ (0x80000000L) #define GENERIC_WRITE (0x40000000L) #define GENERIC_EXECUTE (0x20000000L) #define GENERIC_ALL (0x10000000L) #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) #define IO_REPARSE_TAG_HSM (0xC0000004L) #define IO_REPARSE_TAG_SIS (0x80000007L) #define IO_REPARSE_TAG_FILTER_MANAGER (0x8000000BL) #define IO_COMPLETION_MODIFY_STATE 0x0002 #define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) #define DUPLICATE_CLOSE_SOURCE 0x00000001 #define DUPLICATE_SAME_ACCESS 0x00000002 /////////////////////////// // CreateProcess Options /////////////////////////// #define STARTF_USESHOWWINDOW 0x00000001 #define STARTF_USESIZE 0x00000002 #define STARTF_USEPOSITION 0x00000004 #define STARTF_USECOUNTCHARS 0x00000008 #define STARTF_USEFILLATTRIBUTE 0x00000010 #define STARTF_RUNFULLSCREEN 0x00000020 // ignored for non-x86 platforms #define STARTF_FORCEONFEEDBACK 0x00000040 #define STARTF_FORCEOFFFEEDBACK 0x00000080 #define STARTF_USESTDHANDLES 0x00000100 // #define THREAD_BASE_PRIORITY_LOWRT 15 // value that gets a thread to LowRealtime-1 #define THREAD_BASE_PRIORITY_MAX 2 // maximum thread base priority boost #define THREAD_BASE_PRIORITY_MIN (-2) // minimum thread base priority boost #define THREAD_BASE_PRIORITY_IDLE (-15) // value that gets a thread to idle // #define DEBUG_PROCESS 0x00000001 #define DEBUG_ONLY_THIS_PROCESS 0x00000002 #define CREATE_SUSPENDED 0x00000004 #define DETACHED_PROCESS 0x00000008 #define CREATE_NEW_CONSOLE 0x00000010 #define NORMAL_PRIORITY_CLASS 0x00000020 #define IDLE_PRIORITY_CLASS 0x00000040 #define HIGH_PRIORITY_CLASS 0x00000080 #define REALTIME_PRIORITY_CLASS 0x00000100 #define CREATE_NEW_PROCESS_GROUP 0x00000200 #define CREATE_UNICODE_ENVIRONMENT 0x00000400 #define CREATE_SEPARATE_WOW_VDM 0x00000800 #define CREATE_SHARED_WOW_VDM 0x00001000 #define CREATE_FORCEDOS 0x00002000 #define BELOW_NORMAL_PRIORITY_CLASS 0x00004000 #define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000 #define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 #define CREATE_BREAKAWAY_FROM_JOB 0x01000000 #define CREATE_PRESERVE_CODE_AUTHZ_LEVEL 0x02000000 #define CREATE_DEFAULT_ERROR_MODE 0x04000000 #define CREATE_NO_WINDOW 0x08000000 #define PROFILE_USER 0x10000000 #define PROFILE_KERNEL 0x20000000 #define PROFILE_SERVER 0x40000000 #define CREATE_IGNORE_SYSTEM_DEFAULT 0x80000000 #define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN #define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1) #define THREAD_PRIORITY_NORMAL 0 #define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX #define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1) #define THREAD_PRIORITY_ERROR_RETURN (MAXLONG) #define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT #define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE ////////////////////////////////// // ////////////////////////////////// #define STATUS_WAIT_0 (0x00000000L) #define STATUS_ABANDONED_WAIT_0 (0x00000080L) #define STATUS_USER_APC (0x000000C0L) #define STATUS_TIMEOUT (0x00000102L) #define STATUS_PENDING (0x00000103L) #define DBG_EXCEPTION_HANDLED (0x00010001L) #define DBG_CONTINUE (0x00010002L) #define STATUS_SEGMENT_NOTIFICATION (0x40000005L) #define DBG_TERMINATE_THREAD (0x40010003L) #define DBG_TERMINATE_PROCESS (0x40010004L) #define DBG_CONTROL_C (0x40010005L) #define DBG_CONTROL_BREAK (0x40010008L) #define STATUS_GUARD_PAGE_VIOLATION (0x80000001L) #define STATUS_DATATYPE_MISALIGNMENT (0x80000002L) #define STATUS_BREAKPOINT (0x80000003L) #define STATUS_SINGLE_STEP (0x80000004L) #define DBG_EXCEPTION_NOT_HANDLED (0x80010001L) #define STATUS_ACCESS_VIOLATION (0xC0000005L) #define STATUS_IN_PAGE_ERROR (0xC0000006L) #define STATUS_INVALID_HANDLE (0xC0000008L) #define STATUS_NO_MEMORY (0xC0000017L) #define STATUS_ILLEGAL_INSTRUCTION (0xC000001DL) #define STATUS_NONCONTINUABLE_EXCEPTION (0xC0000025L) #define STATUS_INVALID_DISPOSITION (0xC0000026L) #define STATUS_ARRAY_BOUNDS_EXCEEDED (0xC000008CL) #define STATUS_FLOAT_DENORMAL_OPERAND (0xC000008DL) #define STATUS_FLOAT_DIVIDE_BY_ZERO (0xC000008EL) #define STATUS_FLOAT_INEXACT_RESULT (0xC000008FL) #define STATUS_FLOAT_INVALID_OPERATION (0xC0000090L) #define STATUS_FLOAT_OVERFLOW (0xC0000091L) #define STATUS_FLOAT_STACK_CHECK (0xC0000092L) #define STATUS_FLOAT_UNDERFLOW (0xC0000093L) #define STATUS_INTEGER_DIVIDE_BY_ZERO (0xC0000094L) #define STATUS_INTEGER_OVERFLOW (0xC0000095L) #define STATUS_PRIVILEGED_INSTRUCTION (0xC0000096L) #define STATUS_STACK_OVERFLOW (0xC00000FDL) #define STATUS_CONTROL_C_EXIT (0xC000013AL) #define STATUS_FLOAT_MULTIPLE_FAULTS (0xC00002B4L) #define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L) #define STATUS_REG_NAT_CONSUMPTION (0xC00002C9L) #define STATUS_SXS_EARLY_DEACTIVATION (0xC015000FL) #define STATUS_SXS_INVALID_DEACTIVATION (0xC0150010L) // ////////// // #define INVALID_HANDLE_VALUE (-1) #define INVALID_FILE_SIZE (0xFFFFFFFF) #define INVALID_SET_FILE_POINTER (-1) #define INVALID_FILE_ATTRIBUTES (-1) #define FILE_BEGIN 0 #define FILE_CURRENT 1 #define FILE_END 2 #define TIME_ZONE_ID_INVALID (0xFFFFFFFF) #define WAIT_FAILED (0xFFFFFFFF) #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) #define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0 ) + 0 ) #define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0 ) + 0 ) #define WAIT_TIMEOUT 258L // dderror #define WAIT_IO_COMPLETION STATUS_USER_APC #define STILL_ACTIVE STATUS_PENDING #define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION #define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT #define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT #define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP #define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED #define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND #define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO #define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT #define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION #define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW #define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK #define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW #define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO #define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW #define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION #define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR #define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION #define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION #define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW #define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION #define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION #define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE #define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT } Class name: Standard.Environment.Spawn imports: Standard.IO.K_IO, KGUICore_A, Kernel32, User32 fields: auto appName, cmdLine, clientCallback, procInfo, startInfo, hStdinReadPipe, hStdinWritePipe, hStdoutReadPipe, hStdoutWritePipe, hStderrReadPipe, hStderrWritePipe, hSaveStdin, hSaveStdout, hSaveStderr; auto virtual[procInfo] hProcess, virtual[procInfo] hThread, virtual[procInfo] dwThreadId, virtual[procInfo] dwProcessId; { Function [ ExecAndCaptureOutput(cmd, <[out]> captured_data) captured_data := nil. |buffer := String(2048)||progressHandler| := [:spawn :dwExitCode||lpTotalBytesAvail| PeekNamedPipe(spawn.hStdoutReadPipe, null, 0, null, &lpTotalBytesAvail, null). while(lpTotalBytesAvail) [ |nToRead| := lpTotalBytesAvail min: buffer.size. ReadFile(spawn.hStdoutReadPipe, buffer, nToRead, &nToRead, null). lpTotalBytesAvail :-= nToRead. captured_data :+= buffer[1:nToRead]. ]. ]. return ExecCmd(cmd, progressHandler). ] Function [<::execCmd(<>,<>)> ExecCmd(cmdLine, clientCallback) "" Note that we could provide a variant the "" separated the target-exe from its arguments. "" See OS docs on CreateProcess. ^__new() cmdLine(cmdLine); clientCallback(clientCallback); execute. ] Function [<::execCmd(<>,<>,<>)> ExecCmd(appName, cmdLine, clientCallback) "" Note that we could provide a variant the "" separated the target-exe from its arguments. "" See OS docs on CreateProcess. ^__new() appName(appName); cmdLine(cmdLine); clientCallback(clientCallback); execute. ] Method [ redirectIO "" Preflight stdxxx pipe creation |hStdoutReadPipeTmp, hPipe, lpPipeAttributes := SECURITY_ATTRIBUTES()| "" Set the bInheritHandle flag so pipe handles are inherited. lpPipeAttributes.bInheritHandle := true. """"""""""""""""""""""""""""" "" Allocate the STDOUT pipe """"""""""""""""""""""""""""" if(!CreatePipe(&hStdoutReadPipeTmp, &hPipe, lpPipeAttributes, null "use default pipe size")) throw('CreatePipe failed'). hStdoutWritePipe := hPipe. "" Set a write handle to the pipe to be STDOUT. if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdoutWritePipe)) throw('Redirecting STDOUT failed'). "" Create noninheritable read handle and close the inheritable read handle. if (!DuplicateHandle(GetCurrentProcess(), hStdoutReadPipeTmp, GetCurrentProcess(), &hPipe, 0, false, DUPLICATE_SAME_ACCESS)) throw('DuplicateHandle failed'). hStdoutReadPipe := hPipe. CloseHandle(hStdoutReadPipeTmp). """""""""""""""""""""""""""" "" Allocate the STDERR pipe """""""""""""""""""""""""""" |hStderrReadPipeTmp| if (!CreatePipe(&hStderrReadPipeTmp, &hPipe, lpPipeAttributes, null)) throw('Stderr pipe creation failed'). hStderrWritePipe := hPipe. "" Set a write handle to the pipe to be STDERR. if (!SetStdHandle(STD_ERROR_HANDLE, hStderrWritePipe)) throw('Redirecting Stderr failed'). "" Create noninheritable read handle and close the inheritable read handle. if (!DuplicateHandle(GetCurrentProcess(), hStderrReadPipeTmp, GetCurrentProcess(), &hPipe, 0, false, DUPLICATE_SAME_ACCESS)) throw('DuplicateHandle failed'). hStderrReadPipe := hPipe. CloseHandle(hStderrReadPipeTmp). """""""""""""""""""""""""""" "" Allocate the STDIN pipe """""""""""""""""""""""""""" |hStdinWritePipeTmp| if (!CreatePipe(&hPipe, &hStdinWritePipeTmp, lpPipeAttributes, null)) throw('Stdin pipe creation failed'). hStdinReadPipe := hPipe. "" Set a read handle to the pipe to be STDIN. if (!SetStdHandle(STD_INPUT_HANDLE, hStdinReadPipe)) throw('Redirecting Stdin failed'). "" Duplicate the write handle to the pipe so it is not inherited. if (!DuplicateHandle(GetCurrentProcess(), hStdinWritePipeTmp, GetCurrentProcess(), &hPipe, 0, false, DUPLICATE_SAME_ACCESS)) throw('DuplicateHandle failed'). hStdinWritePipe := hPipe. CloseHandle(hStdinWritePipeTmp). ] Method [ createChildProcess "" Set up members of STARTUPINFO structure. startInfo := STARTUPINFO(). startInfo.dwFlags := STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW. startInfo.wShowWindow := SW_HIDE. startInfo.hStdInput := hStdinReadPipe. startInfo.hStdOutput := hStdoutWritePipe. startInfo.hStdError := hStdoutWritePipe. procInfo := PROCESS_INFORMATION(). "" Tweak as needed for various CreateProcess quirks unless.nil(appName) [ "" Unquote the appName, as required if(appName[1] == $")""" appName := appName[2:appName.lastIndexOf($")-1]. """ "" Ensure spacing for when it concatenates them if (cmdLine.size and: [cmdLine[1].isWhitespace.not]) cmdLine := ' '+cmdLine. ]. "" Create the child process. ^CreateProcess(appName, "" application name cmdLine, "" command line (or appName+' '+cmdLine) null, "" process security attributes null, "" primary thread security attributes true, "" handles are inherited CREATE_NEW_CONSOLE, "" creation flags null, "" use parent's environment null, "" use parent's current directory startInfo, "" STARTUPINFO pointer &procInfo). "" receives PROCESS_INFORMATION ] Method [ execute "" Save the STDXXX handles. hSaveStdin := GetStdHandle(STD_INPUT_HANDLE). hSaveStderr := GetStdHandle(STD_ERROR_HANDLE). hSaveStdout := GetStdHandle(STD_OUTPUT_HANDLE). try [ "" Now create the child process. redirectIO(). if (createChildProcess() != true) [ |error| := thread.lastHostErrorString. if.nil(|request| := appName) request := cmdLine. else unless.nil(cmdLine) request :+= "follow its spacing rules" cmdLine. throw('Create process failed : ' + error + ' : exec(`'' + request + '`')'). ]. ] finally [ "" After process creation, restore the saved STDXXX handles. SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout). SetStdHandle(STD_ERROR_HANDLE, hSaveStderr). SetStdHandle(STD_INPUT_HANDLE, hSaveStdin). ]. | dwExitCode, handles := ByteArray(12), dwTimeoutMS := 100, dwWakeMask := QS_ALLEVENTS, dwFlags := (MWMO_ALERTABLE | (VM.IsWinNT4 ?: 0 : MWMO_INPUTAVAILABLE)) | try [ "" Check process status, if exited we must break out of our loop |nHandles := handles.size // 4| handles uint32At: 8 put: hStderrWritePipe; uint32At: 4 put: hStdoutWritePipe; uint32At: 0 put: hProcess. while(hProcess and: [GetExitCodeProcess(hProcess, &dwExitCode) and: [dwExitCode = STILL_ACTIVE]]) [ "" invoke clientCallback clientCallback.(self, dwExitCode). "" Block waiting for IO, processExit, or timeout |iErr| := MsgWaitForMultipleObjectsEx( nHandles, handles, dwTimeoutMS, dwWakeMask, dwFlags ). "" Give up a slice before we do something again if (iErr = WAIT_FAILED) SleepEx(0, false). ]. "" invoke clientCallback clientCallback.(self, dwExitCode). ] finally [ "" Close/release the temporary pipes CloseHandle(hStdinReadPipe). CloseHandle(hStdinWritePipe). CloseHandle(hStdoutReadPipe). CloseHandle(hStdoutWritePipe). CloseHandle(hStderrReadPipe). CloseHandle(hStderrWritePipe). ]. "" Return the exit code ^dwExitCode. ] } -- Dave S. [www.smallscript.org] "Christopher J. Demers" <[hidden email]> wrote in message news:c3q9ra$2ahof9$[hidden email]... > "Theo Pronk" <[hidden email]> wrote in message > news:c3p2o7$29u2i8$[hidden email]... > > I would like to call "pkunzip.exe" with parameters, so it can unzip a > > file for my application. > > > > Does anyone have an example of calling an exe file with parameters from > > Smalltalk ? > > I think Bob's package may be best for what you are actually doing. However > for more generic use I use some variations on shellOpen:, see the methods I > added bellow. I think it might be handy if something like the methods > bellow found their way into the base system. > > The text between the bars can filed in and will add two methods to > ShellLibrary. > ======================= > !ShellLibrary methodsFor! > shellOpen: fileString directory: dirString parameters: aParameter > "Opens the specified file, which can be an executable or document file. > Simplified wrapper around ShellExecute() to open a document." > | hInst | > hInst := self shellExecute: nil > lpOperation: 'open' > lpFile: fileString > lpParameters: aParameter > lpDirectory: dirString nShowCmd: SW_SHOWNORMAL. > ^hInst asInteger <= 32 > ifTrue: [self systemError] > ifFalse: [hInst]! ! > !ShellLibrary categoriesFor: #shellOpen:directory:parameters:!public!win32 > functions-shell library! ! > !ShellLibrary methodsFor! > shellOpen: fileString parameters: aParameter > "Opens the specified file, which can be an executable or document file. > Simplified wrapper around ShellExecute() to open a document." > ^self shellOpen: fileString directory: nil parameters: aParameter > ! ! > !ShellLibrary categoriesFor: #shellOpen:parameters:!must not > strip!public!win32 functions-shell library! ! > ======================= > > Chris > > |
In reply to this post by Christopher J. Demers
Here is an example of calling the previously provided code:
|cmds| := String().Write('xcopy /D /K /X /Y "{0}" "{1}"', f1.trim, f2.trim). thisThread.exec: cmds inheritHandles: true. -- Dave S. [www.smallscript.org] "Christopher J. Demers" <[hidden email]> wrote in message news:c3q9ra$2ahof9$[hidden email]... > "Theo Pronk" <[hidden email]> wrote in message > news:c3p2o7$29u2i8$[hidden email]... > > I would like to call "pkunzip.exe" with parameters, so it can unzip a > > file for my application. > > > > Does anyone have an example of calling an exe file with parameters from > > Smalltalk ? > > I think Bob's package may be best for what you are actually doing. However > for more generic use I use some variations on shellOpen:, see the methods I > added bellow. I think it might be handy if something like the methods > bellow found their way into the base system. > > The text between the bars can filed in and will add two methods to > ShellLibrary. > ======================= > !ShellLibrary methodsFor! > shellOpen: fileString directory: dirString parameters: aParameter > "Opens the specified file, which can be an executable or document file. > Simplified wrapper around ShellExecute() to open a document." > | hInst | > hInst := self shellExecute: nil > lpOperation: 'open' > lpFile: fileString > lpParameters: aParameter > lpDirectory: dirString nShowCmd: SW_SHOWNORMAL. > ^hInst asInteger <= 32 > ifTrue: [self systemError] > ifFalse: [hInst]! ! > !ShellLibrary categoriesFor: #shellOpen:directory:parameters:!public!win32 > functions-shell library! ! > !ShellLibrary methodsFor! > shellOpen: fileString parameters: aParameter > "Opens the specified file, which can be an executable or document file. > Simplified wrapper around ShellExecute() to open a document." > ^self shellOpen: fileString directory: nil parameters: aParameter > ! ! > !ShellLibrary categoriesFor: #shellOpen:parameters:!must not > strip!public!win32 functions-shell library! ! > ======================= > > Chris > > |
In reply to this post by David Simmons-2
"David Simmons" <[hidden email]> wrote in message
news:[hidden email]... > Here is some generic S# code that gives you the Win32 sequences... > > exec: cmdLine > inheritHandles: bInheritHandles > [... ~550 lines snipped...] Thanks David, but I think Chris Demer's solution will be adequate. Failing that Bob Jarvis' package provides the necessary level of control for more complex requirements. Regards Blair |
In reply to this post by Christopher J. Demers
Thanks Chris,
The methods you gave helped greatly, after I discovered that ShellLibrary requires "default" not "new" eg to run pkunzip from c:\tools\pkzip with parameter /h I had to do the following: ShellLibrary default shellOpen: 'pkunzip.exe' directory: 'C:/Tools/pkzip/' parameters: '/h' Regards, Theo PS Bob your ExternalProcess.pac also like a looks addition in the furture. ============================ Christopher J. Demers wrote: > "Theo Pronk" <[hidden email]> wrote in message > news:c3p2o7$29u2i8$[hidden email]... > >>I would like to call "pkunzip.exe" with parameters, so it can unzip a >>file for my application. >> >>Does anyone have an example of calling an exe file with parameters from >>Smalltalk ? > > > I think Bob's package may be best for what you are actually doing. However > for more generic use I use some variations on shellOpen:, see the methods I > added bellow. I think it might be handy if something like the methods > bellow found their way into the base system. > > The text between the bars can filed in and will add two methods to > ShellLibrary. > ======================= > !ShellLibrary methodsFor! > shellOpen: fileString directory: dirString parameters: aParameter > "Opens the specified file, which can be an executable or document file. > Simplified wrapper around ShellExecute() to open a document." > | hInst | > hInst := self shellExecute: nil > lpOperation: 'open' > lpFile: fileString > lpParameters: aParameter > lpDirectory: dirString nShowCmd: SW_SHOWNORMAL. > ^hInst asInteger <= 32 > ifTrue: [self systemError] > ifFalse: [hInst]! ! > !ShellLibrary categoriesFor: #shellOpen:directory:parameters:!public!win32 > functions-shell library! ! > !ShellLibrary methodsFor! > shellOpen: fileString parameters: aParameter > "Opens the specified file, which can be an executable or document file. > Simplified wrapper around ShellExecute() to open a document." > ^self shellOpen: fileString directory: nil parameters: aParameter > ! ! > !ShellLibrary categoriesFor: #shellOpen:parameters:!must not > strip!public!win32 functions-shell library! ! > ======================= > > Chris > > |
Free forum by Nabble | Edit this page |