SHFileOperation函数

cg 2000-11-06 07:20:00
我填写了这个函数中需要的结构的所有参数,但它说文件系统操作失败,不知道什么原因,其中需要的窗口句柄用当前的句柄行吗?
...全文
238 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
老魏2006 2000-11-07
  • 打赏
  • 举报
回复
哈哈,你的From和To有问题,这两个字符串都应该是两个0结尾,中间以一个0分割,不是标准的字符串。
你用过文件对话框的filter没有?跟他的道理是一样的。api有很多使使用这些字符串,
应该这样,在结束的时候,应该多增加一个0:
fileop.pFrom = "d:\\temp\\*.tmp\0";
fileop.pTo = "c:\\temp\\\0";
dingsg 2000-11-07
  • 打赏
  • 举报
回复
The following sample console application illustrates the use of SHFileOperation to copy files from one directory to another. The source and destination directories, C:\My_Docs and C:\My_Docs2, are hard-coded into the application for simplicity.

#include <shlobj.h>
#include <shlwapi.h>

main()
{
IShellFolder *psfDeskTop = NULL;
IShellFolder *psfDocFiles = NULL;
IMalloc *pMalloc = NULL;
LPITEMIDLIST pidlDocFiles = NULL;
LPITEMIDLIST pidlItems = NULL;
IEnumIDList *ppenum = NULL;
SHFILEOPSTRUCT sfo;
STRRET strDispName;
TCHAR szParseName[MAX_PATH];
TCHAR szSourceFiles[256];
int i;
int iBufPos = 0;
ULONG chEaten;
ULONG celtFetched;
HRESULT hr;

pzSourceFiles[0] = '\0';
hr = SHGetMalloc(&pMalloc);
hr = SHGetDesktopFolder(&psfDeskTop);

hr = psfDeskTop->ParseDisplayName(NULL, NULL, L"c:\\My_Docs",
&chEaten, &pidlDocFiles, NULL);
hr = psfDeskTop->BindToObject(pidlDocFiles, NULL, IID_IShellFolder,
(LPVOID *) &psfDocFiles);
hr = psfDeskTop->Release();

hr = psfDocFiles->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
&ppenum);

while( (hr = ppenum->Next(1,&pidlItems, &celtFetched)) == S_OK
&& (celtFetched) == 1)
{
psfDocFiles->GetDisplayNameOf(pidlItems, SHGDN_FORPARSING,
&strDispName);
StrRetToBuf(&strDispName, pidlItems, szParseName, MAX_PATH);
for(i=0;i<=lstrlen(szParseName); i++)
{
szSourceFiles[iBufPos++] = szParseName[i];
}
pMalloc->Free(pidlItems);
}
ppenum->Release();

szSourceFiles[iBufPos] = '\0';

sfo.hwnd = NULL;
sfo.wFunc = FO_COPY;
sfo.pFrom = szSourceFiles;
sfo.pTo = "c:\\My_Docs2\0";
sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;

hr = SHFileOperation(&sfo);

SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, (LPCVOID) "c:\My_Docs2", 0);

pMalloc->Free(pidlDocFiles);
psfDocFiles->Release();

return 0;
}

cg 2000-11-07
  • 打赏
  • 举报
回复
谢谢大家,我用的是CFileDialog(open)时获得的源文件全路径,CFileDialog(save as)中获得目标文件全路径,源文件路径和目标文件路径是一致的,只是文件名不一样,先用了FireAngel的方法是可行的(显示地手写文件名和路径),但用自己获得的源文件名时还是总是说文件系统有错误。目标文件不换,换了个源文件倒是可以的,很奇怪。等明天再在文件名字符串后加个0试试。
xiaozuo 2000-11-06
  • 打赏
  • 举报
回复
用当前的句柄应该没有问题吧。只是你的结构参数中,文件的属性和你的操作是不是有矛盾?假如是在NT中的话,更要注意权限问题。
土豆 2000-11-06
  • 打赏
  • 举报
回复
我觉得应该比较简单嘛,我的例子:

#include <shellapi.h>

SHFILEOPSTRUCT fileop;
fileop.hwnd = hWnd;
fileop.wFunc = FO_COPY;
fileop.pFrom = "d:\\temp\\*.tmp";
fileop.pTo = "c:\\temp\\";
fileop.fFlags = FOF_SILENT and FOF_NOCONFIRMATION;
if (SHFileOperation(&fileop) != 0)
{ // Fail }

窗口句柄当然是当前窗口的。
你可以将你的代码贴出来看看。另外,不知你的fFlags有没有问题。
VB拦截Windows Explorer删除进程,内含API HOOK,源代码:倒霉蛋儿,程序有时候也会窗口勾挂失败!   勾住了SHFileOperation函数,DLL用Delphi写的C会的太少,查了半天才知道原来explorer是用SHFileOperation删除文件,经过测试很稳定,没有出现崩溃的情况,由于只勾住了SHFileOperation函数,所以别的程序要是调用DeleteFile删除文件,拦截不到,要是想拦截DeleteFile自己接着写吧。      mod_Inject.bas类的注释摘录:   Dim MyAddr As Long ‘执行远程线程代码的起始地址。这里等于LoadLibraryA的地址   ‘dll文件路径   MyDllFileLength = LenB(StrConv(MyDllFileName, vbFromUnicode)) + 1    ‘这里把dll文件名从Unicode转换成Ansi,否则英文字母是2个字节。 _   顺便说一下,学过C的应该知道字符串要以/0标志结尾,所以dll文件名长度要加上1个字节存放Chr(0)   ‘得到进程的句柄   在目标进程中申请分配一块空白内存区域。内存的起始地址保存在MyDllFileBuffer中。 _   这块内存区域我们用来存放dll文件路径,并作为参数传递给LoadLibraryA。   在分配出来的内存区域中写入dll路径径。注意第二个参数传递的是MyDllFileBuffer的内容, _   而不是MyDllFileBuffer的内存地址?   If MyReturn = 0 Then Inject = False   MyAddr = GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA")   ‘得到LoadLibraryA函数的起始地址。他的参数就是我们刚才写入的dll路径。但是LoadLibraryA本身是不知道参数在哪里的。 _   接下来我们就用CreateRemoteThread函数告诉他参数放在哪里了? If MyAddr = 0 Then Inject = False   MyResult = CreateRemoteThread(ProcessHandle, 0, 0, MyAddr, MyDllFileBuffer, 0, 0)   好了,现在用CreateRemoteThread在目标进程创建一个线程,线程起始地址指向LoadLibraryA, _   参数就是MyDllFileBuffer中保存的dll路径?    If MyResult = 0 Then    Inject = False    Else    Inject = True    End If    ‘接下来你可以使用WaitForSingleObject等待线程执行完毕。 _    并用GetExitCodeThread得到线程的退出代码,用来判断时候正确执行了dll中的代码。    CloseHandle MyResult    CloseHandle ProcessHandle    ‘扫地工作   End Function

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧