閱讀125 返回首頁    go 京東網上商城


核心編程隨筆3

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演示文稿中(網址為https://www.microsoft.com/emea/spotlight/sessionh.aspx?videoid=360),Mark Russinovich詳細介紹了UAC的內部機製,比如Windows的係統資源虛擬化技術,它使那些在設計時沒有考慮到新的Administator權限限製的應用程序能夠更好地兼容新的操作係統.

最後更新:2017-04-03 15:22:09

  上一篇:go 核心編程6——線程
  下一篇:go URAL 1043 三角形外接圓