Win32OperatingSystem.st
changeset 25339 3fb3b8bd0b19
parent 25330 bf8d3eba937e
child 25341 6c9eae7e45a3
equal deleted inserted replaced
25338:7ebc001a5a1b 25339:3fb3b8bd0b19
  1731     ConsoleOutputEncoder isNil ifTrue:[
  1731     ConsoleOutputEncoder isNil ifTrue:[
  1732         cp := self getConsoleOutputCP.
  1732         cp := self getConsoleOutputCP.
  1733         "/ should handle more codePages via GetConsoleOutputCP
  1733         "/ should handle more codePages via GetConsoleOutputCP
  1734         outputEncoder := CharacterEncoder encoderNamed:('cp%1' bindWith:cp).
  1734         outputEncoder := CharacterEncoder encoderNamed:('cp%1' bindWith:cp).
  1735         outputEncoder isNullEncoder ifTrue:[
  1735         outputEncoder isNullEncoder ifTrue:[
  1736             ('no encoder for CP%1' bindWith:cp) _errorPrintCR.
  1736             "/ ('no encoder for cp%1' bindWith:cp) _errorPrintCR.
  1737             "/ should we fallback here???
  1737             "/ should we fallback here???
  1738         ] ifFalse:[
  1738         ] ifFalse:[
  1739             ConsoleOutputEncoder := outputEncoder
  1739             ConsoleOutputEncoder := outputEncoder
  1740         ].
  1740         ].
  1741     ].
  1741     ].
  5156 
  5156 
  5157     fileHandle := Win32FileHandle new.
  5157     fileHandle := Win32FileHandle new.
  5158 
  5158 
  5159 %{
  5159 %{
  5160     HANDLE h;
  5160     HANDLE h;
       
  5161     char _pathNameBuffer[MAXPATHLEN+1];
       
  5162     wchar_t _wPathNameBuffer[MAXPATHLEN+1];
  5161     char *name;
  5163     char *name;
  5162     wchar_t _wPathName[MAXPATHLEN+1];
  5164     wchar_t wName;
  5163     OBJ *ap;
  5165     OBJ *ap;
  5164     int numAttrib;
  5166     int numAttrib;
  5165     int i, l;
  5167     int i, l;
  5166     DWORD access, share, create, attr;
  5168     DWORD access, share, create, attr;
  5167 
  5169 
  5168     if (__isStringLike(pathName)) {
  5170     if (__isStringLike(pathName)) {
  5169 	name = __stringVal(pathName);
  5171 	name = __stringVal(pathName);
       
  5172 	if (strlen(name) < MAXPATHLEN) {
       
  5173 	    strncpy(_pathNameBuffer, name, sizeof(_pathNameBuffer));
       
  5174 	    name = _pathNameBuffer;
       
  5175 	} // else: CreateA will use object's string (and execute uninterruptable)
  5170     } else if (__isUnicode16String(pathName)) {
  5176     } else if (__isUnicode16String(pathName)) {
  5171 	_makeWchar(pathName, _wPathName, sizeof(_wPathName));
  5177 	_makeWchar(pathName, _wPathNameBuffer, sizeof(_wPathNameBuffer));
       
  5178 	wName = _wPathNameBuffer;
  5172     } else {
  5179     } else {
  5173 	fileHandle = nil;
  5180 	fileHandle = nil;
  5174 	argumentError = @symbol(badPathName);
  5181 	argumentError = @symbol(badPathName);
  5175 	goto badArgument;
  5182 	goto badArgument;
  5176     }
  5183     }
  5240     }
  5247     }
  5241 #endif
  5248 #endif
  5242     if (__isStringLike(pathName)) {
  5249     if (__isStringLike(pathName)) {
  5243 	h = CreateFileA(name, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  5250 	h = CreateFileA(name, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  5244     } else {
  5251     } else {
  5245 	h = CreateFileW(_wPathName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  5252 	h = CreateFileW(wName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  5246     }
  5253     }
  5247 
  5254 
  5248     if (h != INVALID_HANDLE_VALUE) {
  5255     if (h != INVALID_HANDLE_VALUE) {
  5249 	__externalAddressVal(fileHandle) = (void *)h;
  5256 	__externalAddressVal(fileHandle) = (void *)h;
  5250     } else {
  5257     } else {
  5308     int success;
  5315     int success;
  5309 
  5316 
  5310     if (__isStringLike(fullPathName)) {
  5317     if (__isStringLike(fullPathName)) {
  5311 #ifdef DO_WRAP_CALLS
  5318 #ifdef DO_WRAP_CALLS
  5312 	{
  5319 	{
  5313 	    char _aPathName[MAXPATHLEN];
  5320 	    char _aPathName[MAXPATHLEN+1];
  5314 
  5321 
  5315 	    strncpy(_aPathName, __stringVal(fullPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
  5322 	    strncpy(_aPathName, __stringVal(fullPathName), MAXPATHLEN); _aPathName[MAXPATHLEN] = '\0';
  5316 	    do {
  5323 	    do {
  5317 		// do not cast to INT - will loose sign bit then!
  5324 		// do not cast to INT - will loose sign bit then!
  5318 		success = (int)STX_API_NOINT_CALL1( "RemoveDirectoryA", RemoveDirectoryA, _aPathName);
  5325 		success = (int)STX_API_NOINT_CALL1( "RemoveDirectoryA", RemoveDirectoryA, _aPathName);
  5319 	    } while ((success < 0) && (__threadErrno == EINTR));
  5326 	    } while ((success < 0) && (__threadErrno == EINTR));
  5320 	}
  5327 	}
  8966 !
  8973 !
  8967 
  8974 
  8968 getDomainName
  8975 getDomainName
  8969     "return the DNS domain this host is in.
  8976     "return the DNS domain this host is in.
  8970      Notice:
  8977      Notice:
  8971         not all systems support this; on some, 'unknown' is returned."
  8978 	not all systems support this; on some, 'unknown' is returned."
  8972 
  8979 
  8973     |domainName|
  8980     |domainName|
  8974 
  8981 
  8975     DomainName notNil ifTrue:[
  8982     DomainName notNil ifTrue:[
  8976         ^ DomainName
  8983 	^ DomainName
  8977     ].
  8984     ].
  8978 
  8985 
  8979     domainName := self primGetComputerName:2.
  8986     domainName := self primGetComputerName:2.
  8980 
  8987 
  8981     domainName isEmptyOrNil ifTrue:[
  8988     domainName isEmptyOrNil ifTrue:[
  8982         domainName := self getEnvironment:'DOMAIN'.
  8989 	domainName := self getEnvironment:'DOMAIN'.
  8983         domainName isNil ifTrue:[
  8990 	domainName isNil ifTrue:[
  8984             domainName := self getEnvironment:'DOMAINNAME'.
  8991 	    domainName := self getEnvironment:'DOMAINNAME'.
  8985         ].
  8992 	].
  8986     ].
  8993     ].
  8987 
  8994 
  8988     domainName isEmptyOrNil ifTrue:[
  8995     domainName isEmptyOrNil ifTrue:[
  8989         ^ 'unknown'.
  8996 	^ 'unknown'.
  8990     ].
  8997     ].
  8991     DomainName := domainName.     "cache only, if it is fixed"
  8998     DomainName := domainName.     "cache only, if it is fixed"
  8992 
  8999 
  8993     ^ domainName
  9000     ^ domainName
  8994 
  9001 
 10295 !
 10302 !
 10296 
 10303 
 10297 primGetComputerName:whatEnum
 10304 primGetComputerName:whatEnum
 10298     "return the domain or hostname we are running on:
 10305     "return the domain or hostname we are running on:
 10299        typedef enum _COMPUTER_NAME_FORMAT {
 10306        typedef enum _COMPUTER_NAME_FORMAT {
 10300           ComputerNameNetBIOS,             // 0
 10307 	  ComputerNameNetBIOS,             // 0
 10301           ComputerNameDnsHostname,         // 1
 10308 	  ComputerNameDnsHostname,         // 1
 10302           ComputerNameDnsDomain,           // 2
 10309 	  ComputerNameDnsDomain,           // 2
 10303           ComputerNameDnsFullyQualified,   // 3
 10310 	  ComputerNameDnsFullyQualified,   // 3
 10304           ComputerNamePhysicalNetBIOS,
 10311 	  ComputerNamePhysicalNetBIOS,
 10305           ComputerNamePhysicalDnsHostname,
 10312 	  ComputerNamePhysicalDnsHostname,
 10306           ComputerNamePhysicalDnsDomain,
 10313 	  ComputerNamePhysicalDnsDomain,
 10307           ComputerNamePhysicalDnsFullyQualified,
 10314 	  ComputerNamePhysicalDnsFullyQualified,
 10308           ComputerNameMax                 // 7
 10315 	  ComputerNameMax                 // 7
 10309         } COMPUTER_NAME_FORMAT; "
 10316 	} COMPUTER_NAME_FORMAT; "
 10310 
 10317 
 10311 %{  /* STACK: 2048 */
 10318 %{  /* STACK: 2048 */
 10312     // Note: GetComputerNameExA can fail in certain locales!
 10319     // Note: GetComputerNameExA can fail in certain locales!
 10313 #if 0 && defined(__MINGW32__)
 10320 #if 0 && defined(__MINGW32__)
 10314     char bufferA[512];
 10321     char bufferA[512];
 10315     DWORD buffSize = sizeof(bufferA);
 10322     DWORD buffSize = sizeof(bufferA);
 10316 
 10323 
 10317     if (GetComputerNameA(bufferA, &buffSize) == TRUE) {
 10324     if (GetComputerNameA(bufferA, &buffSize) == TRUE) {
 10318         RETURN(__MKSTRING_L(bufferA, buffSize));
 10325 	RETURN(__MKSTRING_L(bufferA, buffSize));
 10319     }
 10326     }
 10320 #else
 10327 #else
 10321     WCHAR buffer[512];
 10328     WCHAR buffer[512];
 10322     DWORD buffSize = sizeof(buffer)/sizeof(buffer[0]);
 10329     DWORD buffSize = sizeof(buffer)/sizeof(buffer[0]);
 10323 
 10330 
 10324     if (GetComputerNameExW((COMPUTER_NAME_FORMAT)__intVal(whatEnum), buffer, &buffSize) == TRUE) {
 10331     if (GetComputerNameExW((COMPUTER_NAME_FORMAT)__intVal(whatEnum), buffer, &buffSize) == TRUE) {
 10325         RETURN(__mkStringOrU16String_maxlen(buffer, buffSize));
 10332 	RETURN(__mkStringOrU16String_maxlen(buffer, buffSize));
 10326     }
 10333     }
 10327 #endif
 10334 #endif
 10328 %}.
 10335 %}.
 10329 
 10336 
 10330     "
 10337     "
 10331      0 to: 7 collect:[:i|    
 10338      0 to: 7 collect:[:i|
 10332         OperatingSystem primGetComputerName:i
 10339 	OperatingSystem primGetComputerName:i
 10333      ]
 10340      ]
 10334     "
 10341     "
 10335 
 10342 
 10336     "Modified: / 20-02-2020 / 21:50:38 / stefan"
 10343     "Modified: / 20-02-2020 / 21:50:38 / stefan"
 10337 !
 10344 !
 11399 !
 11406 !
 11400 
 11407 
 11401 dateFormat
 11408 dateFormat
 11402     "Answer the date format string to be used dep. on the OS system value for date format.
 11409     "Answer the date format string to be used dep. on the OS system value for date format.
 11403      One of DfMDY = Month-Day-Year
 11410      One of DfMDY = Month-Day-Year
 11404             DfDMY = Day-Month-Year
 11411 	    DfDMY = Day-Month-Year
 11405             DfYMD = Year-Month-Day
 11412 	    DfYMD = Year-Month-Day
 11406      is mapped to the ST/X dateFormatString %(mon)-%(day)-%(year)"
 11413      is mapped to the ST/X dateFormatString %(mon)-%(day)-%(year)"
 11407 
 11414 
 11408     |separatorString code|
 11415     |separatorString code|
 11409 
 11416 
 11410     separatorString := self dateSeparator.
 11417     separatorString := self dateSeparator.
 11415     code = 2 ifTrue:[ ^ '%(year)', separatorString, '%(mon)', separatorString, '%(day)' ].
 11422     code = 2 ifTrue:[ ^ '%(year)', separatorString, '%(mon)', separatorString, '%(day)' ].
 11416 
 11423 
 11417     ^ '%(day)', separatorString, '%(mon)', separatorString, '%(year)'
 11424     ^ '%(day)', separatorString, '%(mon)', separatorString, '%(year)'
 11418 
 11425 
 11419     "
 11426     "
 11420      self dateFormat 
 11427      self dateFormat
 11421      Date today printStringFormat:(self dateFormat)
 11428      Date today printStringFormat:(self dateFormat)
 11422     "
 11429     "
 11423 
 11430 
 11424     "Modified: / 22-12-2006 / 16:43:30 / User"
 11431     "Modified: / 22-12-2006 / 16:43:30 / User"
 11425     "Modified: / 28-03-2011 / 17:10:01 / cg"
 11432     "Modified: / 28-03-2011 / 17:10:01 / cg"
 11426 !
 11433 !
 11427 
 11434 
 11428 dateFormatCode
 11435 dateFormatCode
 11429     "Answer the current system value for date format.
 11436     "Answer the current system value for date format.
 11430      Answer DfMDY = Month-Day-Year = 0
 11437      Answer DfMDY = Month-Day-Year = 0
 11431             DfDMY = Day-Month-Year = 1
 11438 	    DfDMY = Day-Month-Year = 1
 11432             DfYMD = Year-Month-Day = 2
 11439 	    DfYMD = Year-Month-Day = 2
 11433     "
 11440     "
 11434 
 11441 
 11435     "/ this is somewhat outdated, but windows maps the initProfile query to
 11442     "/ this is somewhat outdated, but windows maps the initProfile query to
 11436     "/ a registry fetch (i.e. in HKEY_CURRENT_USER\Control Panel\International).
 11443     "/ a registry fetch (i.e. in HKEY_CURRENT_USER\Control Panel\International).
 11437     "/ Code should probably be changed to ask there...
 11444     "/ Code should probably be changed to ask there...
 11501     "Created: / 22-12-2006 / 16:48:17 / User"
 11508     "Created: / 22-12-2006 / 16:48:17 / User"
 11502 !
 11509 !
 11503 
 11510 
 11504 language
 11511 language
 11505     "Answer the current system value for country name.
 11512     "Answer the current system value for country name.
 11506      Notice that windows uses a different format (iso 639-2/b ???), 
 11513      Notice that windows uses a different format (iso 639-2/b ???),
 11507      where the first two chars correspond to the standard iso language, 
 11514      where the first two chars correspond to the standard iso language,
 11508      and the 3 third char represents the territory (somehow).
 11515      and the 3 third char represents the territory (somehow).
 11509      US-english which is 'en-us', is in windows ENU,
 11516      US-english which is 'en-us', is in windows ENU,
 11510      GB-english which is 'en-gb', is in windows ENG,
 11517      GB-english which is 'en-gb', is in windows ENG,
 11511      German de-de, de-au, de-ch are DEU, DEA, DES respectively.
 11518      German de-de, de-au, de-ch are DEU, DEA, DES respectively.
 11512      See ISO-3166 Country Codes / ISO-639 Language Codes"
 11519      See ISO-3166 Country Codes / ISO-639 Language Codes"
 11537 queryNationalProfileInt: aKeyName default: defaultValue
 11544 queryNationalProfileInt: aKeyName default: defaultValue
 11538     | answer |
 11545     | answer |
 11539 
 11546 
 11540     answer := self primGetProfileInt: 'Intl' keyName: aKeyName default:(-1 asUnsigned32).
 11547     answer := self primGetProfileInt: 'Intl' keyName: aKeyName default:(-1 asUnsigned32).
 11541     ^ answer = -1 asUnsigned32
 11548     ^ answer = -1 asUnsigned32
 11542         ifTrue: [ defaultValue ]
 11549 	ifTrue: [ defaultValue ]
 11543         ifFalse: [ answer ]
 11550 	ifFalse: [ answer ]
 11544 
 11551 
 11545     "
 11552     "
 11546      self queryNationalProfileInt: 'iDate' default: 0
 11553      self queryNationalProfileInt: 'iDate' default: 0
 11547     "
 11554     "
 11548 
 11555 
 11555      Answer defaultValue if aKeyName cannot be found."
 11562      Answer defaultValue if aKeyName cannot be found."
 11556 
 11563 
 11557     | extString result |
 11564     | extString result |
 11558 
 11565 
 11559     extString := String new: 80.
 11566     extString := String new: 80.
 11560     result := self 
 11567     result := self
 11561                 primGetProfileString:'Intl' keyName:aKeyName default:''
 11568 		primGetProfileString:'Intl' keyName:aKeyName default:''
 11562                 returnedString:extString
 11569 		returnedString:extString
 11563                 size:(extString size).
 11570 		size:(extString size).
 11564     result > 0 ifTrue: [
 11571     result > 0 ifTrue: [
 11565         ^ extString copyFrom: 1 to: result
 11572 	^ extString copyFrom: 1 to: result
 11566     ].
 11573     ].
 11567     ^ defaultValue
 11574     ^ defaultValue
 11568 
 11575 
 11569     "Created: / 22-12-2006 / 16:13:01 / User"
 11576     "Created: / 22-12-2006 / 16:13:01 / User"
 11570 !
 11577 !
 11699 
 11706 
 11700 voiceCommandSpec
 11707 voiceCommandSpec
 11701     "commands to try for speech output"
 11708     "commands to try for speech output"
 11702 
 11709 
 11703     ^ #(
 11710     ^ #(
 11704         "/ triples are:
 11711 	"/ triples are:
 11705         "/      -command
 11712 	"/      -command
 11706         "/      -commandline for default voice
 11713 	"/      -commandline for default voice
 11707         "/      -commandline for specific voice
 11714 	"/      -commandline for specific voice
 11708         "/      -commandline for Speech Synthesis Markup Language (SSML) voice
 11715 	"/      -commandline for Speech Synthesis Markup Language (SSML) voice
 11709         ('powershell'
 11716 	('powershell'
 11710          'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak(''%2'');"'
 11717 	 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak(''%2'');"'
 11711          'powershell -Command "Add-Type -AssemblyName System.Speech; $S=(New-Object System.Speech.Synthesis.SpeechSynthesizer);$S.SelectVoice(''%1'');$S.Speak(''%2'');"'
 11718 	 'powershell -Command "Add-Type -AssemblyName System.Speech; $S=(New-Object System.Speech.Synthesis.SpeechSynthesizer);$S.SelectVoice(''%1'');$S.Speak(''%2'');"'
 11712          'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).SpeakSsml(''%2'');"'
 11719 	 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).SpeakSsml(''%2'');"'
 11713         )
 11720 	)
 11714     )
 11721     )
 11715 
 11722 
 11716     "
 11723     "
 11717      self speak:'hello'
 11724      self speak:'hello'
 11718      self speak:'hallo'
 11725      self speak:'hallo'
 11725     "<<END
 11732     "<<END
 11726      OperatingSystem executeCommand:
 11733      OperatingSystem executeCommand:
 11727 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak(''hello'');"'
 11734 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak(''hello'');"'
 11728 
 11735 
 11729      OperatingSystem
 11736      OperatingSystem
 11730         executeCommand:
 11737 	executeCommand:
 11731 'powershell -Command "Add-Type -AssemblyName System.Speech;$S = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer;$S.voice;"'
 11738 'powershell -Command "Add-Type -AssemblyName System.Speech;$S = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer;$S.voice;"'
 11732         outputTo:Transcript
 11739 	outputTo:Transcript
 11733 
 11740 
 11734      OperatingSystem
 11741      OperatingSystem
 11735         executeCommand:
 11742 	executeCommand:
 11736 'powershell -Command "Add-Type -AssemblyName System.Speech;$S = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer;$S.GetInstalledVoices();"'
 11743 'powershell -Command "Add-Type -AssemblyName System.Speech;$S = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer;$S.GetInstalledVoices();"'
 11737         outputTo:Transcript
 11744 	outputTo:Transcript
 11738 
 11745 
 11739      OperatingSystem
 11746      OperatingSystem
 11740         executeCommand:
 11747 	executeCommand:
 11741 'powershell -Command "Add-Type -AssemblyName System.Speech; foreach ($v in (New-Object System.Speech.Synthesis.SpeechSynthesizer).GetInstalledVoices() ){ Write-Host $v.VoiceInfo.Name }"'
 11748 'powershell -Command "Add-Type -AssemblyName System.Speech; foreach ($v in (New-Object System.Speech.Synthesis.SpeechSynthesizer).GetInstalledVoices() ){ Write-Host $v.VoiceInfo.Name }"'
 11742         outputTo:Transcript
 11749 	outputTo:Transcript
 11743 END"
 11750 END"
 11744 !
 11751 !
 11745 
 11752 
 11746 voiceInfo
 11753 voiceInfo
 11747     "return a list of available (OS-specific) voice names plus info.
 11754     "return a list of available (OS-specific) voice names plus info.
 11748      For each available voice, a triple is returned, containing:
 11755      For each available voice, a triple is returned, containing:
 11749         voiceName language_territory comment/description
 11756 	voiceName language_territory comment/description
 11750 
 11757 
 11751      the language_territory (of the form en_EN / en_US etc.) gives a hint,
 11758      the language_territory (of the form en_EN / en_US etc.) gives a hint,
 11752      for which language the voice is best used.
 11759      for which language the voice is best used.
 11753 
 11760 
 11754      For now, this is experimental and will be enhanced to ask the OS..."
 11761      For now, this is experimental and will be enhanced to ask the OS..."
 11755 
 11762 
 11756     ^ #(
 11763     ^ #(
 11757         ('default'                  'en_US' 'the default system voice')
 11764 	('default'                  'en_US' 'the default system voice')
 11758 
 11765 
 11759         #('Microsoft Zira Desktop'   'en_US' 'Isn''t it nice to have a computer that will talk to you?')
 11766 	#('Microsoft Zira Desktop'   'en_US' 'Isn''t it nice to have a computer that will talk to you?')
 11760         #('Microsoft Hazel Desktop'  'en_GB' 'Isn''t it nice to have a computer that will talk to you?')
 11767 	#('Microsoft Hazel Desktop'  'en_GB' 'Isn''t it nice to have a computer that will talk to you?')
 11761         #('Microsoft Hedda Desktop'  'de_DE' 'Danke, daß Sie mir zuhören')
 11768 	#('Microsoft Hedda Desktop'  'de_DE' 'Danke, daß Sie mir zuhören')
 11762         #('Microsoft Helena Desktop' 'es_ES' 'holla mondo')
 11769 	#('Microsoft Helena Desktop' 'es_ES' 'holla mondo')
 11763         #('Microsoft Irina Desktop'  'ru_RU' 'привет мир')
 11770 	#('Microsoft Irina Desktop'  'ru_RU' 'привет мир')
 11764         #('Microsoft Elsa Desktop'     'it_IT' 'ciao mondo')
 11771 	#('Microsoft Elsa Desktop'     'it_IT' 'ciao mondo')
 11765         #('Microsoft Hortense Desktop' 'fr_FR' 'bonjour monde')
 11772 	#('Microsoft Hortense Desktop' 'fr_FR' 'bonjour monde')
 11766         #('Microsoft Helia Desktop'  'pt_PT' 'olá mundo')
 11773 	#('Microsoft Helia Desktop'  'pt_PT' 'olá mundo')
 11767         #('Microsoft Hanhan Desktop' 'zh_TW' '你好世界')
 11774 	#('Microsoft Hanhan Desktop' 'zh_TW' '你好世界')
 11768         #('Microsoft Tracy Desktop'  'zh_HK' '你好世界')
 11775 	#('Microsoft Tracy Desktop'  'zh_HK' '你好世界')
 11769         #('Microsoft Huihui Desktop' 'zh_CN' '你好世界')
 11776 	#('Microsoft Huihui Desktop' 'zh_CN' '你好世界')
 11770         #('Microsoft Haruka Desktop' 'ja_JP' 'こんにちは世界')
 11777 	#('Microsoft Haruka Desktop' 'ja_JP' 'こんにちは世界')
 11771      )     
 11778      )
 11772 
 11779 
 11773 "<<END
 11780 "<<END
 11774      OperatingSystem voiceInfo
 11781      OperatingSystem voiceInfo
 11775 
 11782 
 11776      OperatingSystem speak:'hallo welt'  voiceName:'Microsoft Hedda Desktop'
 11783      OperatingSystem speak:'hallo welt'  voiceName:'Microsoft Hedda Desktop'
 11783      OperatingSystem speak:'bonjour monde' voiceName:'Microsoft Caroline Desktop'
 11790      OperatingSystem speak:'bonjour monde' voiceName:'Microsoft Caroline Desktop'
 11784      OperatingSystem speak:'bonjour monde' voiceName:'Microsoft Julie Desktop'
 11791      OperatingSystem speak:'bonjour monde' voiceName:'Microsoft Julie Desktop'
 11785      OperatingSystem speak:'ciao mondo' voiceName:'Microsoft Elsa Desktop'
 11792      OperatingSystem speak:'ciao mondo' voiceName:'Microsoft Elsa Desktop'
 11786      OperatingSystem speak:'olá mundo' voiceName:'Microsoft Helia Desktop'
 11793      OperatingSystem speak:'olá mundo' voiceName:'Microsoft Helia Desktop'
 11787      OperatingSystem speak:'привет мир'  voiceName:'Microsoft Irina Desktop'
 11794      OperatingSystem speak:'привет мир'  voiceName:'Microsoft Irina Desktop'
 11788      OperatingSystem speak:'こんにちは世界' voiceName:'Microsoft Haruka Desktop'   "Kon'nichiwa sekai" 
 11795      OperatingSystem speak:'こんにちは世界' voiceName:'Microsoft Haruka Desktop'   "Kon'nichiwa sekai"
 11789      OperatingSystem speak:'你好世界' voiceName:'Microsoft Hanhan Desktop'      "Nǐ hǎo shìjiè"  
 11796      OperatingSystem speak:'你好世界' voiceName:'Microsoft Hanhan Desktop'      "Nǐ hǎo shìjiè"
 11790      OperatingSystem speak:'你好世界' voiceName:'Microsoft Huihui Desktop'      "Nǐ hǎo shìjiè"  
 11797      OperatingSystem speak:'你好世界' voiceName:'Microsoft Huihui Desktop'      "Nǐ hǎo shìjiè"
 11791      OperatingSystem speak:'hello' voiceName:'Microsoft Huihui Desktop'      "Nǐ hǎo shìjiè"  
 11798      OperatingSystem speak:'hello' voiceName:'Microsoft Huihui Desktop'      "Nǐ hǎo shìjiè"
 11792 
 11799 
 11793     Do do:
 11800     Do do:
 11794 
 11801 
 11795      OperatingSystem
 11802      OperatingSystem
 11796         executeCommand:
 11803 	executeCommand:
 11797 'powershell -Command "Add-Type -AssemblyName System.Speech; foreach ($v in (New-Object System.Speech.Synthesis.SpeechSynthesizer).GetInstalledVoices() ){ Write-Host $v.VoiceInfo.Name; Write-Host $v.VoiceInfo.Culture }"'
 11804 'powershell -Command "Add-Type -AssemblyName System.Speech; foreach ($v in (New-Object System.Speech.Synthesis.SpeechSynthesizer).GetInstalledVoices() ){ Write-Host $v.VoiceInfo.Name; Write-Host $v.VoiceInfo.Culture }"'
 11798         outputTo:Transcript
 11805 	outputTo:Transcript
 11799 END 
 11806 END
 11800 ! !
 11807 ! !
 11801 
 11808 
 11802 !Win32OperatingSystem class methodsFor:'system management'!
 11809 !Win32OperatingSystem class methodsFor:'system management'!
 11803 
 11810 
 11804 exitWindows
 11811 exitWindows
 20166 #  define NI_MAXSERV 64
 20173 #  define NI_MAXSERV 64
 20167 # endif
 20174 # endif
 20168 
 20175 
 20169     char host[NI_MAXHOST];
 20176     char host[NI_MAXHOST];
 20170     char service[NI_MAXSERV];
 20177     char service[NI_MAXSERV];
       
 20178     char sockAddrLocal[1024];
 20171     char *hp = NULL, *sp = NULL;
 20179     char *hp = NULL, *sp = NULL;
 20172     int hsz = 0, ssz = 0;
 20180     int hsz = 0, ssz = 0;
 20173     int ret;
 20181     int ret;
 20174     int __flags;
 20182     int __flags;
 20175     char *bp;
 20183     char *bp;
 20194 
 20202 
 20195     nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_ninstvars));
 20203     nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_ninstvars));
 20196     sockAddrSize = __byteArraySize(socketAddress);
 20204     sockAddrSize = __byteArraySize(socketAddress);
 20197     sockAddrSize -= nInstBytes;
 20205     sockAddrSize -= nInstBytes;
 20198 
 20206 
       
 20207     if (sockAddrSize > sizeof(sockAddrLocal)) {
       
 20208 	error = @symbol(badArgument1);
       
 20209 	goto err;
       
 20210     }
       
 20211     bp = (char *)(__byteArrayVal(socketAddress));
       
 20212     bp += nInstBytes;
       
 20213     memcpy(sockAddrLocal, bp, sockAddrSize);
       
 20214 
 20199     if (!__isSmallInteger(flags)) {
 20215     if (!__isSmallInteger(flags)) {
 20200 	error = @symbol(badArgument5);
 20216 	error = @symbol(badArgument5);
 20201 	goto err;
 20217 	goto err;
 20202     }
 20218     }
       
 20219 
 20203     __flags = __intVal(flags);
 20220     __flags = __intVal(flags);
 20204 
 20221 
 20205 #if defined(NI_NUMERICHOST)
 20222 #if defined(NI_NUMERICHOST)
 20206     if (useDatagram == true) {
 20223     if (useDatagram == true) {
 20207 	__flags |= NI_DGRAM;
 20224 	__flags |= NI_DGRAM;
 20212 	bp += nInstBytes;
 20229 	bp += nInstBytes;
 20213 # ifdef DO_WRAP_CALLS
 20230 # ifdef DO_WRAP_CALLS
 20214 	do {
 20231 	do {
 20215 	    __threadErrno = 0;
 20232 	    __threadErrno = 0;
 20216 	    // do not cast to INT - will loose sign bit then!
 20233 	    // do not cast to INT - will loose sign bit then!
 20217 	    ret = (int)(STX_WSA_NOINT_CALL7( "getnameinfo", getnameinfo, (struct sockaddr *)bp, (INT)sockAddrSize, hp, (INT)hsz, sp, (INT)ssz, (INT)__flags));
 20234 	    ret = (int)(STX_WSA_NOINT_CALL7( "getnameinfo", getnameinfo, (struct sockaddr *)sockAddrLocal, (INT)sockAddrSize, hp, (INT)hsz, sp, (INT)ssz, (INT)__flags));
 20218 	} while ((ret < 0) && (__threadErrno == EINTR));
 20235 	} while ((ret < 0) && (__threadErrno == EINTR));
 20219 # else
 20236 # else
 20220 	__BEGIN_INTERRUPTABLE__
 20237 	__BEGIN_INTERRUPTABLE__
 20221 	ret = getnameinfo((struct sockaddr *)bp, sockAddrSize,
 20238 	ret = getnameinfo((struct sockaddr *)sockAddrLocal, sockAddrSize, hp, hsz, sp, ssz, __flags);
 20222 			  hp, hsz, sp, ssz, __flags);
       
 20223 	__END_INTERRUPTABLE__
 20239 	__END_INTERRUPTABLE__
 20224 # endif
 20240 # endif
 20225     } while (ret != 0 && __threadErrno == EINTR);
 20241     } while (ret != 0 && __threadErrno == EINTR);
 20226 
 20242 
 20227     if (ret != 0) {
 20243     if (ret != 0) {