核心编程随笔3 分类: VC++ 2013-09-28 08:43 487人阅读 评论(0) 收藏
Note 1:
一个线程可以调用以下两个函数来获取和设置其进程的当前驱动器和目录:
DWORD GetCurrentDirectory(
DWORD cchCurDir,
PTSTR pszCurDir);
BOOL SetCurrentDirectory(PCTSTR pszCurDir);
注意
WinDef.h文件中被定义为260的常量MAX_PATH是目录名称或文件名称的最大字符数.所以在调用GetCurrentDirectory的时候,向该函数传递由MAX_PATH个TCHAR类型的元素构成的一个缓冲区是非常安全的.
Note 2:
系统跟踪记录着进程的当前驱动器和目录,但它没有记录每个驱动器的当前目录.不过,利用操作系统提供的支持,可以处理多个驱动器的当前目录.这个支持是通过进程的环境字符串来提供的.
可以使用C运行库函数_chdir而不是WindowsSetCurrentDirectory函数来更改当前目录._chdir函数在内部调用SetCurrentDirectory,但_chdir还可以调用SetEnvironmentVariable来添加或修改环境变量,从而使不同驱动器的当前目录得以保留.
Note 3:
可以通过调用GetFullPathName来获得进程的当前目录:
DWORD GetFullPathName(
PCTSTR pszFile,
DWORD cchPath,
PTSTR pszPath,
PTSTR *ppszFilePart);
例如,要想获得C驱动器的当前目录,可以像下面这样调用GetFullPathName:
TCHAR szCurDir[MAX_PATH];
DWORD cchLength = GetFullPathName(TEXT("C:"), MAX_PATH, szCurDir, NULL);
Note 4:
CreateProcess试图修改字符串时,会引起一个访问冲突(MicrosoftC/C++编译器的早期版本把字符串放在可读/写内存中。所以对CreateProcess函数的调用不会引起访问冲突).
解决这个问题的最佳方式是:在调用CreateProcess之前.把常量字符串复制到一个临时缓冲区.如下所示:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR szCommandLine[] = TEXT("NOTEPAD");
CreateProcess(NULL, szCommandLine, NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);
还可以使用Microsoft C++的/Gf和/GF编译器开关.它们可以消除重复的字符串,以及判断那些字符串是否放在一个只读区域.(还要注意/ZI开关,它允许使用Visual Studio的Edit & Continue调试功能,它包含了/GF开关的功能.)最佳做法是使用/GF编译器开关和一个临时缓冲区.
Note 5:
应用程序运行期间,必须关闭到子进程及其主线程的句柄,以避免资源泄漏.当然,系统会在你的进程终止后自动清理这种泄漏.但是,如果是一个编写精妙的软件,肯定会在进程不再需要访问一个子进程及其主线程的时候,显式地调用CloseHandle来关闭这些句柄.忘记关闭这些句柄是开发人员最容易犯的错误之一.
不知道为什么,许多开发人员都有这样的一个误解:关闭到一个进程或线程的句柄,会强迫系统杀死此进程或线程.但这是大谬不然的.关闭句柄只是告诉系统你对进程或线程的统计数据不再感兴趣了.进程或线程会继续执行,直至自行终止.
Note 6:
通过调用GetExitCodeProcess来获得已经死亡的一个进程的退出代码:
BOOL GetExitCodeProcess(
HANDLE hProcess,
PDWORD pdwExitCode);
Note 7:
Windows提供了几种方式在不同进程之间传递数据,其中包括动态数据交换(Dynamic Data Exchange,DDE),OLE,pipes,mailslots等等.共享数据最方便的方式之一就是使用内存映射文件.
Note 8:
如果你希望创建一个新线程,让它执行一些工作,然后等候结果,可以像下面这样编码:
PROCESS_INFORMATION pi;
DWORD dwExitCode;
// Spawn the child process.
BOOL fSuccess = CreateProcess(..., &pi);
if (fSuccess) {
// Close the thread handle as soon as it is no longer needed!
CloseHandle(pi.hThread);
// Suspend our execution until the child has terminated.
WaitForSingleObject(pi.hProcess, INFINITE);
// The child process terminated; get its exit code.
GetExitCodeProcess(pi.hProcess, &dwExitCode);
// Close the process handle as soon as it is no longer needed.
CloseHandle(pi.hProcess);
}
Note 9:
下代码示例展示了如何新建一个进程,然后让它分离出去运行:
PROCESS_INFORMATION pi;
// Spawn the child process.
BOOL fSuccess = CreateProcess(..., &pi);
if (fSuccess) {
// Allow the system to destroy the process & thread kernel
// objects as soon as the child process terminates.
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
Note 10:
为什么Windows Vista不是只问一次,然后把安全数据保存到系统中,并让用户随意以管理员的身份来运行应用程序呢?这样一来,就不必每次都弹出一个UAC对话框来打扰用户了.Windows Vista不提供这个功能,因为否则的话,它就必须将数据保存到某个地方(比如保存到注册表中或者其他某个文件中).一旦这个存储区域被成功入侵,恶意程序就可以修改这个存储,使它总是以提升的权限来运行,而不会向用户进行任何提示.
Note 11:
在一段视频和一份Microsoft Office PowerPoint演示文稿中(网址为http://www.microsoft.com/emea/spotlight/sessionh.aspx?videoid=360),Mark
Russinovich详细介绍了UAC的内部机制,比如Windows的系统资源虚拟化技术,它使那些在设计时没有考虑到新的Administator权限限制的应用程序能够更好地兼容新的操作系统.
版权声明:本文为博主原创文章,未经博主允许不得转载。