我對此有一個工作解決方案。這是一種黑客,但它的工作原理。
在我展示解決方案之前的簡短聲明。我主要同意Hefferman。這並不意味着。我實際上並不推薦這樣做的代碼。這是沒有32位文本編輯器,文字處理器(包括32位Office),或正常的應用程序支持。 64位系統上的普通用戶不直接在系統目錄中打開或保存文件。而且,大多數非管理員用戶無論如何都無權觸摸文件。微軟重新定向文件系統的原因非常好,適用於32位應用程序。不要試圖與它戰鬥。
現在解決方案。
訣竅是在DllMain中爲每個DLL_THREAD_ATTACH回調調用Wow64DisableWow64FsRedirection。
首先創建一個簡單的DLL,它只有一個DllMain並導出一些函數:「StartDisableRedirect」和「DisableRedirection」。
bool g_fDisableRedirect = false;
__declspec(dllexport)
int DisableRedirection()
{
void* pVoid = NULL;
Wow64DisableWow64FsRedirection(&pVoid);
return 0;
}
__declspec(dllexport)
int StartDisableRedirect()
{
g_fDisableRedirect = true;
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
{
void* pVoid = NULL;
if (g_fDisableRedirect)
{
DisableRedirection();
}
break;
}
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
讓您的二進制文件(EXE或DLL)直接與此DLL鏈接。然後,在調用GetOpenFileName之前,調用StartDisableRedirect(使後續線程不重定向)和DisableRedirect(用於當前線程)。
我故意做了一個「Start」函數,使得所有的DLL(包括系統DLL)都在鉤子實際開始處理線程之前被加載。我不想假設實現Wow64Disable的DLL會在我的DLL之前加載。從DllMain調用代碼時,必須非常小心(閱讀:不應該)。
extern int StartDisableRedirect();
extern int DisableRedirection();
void OnFile(HWND hwndParent)
{
StartDisableRedirect();
DisableRedirection();
OPENFILENAME ofn = {};
WCHAR szFile[MAX_PATH*2] = {};
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwndParent;
ofn.lpstrFilter = L"All Files\0*.*\0\0";
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = ARRAYSIZE(szFile);
ofn.Flags = OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
::GetOpenFileName(&ofn);
}
當你想在system32文件夾中顯示文件時,不應該在對話框中設置正確的初始文件夾嗎? – GolezTrol 2011-03-09 06:48:49
@GolezTrol:這是一個文本編輯器(以及我製作的類似類型的應用程序),其中*我*不會對用戶選擇的內容有任何偏好,但是如果他想要在'System32'中選擇一些東西,然後他不能。無論如何,這不是一個真正的解決方案,但只是一個解決方法,並不真正起作用。 (謝謝你的建議。) – Mehrdad 2011-03-09 06:50:29
如果你使用C#,爲什麼不爲'AnyCPU編譯而不用擔心呢? – Gabe 2011-03-09 08:32:28