--- a/Win32OperatingSystem.st Thu Aug 09 17:33:11 2018 +0200
+++ b/Win32OperatingSystem.st Fri Aug 10 12:03:54 2018 +0200
@@ -598,6 +598,7 @@
buffer[i] = __unicode16StringVal(string)[i];
}
} else {
+ buffer[0] = 0;
return(-1);
}
buffer[len] = 0;
@@ -1669,7 +1670,7 @@
result := self primCloseClipboard.
result ifFalse: [
- self error:'Clipboard close failed'
+ self error:'Clipboard close failed'
].
^ result
@@ -1677,11 +1678,11 @@
!
emptyClipboard
- "Private - empty the clipboard. Note: it must be opened first."
+ "Private - empty the clipboard. Note: it must be opened first."
| result |
result := self primEmptyClipboard.
result ifFalse: [
- self error:'Clipboard empty failed'
+ self error:'Clipboard empty failed'
].
^result
@@ -1703,7 +1704,7 @@
result := self primOpenClipboard: aHwnd.
result ifFalse: [
- self error:'Clipboard open failed'
+ self error:'Clipboard open failed'
].
^ result
@@ -1761,7 +1762,7 @@
self closeClipboard
"
- Win32OperatingSystem setBitmapToClipboard: Image fromUser
+ Win32OperatingSystem setBitmapToClipboard: Image fromUser
"
"Modified (format): / 03-08-2018 / 11:24:11 / Stefan Vogel"
@@ -1772,7 +1773,7 @@
result := self primSetClipboardData: aCfConstant hMem: aMemHandle address.
result = 0 ifTrue: [
- self error:'Set clipboard data failed'
+ self error:'Set clipboard data failed'
].
^ result.
@@ -4374,7 +4375,7 @@
handle := Win32ProcessHandle new.
%{
- SHELLEXECUTEINFO shExecInfo = {0};
+ SHELLEXECUTEINFOW shExecInfo = {0};
shExecInfo.cbSize = sizeof(shExecInfo);
if (__isSmallInteger(nShowCmd)) {
@@ -4405,30 +4406,40 @@
}
}
if (((lpOperationArg == nil) || __isStringLike(lpOperationArg))
- && ((lpFileArg == nil) || __isStringLike(lpFileArg))
- && ((lpParametersArg == nil) || __isStringLike(lpParametersArg))
- && ((lpDirectoryArg == nil) || __isStringLike(lpDirectoryArg))
+ && ((lpFileArg == nil) || __isStringLike(lpFileArg) || __isUnicode16String(lpFileArg))
+ && ((lpParametersArg == nil) || __isStringLike(lpParametersArg) || __isUnicode16String(lpParametersArg))
+ && ((lpDirectoryArg == nil) || __isStringLike(lpDirectoryArg) || __isUnicode16String(lpDirectoryArg))
) {
// hProcess member receives the process handle
shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
+ wchar_t _wFileArg[MAXPATHLEN+1];
+ wchar_t _wParametersArg[MAXPATHLEN+1];
+ wchar_t _wDirectoryArg[MAXPATHLEN+1];
+ wchar_t _wVerbArg[128];
+
+ _makeWchar(lpOperationArg, _wVerbArg, sizeof(_wVerbArg));
+ _makeWchar(lpFileArg, _wFileArg, sizeof(_wFileArg));
+ _makeWchar(lpParametersArg, _wParametersArg, sizeof(_wParametersArg));
+ _makeWchar(lpDirectoryArg, _wDirectoryArg, sizeof(_wDirectoryArg));
+
+ shExecInfo.lpVerb = (lpOperationArg != nil) ? _wVerbArg : NULL;
+ shExecInfo.lpFile = (lpFileArg != nil) ? _wFileArg : NULL;
+ shExecInfo.lpParameters = (lpParametersArg != nil) ? _wParametersArg : NULL;
+ shExecInfo.lpDirectory = (lpDirectoryArg != nil) ? _wDirectoryArg : NULL;
shExecInfo.hwnd = 0;
- shExecInfo.lpVerb = (lpOperationArg != nil) ? __stringVal(lpOperationArg) : NULL;
- shExecInfo.lpFile = (lpFileArg != nil) ? __stringVal(lpFileArg) : NULL;
- shExecInfo.lpParameters = (lpParametersArg != nil) ? __stringVal(lpParametersArg) : NULL;
- shExecInfo.lpDirectory = (lpDirectoryArg != nil) ? __stringVal(lpDirectoryArg) : NULL;
if (hwndArg != nil) {
if (__isExternalAddressLike(hwndArg)) {
shExecInfo.hwnd = _HANDLEVal(hwndArg);
} else
goto badArgument;
}
- if (ShellExecuteEx(&shExecInfo)) {
+ if (ShellExecuteExW(&shExecInfo)) {
if (shExecInfo.hProcess) {
DWORD_PTR processAffinityMask, systemAffinityMask;
/*
- * Set the affinity mask
- * to any processor, and resume the processes main thread.
+ * Set the affinity mask to any processor,
+ * and resume the processes main thread.
* (librun/process.s limited the affinity to a single processor).
*/
GetProcessAffinityMask(shExecInfo.hProcess, &processAffinityMask, &systemAffinityMask);
@@ -6021,10 +6032,10 @@
codePage := vfi unsignedInt16At:3.
assocs := infoKeys collect:[:each |
sfi := self extractVersionValue:('\StringFileInfo\%1%2\%3'
- bindWith:(lang hexPrintString:4)
- with:(codePage hexPrintString:4)
- with:each)
- from:bytes.
+ bindWith:(lang hexPrintString:4)
+ with:(codePage hexPrintString:4)
+ with:each)
+ from:bytes.
each -> (sfi zeroByteStringAt:1 maximumSize:999)
].
^ Dictionary withAssociations:assocs
@@ -7601,8 +7612,8 @@
The process terminates immediately and has no chance to perform any cleanup actions.
WARNING: in order to avoid zombie processes (on unix),
- you have to fetch the processes exitstatus with
- OperatingSystem>>getStatusOfProcess:aProcessId."
+ you have to fetch the processes exitstatus with
+ OperatingSystem>>getStatusOfProcess:aProcessId."
self killProcess:processHandleOrPid exitCode:0.
@@ -7615,20 +7626,20 @@
%{
if (__isExternalAddressLike(processHandleOrPid) ) {
- HANDLE hProcess = _HANDLEVal(processHandleOrPid);
-
- if (hProcess != 0) {
- TerminateProcess( hProcess, __intVal(exitCode) );
- }
- RETURN( true );
+ HANDLE hProcess = _HANDLEVal(processHandleOrPid);
+
+ if (hProcess != 0) {
+ TerminateProcess( hProcess, __intVal(exitCode) );
+ }
+ RETURN( true );
} else if( __isSmallInteger(processHandleOrPid) ) {
- HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, __smallIntegerVal(processHandleOrPid));
-
- if( hProcess != 0 ) {
- TerminateProcess( hProcess, __intVal(exitCode) );
- CloseHandle(hProcess);
- }
- RETURN( true );
+ HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, __smallIntegerVal(processHandleOrPid));
+
+ if( hProcess != 0 ) {
+ TerminateProcess( hProcess, __intVal(exitCode) );
+ CloseHandle(hProcess);
+ }
+ RETURN( true );
}
%}.
self primitiveFailed:#invalidParameter.
@@ -7642,15 +7653,15 @@
Here we kill any offspring of the process identified by processGroupHandleOrPid.
WARNING: in order to avoid zombie processes (on unix),
- you have to fetch the processes exitstatus with
- OperatingSystem>>getStatusOfProcess:aProcessId."
+ you have to fetch the processes exitstatus with
+ OperatingSystem>>getStatusOfProcess:aProcessId."
| pid processList groupsToTerminate anyMore |
processGroupHandleOrPid isInteger ifTrue:[
- pid := processGroupHandleOrPid
+ pid := processGroupHandleOrPid
] ifFalse:[
- pid := processGroupHandleOrPid pid.
+ pid := processGroupHandleOrPid pid.
].
groupsToTerminate := Set with:pid.
processList := self getAllProcesses asSet.
@@ -7658,21 +7669,21 @@
"/ Transcript show:'terminate group '; showCR:pid.
anyMore := true.
[anyMore] whileTrue:[
- anyMore := false.
- processList doWithExit:[:anOSProcess :exit |
- |pid|
-
- (groupsToTerminate includes:anOSProcess parentPid) ifTrue:[
- pid := anOSProcess pid.
- groupsToTerminate add:pid.
- "/ Transcript show:'terminate '; showCR:pid.
- self killProcess:pid.
- processList remove:anOSProcess.
- anyMore := true.
- "/ need to restart: we have removed an element inside the loop
- exit value:nil
- ].
- ].
+ anyMore := false.
+ processList doWithExit:[:anOSProcess :exit |
+ |pid|
+
+ (groupsToTerminate includes:anOSProcess parentPid) ifTrue:[
+ pid := anOSProcess pid.
+ groupsToTerminate add:pid.
+ "/ Transcript show:'terminate '; showCR:pid.
+ self killProcess:pid.
+ processList remove:anOSProcess.
+ anyMore := true.
+ "/ need to restart: we have removed an element inside the loop
+ exit value:nil
+ ].
+ ].
].
"Modified: / 03-08-2018 / 09:58:21 / Stefan Vogel"
@@ -7774,15 +7785,15 @@
"terminate a process.
ATTENTION WIN32:
- Under unix, we have terminateProcess, which does a soft
- terminate (giving the process a chance to cleanup) and
- killProcess, which does a hard terminate.
- Under WIN32, both (currently) use the TerminateProcess
- function, which unconditionally causes a process to exit.
- I.e. under WIN32, the process has no chance to perform cleanup.
- Use it only in extreme circumstances. The state of
- global data maintained by dynamic-link libraries (DLLs)
- may be compromised if TerminateProcess is used.
+ Under unix, we have terminateProcess, which does a soft
+ terminate (giving the process a chance to cleanup) and
+ killProcess, which does a hard terminate.
+ Under WIN32, both (currently) use the TerminateProcess
+ function, which unconditionally causes a process to exit.
+ I.e. under WIN32, the process has no chance to perform cleanup.
+ Use it only in extreme circumstances. The state of
+ global data maintained by dynamic-link libraries (DLLs)
+ may be compromised if TerminateProcess is used.
TODO: send a WM_QUIT instead, to allow for proper shutdown."
@@ -7797,15 +7808,15 @@
"terminate a process group (that is all subprocesses of a process).
ATTENTION WIN32:
- Under unix, we have terminateProcess, which does a soft
- terminate (giving the process a chance to cleanup) and
- killProcess, which does a hard terminate.
- Under WIN32, both (currently) use the TerminateProcess
- function, which unconditionally causes a process to exit.
- I.e. under WIN32, the process has no chance to perform cleanup.
- Use it only in extreme circumstances. The state of
- global data maintained by dynamic-link libraries (DLLs)
- may be compromised if TerminateProcess is used.
+ Under unix, we have terminateProcess, which does a soft
+ terminate (giving the process a chance to cleanup) and
+ killProcess, which does a hard terminate.
+ Under WIN32, both (currently) use the TerminateProcess
+ function, which unconditionally causes a process to exit.
+ I.e. under WIN32, the process has no chance to perform cleanup.
+ Use it only in extreme circumstances. The state of
+ global data maintained by dynamic-link libraries (DLLs)
+ may be compromised if TerminateProcess is used.
TODO: send a WM_QUIT instead, to allow for proper shutdown."
self killProcessGroup:processGroupHandleOrPid.
@@ -11194,11 +11205,11 @@
"commands to try for speech output"
^ #(
- ('powershell'
- 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SPeechSynthesizer).Speak(''%2'');"'
- 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SPeechSynthesizer).Speak(''%2'');"'
- )
- )
+ ('powershell'
+ 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SPeechSynthesizer).Speak(''%2'');"'
+ 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SPeechSynthesizer).Speak(''%2'');"'
+ )
+ )
"
self speak:'hello'