[英]32-bit OpenFileDialog --> 64-bit System32?
在32位程序中,如何獲取“打開/保存文件”對話框以顯示64位系統的System32文件夾中的文件?
( Wow64DisableWow64FsRedirection
不起作用,因為出於某種原因它不適用於對話框,我猜測是因為它在不同的線程上。當然,使用SysNative
也不起作用,因為用戶不知道會發生什么內部;他只想查看計算機上的“實際”文件。)
這是提出問題的另一種方法:
是否有任何 32位程序從打開文件對話框中瀏覽64位System32
文件夾?
我相信這根本不可能。
即使您可以使用對話框來顯示文件,將文件返回到32位進程時它們的名稱是什么? Sysnative有點麻煩,無論如何在XP 64上都不可用。這只是重載system32名稱的結果。
另一個思想實驗。 如果有可能,您將需要執行枚舉的線程來禁用重定向。 由於該線程不在您的控制范圍內,因此必須有一個已發布的選項將其禁用。 沒有。 不允許您從外部禁用重定向是沒有好處的,因為當32位進程嘗試加載Shell擴展時,這將導致DLL加載失敗-如果要加載DLL,則無法禁用重定向,因為您將獲得錯誤的
我想如果您想解決這個限制,就應該編寫一個64位程序。
我對此有一個可行的解決方案。 這是一種hack,但可以。
在顯示解決方案之前,請提供簡短的免責聲明。 我大多同意赫弗曼的觀點。 並非如此。 實際上,我不建議這樣做來發送代碼。 沒有32位文本編輯器,文字處理器(包括32位Office)或普通應用程序支持的內容。 64位系統上的普通用戶不會直接在系統目錄中打開或保存文件。 而且,大多數非管理員用戶無論如何都沒有適當的權限可以在其中觸摸文件。 Microsoft非常有理由使用32位應用程序重定向文件系統。 不要試圖與之抗爭。
現在開始解決。
訣竅是在DllMain中為每個DLL_THREAD_ATTACH回調都進行DLL調用Wow64DisableWow64FsRedirection。
首先創建一個僅具有DllMain的簡單DLL,並導出幾個函數:“ 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(對於當前線程)。
我特意做了一個“啟動”功能,以便在掛鈎實際開始處理線程之前加載所有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);
}
這是安裝程序的常見問題。 人們希望為32位和64位系統提供一個安裝程序可執行文件,這意味着它必須是32位。 但是32位安裝程序無法將64位可執行文件放在正確的位置。 正如雷蒙德·陳(Raymond Chen ) 所描述的,該解決方案是擁有一個單獨的64位安裝程序,該安裝程序將由64位計算機上的32位版本調用。
您將創建一個64位程序,其任務是打開一個以應用程序窗口為所有者的通用對話框。 在64位系統上,您只需創建打開對話框的過程,然后將要傳遞給GetOpenFileName
或其他參數的參數傳遞給該對話框。 您可以在stdout上監聽文件名或使用其他IPC機制。 打開返回的文件時,請記住使用Wow64DisableWow64FsRedirection
! 在另一個進程中運行UI似乎很笨拙,但對用戶而言是無縫的,許多Web瀏覽器在不同進程中運行不同的選項卡或插件。
如果您適合使用Vista或更高版本,則可以使用IFileDialog
接口,該接口允許您為SysNative
目錄添加“位置”。 這樣,用戶仍然可以根據需要訪問文件。 甚至可能有一種簡單的方法來重定向事物,以便當有人單擊System32
目錄時,您將其帶到SysNative
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.