64位Windows文件打开
我正在尝试使用对话框来打开程序中的文件。这在 32 位系统上完美运行,但是当我尝试在 64 位系统上使用它时,它无法打开该文件。我发现如果尝试打开的文件与我的程序位于同一目录中,则它可以正常工作。但是,尝试从另一个文件夹打开文件根本不起作用。
因此,我尝试将文件复制到程序文件夹中。这在 32 位系统上也可以正常工作,但在 64 位系统上根本不起作用。有什么想法吗?
char cwdl[500];
getcwd(cwdl,500);
string mystring = string(cwdl);
CFileDialog fileDlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "All Files (*.*)|*.*||", this);
fileDlg.m_ofn.lpstrTitle = "Select New File";
if( fileDlg.DoModal() == IDOK)
{
CString newFile= fileDlg.GetFileName();
mystring+="\\"+newFile;
const char * newLoc = mystring.c_str();
CopyFile(newFile,newLoc,true);
这只是代码片段。
I'm trying to use a dialog box to open a file in my program. This works perfectly on a 32 bit system, but when I try to use it on 64 bit it is unable to open the file. I've figured out that if the file trying to be opened is in the same directory as my program, it works fine. Trying to open a file from another folder, however, doesn't work at all.
So, I tried to copy the file to the program folder. This also works fine on 32 bit but doesn't work at all on a 64 system. Any thoughts why?
char cwdl[500];
getcwd(cwdl,500);
string mystring = string(cwdl);
CFileDialog fileDlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "All Files (*.*)|*.*||", this);
fileDlg.m_ofn.lpstrTitle = "Select New File";
if( fileDlg.DoModal() == IDOK)
{
CString newFile= fileDlg.GetFileName();
mystring+="\\"+newFile;
const char * newLoc = mystring.c_str();
CopyFile(newFile,newLoc,true);
this is just a snippet of the code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
UAC 和文件系统重定向既相关又不同。
用户帐户控制是基于权限的安全性,可防止未经授权的用户更改您的文件系统或执行可能影响其他用户的应用程序。该提示允许您通过临时提供管理员权限来覆盖安全性(如果这是您的意图)。
文件系统重定向是为了通过镜像 32 位系统文件夹和注册表来向后兼容 32 位应用程序。事实上,如果导致 UAC 启动重定向的操作没有发生,那么在这种情况下它将始终尝试使用该文件的 64 位版本。除非您明确指定重定向目录或以管理员权限运行32位应用程序来绕过UAC。
好吧,这就是说您正在使用相对路径,因此它将在当前目录中查找该进程的文件。如果它被编译为 32 位进程,则由于上述重定向,在具有不同体系结构的系统上运行它可能不会按预期运行。
您可以使用 GetCurrentDirectory Windows API 来查看当前进程正在使用哪个目录并验证它是否是您所期望的。如果没有,你有几个选择。
CFileDialog
并通过在构造函数中调用Wow64DisableWow64FsRedirection
和在析构函数中调用Wow64RevertWow64FsRedirection
来禁用重定向。然而,这是一个系统设置,因此您可能会因在 64 位 Windows 上强制使用 32 位应用程序而遇到新问题。可能还有很多其他选择,因为通常有很多方法可以给猫剥皮。然而,第一步是放置一些调试代码,并使用
GetCurrentDirectory
验证或消除重定向作为罪魁祸首UAC and file system redirection are related yet different.
User account control is a permissions based security to prevent unauthorized users from changing your file system or executing applications which may affect other users. The prompt allows you to override the security by providing administrator privileges temporarily if that was your intent.
File system redirection is to allow backwards compatibility with 32bit applications by having a mirrored 32bit system folders and registry. In fact if the action causes UAC to kick in redirection does not occur it will always try to use the 64bit version of the file in that case. Unless you specify the redirection directory explicitly or run the 32bit application with administrator privileges to bypass UAC.
Ok that said you are using a relative path so it will look for the file in the current directory for the process. If it's compiled as 32 bit process running it on systems with different architectures may not behave as expected due to aforementioned redirection.
You can use GetCurrentDirectory windows API to see what directory the current process is using and verify it is what you expected. If not you have a few options.
CFileDialog
and disable redirection by callingWow64DisableWow64FsRedirection
in the constructor andWow64RevertWow64FsRedirection
in the desctructor. However this is meant to be a system setting so you may get new problems by forcing your 32bit application on 64bit windows.There are probably plenty of other options as well since there is usually many ways to skin a cat. However the first step is to put some debug code in place and verify or eliminate redirection as a culprit with
GetCurrentDirectory
也许只有我这么认为,但我看到了一个奇怪的结果:在 64 位模式下,用于存储路径位置的缓冲区的前四个字节用零填充。
返回值 OTOH 是正确的。 “ret”指向wk + 4;
在 32 位模式下,没有前导零,路径从第一个字节开始。注意:这是一个多字节应用程序,而不是 Unicode。
我使用的是 Visual Studio 2010 (10.0.40219.1 SP1Rel)。
无论如何,如果您得到相同的结果,那就可以解释为什么您的示例不起作用。您可能会说(仅限 64 位模式):
奇怪还是什么?
编辑:似乎是对齐问题。如果 _getcwd 位于单独的函数中,则工作正常。
Maybe it's just me, but I'm seeing a strange result: in 64-bit mode, the first four bytes of the buffer used to store the location of the path, are filled with zeros.
The return value OTOH is correct. "ret" points to wk + 4;
In 32-bit mode, there are no leading zeros, the path starts at the first byte. Note: this is a Multi-byte app, not Unicode.
I'm using Visual Studio 2010 (10.0.40219.1 SP1Rel).
Anyway, if you're getting the same result, that would explain why your example doesn't work. You would have to say (in 64-bit mode only):
Weird or What?
Edit: Seems to be an alignment problem. Works OK if the _getcwd is in a separate function.