我对此有一个工作解决方案。这是一种黑客,但它的工作原理。
在我展示解决方案之前的简短声明。我主要同意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