Re: [問題] 呼叫外部執行檔 無法開啟中文檔案
雖然 Windows sucks
不過這問題不知道該算在 windows 頭上還是 Python 2.x subprocess module 頭上
以前 Python 2.x 的時候想叫檔案總管顯示某個檔案
用 subprocess.call,也是遇到某些日文字就掛掉,很不方便
去找原因 (以下是記憶,時間久遠,可能記錯或根本搞錯,請多包涵)
是因為 Windows API 分兩種,ANSI 和 Unicode
比如說 GetWindowText,實際上會呼叫 GetWindowTextA 或 GetWindowTextW
想要用 unicode 當輸入或是想得到 unicode 輸出,當然該用 Unicode版本的 API
可是 Python 2.x 的 subprocess module 很阿呆
不管輸入啥,全部給你 ANSI 版本的 API,這結果當然會出問題
所以最後直接呼叫 Unicode 版本的 Windows API,別用 subprocess
就可以讓檔案總管顯示日文檔案了
code 如下:
from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFUNCTYPE, byref, c_wchar_p
from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPWSTR, UINT, WORD
LPVOID = c_void_p
LPBYTE = POINTER(BYTE)
LPDWORD = POINTER(DWORD)
class PROCESS_INFORMATION(Structure):
_fields_ = [("hProcess", HANDLE),
("hThread", HANDLE),
("dwProcessID", DWORD),
("dwThreadID", DWORD)]
def __init__(self):
Structure.__init__(self)
self.cb = sizeof(self)
class STARTUPINFO(Structure):
_fields_ = [("cb", DWORD),
("lpReserved", LPWSTR),
("lpDesktop", LPWSTR),
("lpTitle", LPWSTR),
("dwX", DWORD),
("dwY", DWORD),
("dwXSize", DWORD),
("dwYSize", DWORD),
("dwXCountChars", DWORD),
("dwYCountChars", DWORD),
("dwFillAttribute", DWORD),
("dwFlags", DWORD),
("wShowWindow", WORD),
("cbReserved2", WORD),
("lpReserved2", LPBYTE),
("hStdInput", HANDLE),
("hStdOutput", HANDLE),
("hStdError", HANDLE)]
NORMAL_PRIORITY_CLASS = 0x00000020
pi = PROCESS_INFORMATION()
si = STARTUPINFO()
cmd = u' /select,"{0}"'.format('c:\\a.txt')
r1 = windll.kernel32.CreateProcessW(c_wchar_p(u'c:\\windows\\explorer.exe'), c_wchar_p(cmd), None, None, False, NORMAL_PRIORITY_CLASS, None, None, byref(si), byref(pi))
r2 = windll.kernel32.CloseHandle(pi.hProcess)
r3 = windll.kernel32.CloseHandle(pi.hThread)
python 3.x 的 subprocess module,照大大的說法,似乎沒這種問題了
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.46.158.11
→
12/06 14:38, , 1F
12/06 14:38, 1F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):