我尝试使用IShellItem将文件从IFileOperation COM接口从系统目录复制到另一个目录。为此,我必须使用完全相同的IFileOperation COM接口。
当我指定完整文件名时 - SHCreateItemFromParsingName()
的返回值为ERROR_FILE_NOT_FOUND
,但文件存在于目录中。当我从下面的路径中删除文件名并仅使用文件夹路径时 - 一切似乎都很好,返回值为S_OK
。
//...
CoInitialize(NULL);
//...
WCHAR szSourceDll[MAX_PATH * 2];
wcscpy_s(szSourceDll, MAX_PATH, L"C:\\Windows\\System32\\sysprep\\cryptbase.dll");
r = CoCreateInstance(&CLSID_FileOperation, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER, &IID_IFileOperation, &FileOperation1);
if (r != S_OK) return;
FileOperation1->lpVtbl->SetOperationFlags(FileOperation1, FOF_NOCONFIRMATION | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION);
r = SHCreateItemFromParsingName(szSourceDll, NULL, &IID_IShellItem, &isrc);
//...
CoUninitialize();
//...
为什么用C
编写的代码不能使用文件名。如何为系统文件夹中的文件创建IShellItem
实例进行复制?
P.S。
Windows 7 x64,C,Visual Studio 2015,v140平台工具集,其他依赖项: Msi.lib; Wuguid.lib; ole32.lib; ntdll.lib
P.P.S
它可以正常使用用户目录中的文件......
答案 0 :(得分:3)
假设您的应用程序被编译为32位应用程序并在64位操作系统上运行,则找不到文件错误可能是正确的,因为您的应用程序被重定向到32位系统目录(%WinDir%\SysWoW64
)
在大多数情况下,只要32位应用程序尝试访问%windir%\ System32,%windir%\ lastgood \ system32或%windir%\ regedit.exe,就会将访问权限重定向到特定于体系结构的路径。
有关详细信息,请参阅MSDN上的File System Redirector。
你可以暂时关闭你的线程中的重定向但是在调用shell函数时这样做是不安全的,只在kernel32中执行。如果您在内部调用的API使用LoadLibrary
和/或COM,则API可能会失败,因为在禁用重定向时无法从system32加载。
您还可以使用%WinDir%\SysNative
后门访问本机system32目录。这仅适用于64位Vista +上的32位应用程序,因此您必须进行一些版本检测。