Windows API
跳转到导航
跳转到搜索
此条目在于指出 Windows API 中需要特别注意的地方,以及一些代码示例。
进程相关
CreateProcess
该函数的第一个参数指明可执行文件。如果是相对路径,“the function uses the current drive and current directory to complete the specification. The function will not use the search path”[1]。“If the file name does not contain an extension, .exe is assumed.”“If the file name does not contain a directory path, the system searches for the executable file in the following sequence:”
- The directory from which the application loaded.
- The current directory for the parent process.
- The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.
也就是说,在不指定路径的情况下,系统目录下的程序享有优先权,而 PATH 环境变量在其次。
文件系统
文件变动通知
使用 Python ctypes 监视指定目录中的文件/目录的写操作。主要使用了 ReadDirectoryChangesW [2]API。
#!/usr/bin/env python3
import struct
import ctypes
kernel32 = ctypes.windll.kernel32
class FileWatcher:
def __init__(self, path):
self.d_hdl = kernel32.CreateFileW(
path,
1 | 0x80000000, # FILE_LIST_DIRECTORY | GENERIC_READ
7, # FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE
0, # NULL
3, # OPEN_EXISTING
128 | 0x02000000, # FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS
0, # NULL
)
self.bufsize = 4096
self.buf = ctypes.create_string_buffer(b'\0' * (self.bufsize-1))
# DWORD is unsigned long http://stackoverflow.com/a/39430/296473
self.datalen = ctypes.c_ulong()
def read(self):
ret = kernel32.ReadDirectoryChangesW(
self.d_hdl,
self.buf,
self.bufsize,
0, # not bWatchSubtree
# FILE_NOTIFY_CHANGE_LAST_WRITE
# This happens when a write is performed (to a file or directory)
0x00000010,
ctypes.byref(self.datalen),
0,
0,
)
if ret == 0:
raise RuntimeError('ReadDirectoryChangesW failed')
p = 0
buf = self.buf.raw
ret = []
while True:
namestart = p + 12
offset, action, filenamelen = struct.unpack('=LLL', buf[p:namestart])
ret.append(buf[namestart:namestart+filenamelen].decode('utf-16le'))
if offset == 0:
break
p += offset
return ret
def __del__(self):
kernel32.CloseHandle(self.d_hdl)
if __name__ == '__main__':
w = FileWatcher(r'd:\test')
while True:
print(w.read())
图形相关
LoadImage
只接受 BMP 图像。
参见
外部链接
- theForger's Win32 API Tutorial(有英文版和中文版)
- One of my favorite error codes: Optional parameter missing - The Old New Thing - Site Home - MSDN Blogs
参考资料
- ↑ MSDN: ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dllproc/base/createprocess.htm
- ↑ ReadDirectoryChangesW function (Windows)