作者os653 (allstar)
看板Python
标题Re: [问题] 呼叫外部执行档 无法开启中文档案
时间Thu Dec 6 14:25:27 2012
虽然 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
1F:→ uranusjr:因为 3.x 底层全改写成 unicode 了; 2.x 确实是这样没错 12/06 14:38