Windows 程式常需處理命令列參數:使用者在「執行」對話框、捷徑屬性、或拖曳檔案到程式圖示時,檔案路徑會作為參數傳遞給程式。本文提供一個健全的 MASM 函式 GetFileNameFromCommandLine,能正確解析帶引號、含空白、或無參數等各種情況。
GetCommandLine 回傳的字串格式:
GetCommandLine 取得指標 ESI。",直讀至下一個 "。",複製至緩衝區直到下一個 "。0,回傳緩衝區位址;失敗則回傳 NULL。.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include masm32.inc
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
.data
szCaption db "GetCommandLine",0
.data?
FileName db 256 dup(?)
.code
GetFileNameFromCommandLine PROTO :LPSTR
start:
invoke GetFileNameFromCommandLine, addr FileName
.if eax != NULL
invoke MessageBox, NULL, eax, addr szCaption, MB_OK
.endif
invoke ExitProcess, NULL
; 回傳:EAX = 檔案名緩衝區位址,或 NULL
GetFileNameFromCommandLine proc uses esi edi, lpString:LPSTR
mov edi, lpString
invoke GetCommandLine
mov esi, eax
xor eax, eax
cld
; 略過程式路徑
G1: lodsb
cmp al, '"'
jnz G3
G2: lodsb
cmp al, '"'
jnz G2
G3: lodsb
cmp al, ' '
jnz G3
; 略過分隔空白
G4: lodsb
cmp al, 0
jz G7
cmp al, ' '
jz G4
cmp al, 9
jz G4
; 處理檔案名
cmp al, '"'
jnz G5
stosb
G4p: lodsb
stosb
cmp al, '"'
jnz G4p
jmp G6
G5: stosb
lodsb
cmp al, 0
jz G6
cmp al, ' '
jz G6
cmp al, 9
jnz G5
G6: xor al, al
stosb
mov eax, lpString
G7: ret
GetFileNameFromCommandLine endp
end start
D:\KZ_Z>GetFileName "\My documents\pop.exe"
D:\KZ_Z>GetFileName Cala.exe
實際專案中,建議先嘗試 GetFileNameFromCommandLine,若回傳 NULL 再彈出 GetOpenFileName 對話框讓使用者手動選擇,提供最佳使用者體驗。