32位OpenFileDialog - > 64位System32?

在32位程序中,如何获取打开/保存文件对话框以显示64位系统的System32文件夹中的文件? (
Wow64DisableWow64FsRedirection
不起作用,因为由于某种原因它不适用于对话框,我猜是因为它在不同的线程上。当然使用
SysNative
不起作用,因为用户不知道发生了什么在内部;他只是想看到计算机上的“实际”文件。) 这是提出问题的另一种方式: 是否有任何32位程序从打开文件对话框中浏览64位
System32
文件夹?     
已邀请:
我相信这根本不可能。 即使您可以获得显示文件的对话框,当它们返回到32位进程时,它们的名称是什么? Sysnative是一个黑客攻击,无论如何在XP 64上都不可用。这只是系统32名称重载的结果。 另一个思想实验。如果可能的话,您需要执行枚举的线程来禁用重定向。由于该线程不受您的控制,因此必须有一个已发布的选项来禁用它。没有。允许您从外部禁用重定向是不合适的,因为当32位进程尝试加载shell扩展时会导致DLL加载失败 - 如果您要加载DLL,则无法禁用重定向,因为您将获得错了 我想如果你想绕过这个限制,你应该写一个64位程序。     
我有一个有效的解决方案。这是一种黑客攻击,但它确实有效。 在我展示解决方案之前的简要免责声明。我大多同意赫弗曼的观点。这并不意味着。我实际上并不建议这样做以运送代码。这是没有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)。我不想假设在我的DLL之前加载实现Wow64Disable的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*.*";
    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
。     

要回复问题请先登录注册