2008年12月26日

Get Windows Information in REBOL 2.x

寫了一段REBOL 2.x程式, 可以用來進行許多OS相關的判斷.

Kernel32.DLL: load/library %Kernel32.dll

MultiByteToWideChar: make routine! [
CodePage [ int ] ; 65001 for UTF-8
Flags [ int ]
MultiByteStr [ char* ]
MultiByteLen [ int ]
WideCharStr [ char* ]
WideCharLen [ int ]
return: [ int ]
] Kernel32.DLL "MultiByteToWideChar"

User-profile: dirize to-rebol-file get-env "Userprofile"

make-sure-c-string: func [ str [ string! ] ] [
if #"^@" <> last str [ append str #"^@" ]
]

get-wide-str: func [ str [string!] /local tmp ans ] [
make-sure-c-string str
insert/dup tmp: copy "" #" " 2 * length? str
MultiByteToWideChar 65001 0 str -1 tmp length? tmp
ans: copy/part tmp any [
attempt [ skip find tmp "^@^@^@" 3 ]
attempt [ skip find tmp "^@^@" 2 ]
tail tmp
]
]

GetWindowsDirectory: make routine! [
Buffer [ char* ]
Size [ int ]
return: [ int ]
] Kernel32.DLL "GetWindowsDirectoryA"

insert/dup buffer: copy "" #" " 200

GetWindowsDirectory buffer length? buffer
OS-drive: rejoin [ %/ copy/part buffer find buffer ":\" "/" ]

make-elements: func [name count type /local result][
if not word? type [type: type?/word type]
result: copy "^/"
repeat i count [
append result join name [i " [" type "]" newline]
]
to block! result
]

OS-VERSION-INFO-EX: make struct! OS-VERSION-INFO-EX-SPEC: compose/deep [
OSVersionInfoSize [ int ]
MajorVersion [ int ]
MinorVersion [ int ]
BuildNumber [ int ]
PlatformId [ int ]
(make-elements 'ch 128 #"@")
ServicePackMajor [ short ]
ServicePackMinor [ short ]
SuiteMask [ short ]
ProductType [ char ]
Reserved [ char ]
] none

OS-VERSION-INFO-EX/OSVersionInfoSize: 148 + 8

GetVersionEx: make routine! [
VersionInfo [ struct! [ (OS-VERSION-INFO-EX-SPEC) ]]
return: [ integer! ]
] Kernel32.dll "GetVersionExA"

GetSystemDefaultLCID: make routine! [
return: [ integer! ]
] Kernel32.dll "GetSystemDefaultLCID"

GetLastError: make routine! [
return: [ int ]
] Kernel32.DLL "GetLastError"

if zero? GetVersionEx OS-VERSION-INFO-EX [
alert rejoin [ {Error When Calling "GetVersionEx". Error Code =} GetLastError ]
exit
]

os-ver: rejoin [OS-VERSION-INFO-EX/MajorVersion "." OS-VERSION-INFO-EX/MinorVersion]
;SP?: OS-VERSION-INFO-EX/ServicePackMajor

sp: to-string copy/part at third OS-VERSION-INFO-EX 21 128
sp: copy/part sp find sp #"^@"

Win-Vista?: Win-2003?: Win-XP?: Win-2000?: false
OS?: switch/default os-ver [
"6.0" [ Win-Vista?: true "Win-Vista"]
"5.2" [ Win-2003?: true "Win-2003" ]
"5.1" [ Win-XP?: true "Win-XP" ]
"5.0" [ Win-2000?: true "Win-2000" ]
] [ none ]

SP0?: SP1?: SP2?: SP3?: SP4?: false

sp?: switch sp [
"" [ SP0?: true 0 ]
"Service Pack 1" [ SP1?: true 1 ]
"Service Pack 2" [ SP2?: true 2 ]
"Service Pack 3" [ SP3?: true 3 ]
]

HOME-Ed?: not zero? (OS-VERSION-INFO-EX/SuiteMask and 512)
EMBEDDED-Ed?: not zero? (OS-VERSION-INFO-EX/SuiteMask and 64)

zh-TW?: zh-CN?: zh-HK?: zh-MO?: zh-SG?: ja-JP?: ko-KR?: vi-VN?: th-TH?: false

lang?: switch/default skip to-hex GetSystemDefaultLCID 4 [
#0404 [
zh-TW?: true "zh-TW"
]
#0804 [
zh-CN?: true "zh-CN"
]
#0c04 [
zh-HK?: true "zh-HK"
]
#1404 [
zh-MO?: true "zh-MO"
]
#1004 [
zh-SG?: true "zh-SG"
]
#0411 [
ja-JP?: true "ja-JP"
]
#0412 [
ko-KR?: true "ko-KR"
]
#042a [
vi-VN?: true "vi-VN"
]
#041e [
th-TH?: true "th-TH"
]
] [ none ]

2 則留言:

匿名 提到...

http://msdn.microsoft.com/zh-tw/library/dd252674.aspx

第一段代码说明中有误,希望可以更正:

「string -> int * int」意思是:需要一個字串(string)當參數,沒有傳出值。

匿名 提到...

忘了说声感谢,你写的F#教学非常好,希望可以写更多关于F#的指导文章。