Using SHFileOperation.
-
I keep getting an error message telling me that the file cannot be found UNLESS I hard-code the name of the file to work on (in this case delete). Here's the code:
SHFILEOPSTRUCT fileOp;
CString sSrc; //this is actually declared and set earlier
fileOp.hwnd = this->m_hWnd;
sSrc = pItem->sCol4; //pointer to a STRUCT containing CStrings
fileOp.pFrom = (LPCSTR)sSrc; //Source path+name
fileOp.pTo = "\0"; //Unhandled exception if I don't set this
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
fileOp.wFunc = FO_DELETE;
int iRes = SHFileOperation(&fileOp);It seems apparent that the problem is in the conversion from the CString to LPCSTR for fileOp.pFrom. It works fine if I replace the line "fileOp.pFrom...." with
fileOp.pFrom = "C:\\Dummy.txt";
The strings look correct in the debugger window, so I'm at a loss here. I've tried various different castings and even tried using sSrc.GetBuffer(n) where n is various different values. None of those things seems to make a difference. So what's the snag? Any suggestions?
-
I keep getting an error message telling me that the file cannot be found UNLESS I hard-code the name of the file to work on (in this case delete). Here's the code:
SHFILEOPSTRUCT fileOp;
CString sSrc; //this is actually declared and set earlier
fileOp.hwnd = this->m_hWnd;
sSrc = pItem->sCol4; //pointer to a STRUCT containing CStrings
fileOp.pFrom = (LPCSTR)sSrc; //Source path+name
fileOp.pTo = "\0"; //Unhandled exception if I don't set this
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
fileOp.wFunc = FO_DELETE;
int iRes = SHFileOperation(&fileOp);It seems apparent that the problem is in the conversion from the CString to LPCSTR for fileOp.pFrom. It works fine if I replace the line "fileOp.pFrom...." with
fileOp.pFrom = "C:\\Dummy.txt";
The strings look correct in the debugger window, so I'm at a loss here. I've tried various different castings and even tried using sSrc.GetBuffer(n) where n is various different values. None of those things seems to make a difference. So what's the snag? Any suggestions?
pFrom must be a double-null-terminated string. It is actually the Win32 version of a string list - one null-terminated string after the other, with two nulls to mark the end. The version where you set pFrom to a string literal just happens to work, even though the correct literal is "c:\\dummy.txt\0". You'll need to set up a character buffer (not a CString because CString does not handle embedded nulls) and use that for pTo. --Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm
-
pFrom must be a double-null-terminated string. It is actually the Win32 version of a string list - one null-terminated string after the other, with two nulls to mark the end. The version where you set pFrom to a string literal just happens to work, even though the correct literal is "c:\\dummy.txt\0". You'll need to set up a character buffer (not a CString because CString does not handle embedded nulls) and use that for pTo. --Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm
I had noticed in the documentation that .pFrom (and .pTo) had to be double-null terminated, but I did not realize that CStrings would not handle the nulls. Thanks. Oh, BTW, it worked with "c:\\Dummy.txt", "c:\\Dummy.txt\0", and "c:\\Dummy.txt\0\0". However, I confess that I'm lame where string manipulation is concerned. I've fiddled with it and still can't get it to work. Here's what I've got:
fileOp.hwnd = this->m_hWnd;
sSrc = pItem->sCol4;
char szSrc[255]; //my buffer for the string
strcpy(szSrc, (LPCTSTR)sSrc); //this works fine
int iSize = strlen(szSrc); //len appears OK
strcat(szSrc, "\0\0"); //append double nulls
iSize = strlen(szSrc); //debugger says len is same (?)
fileOp.pFrom = szSrc;
fileOp.pTo = "\0\0";
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
fileOp.wFunc = FO_DELETE;
SHFileOperation(&fileOp);Ugh! I'm clearly missing something rather fundamental. Thanks.
-
I had noticed in the documentation that .pFrom (and .pTo) had to be double-null terminated, but I did not realize that CStrings would not handle the nulls. Thanks. Oh, BTW, it worked with "c:\\Dummy.txt", "c:\\Dummy.txt\0", and "c:\\Dummy.txt\0\0". However, I confess that I'm lame where string manipulation is concerned. I've fiddled with it and still can't get it to work. Here's what I've got:
fileOp.hwnd = this->m_hWnd;
sSrc = pItem->sCol4;
char szSrc[255]; //my buffer for the string
strcpy(szSrc, (LPCTSTR)sSrc); //this works fine
int iSize = strlen(szSrc); //len appears OK
strcat(szSrc, "\0\0"); //append double nulls
iSize = strlen(szSrc); //debugger says len is same (?)
fileOp.pFrom = szSrc;
fileOp.pTo = "\0\0";
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
fileOp.wFunc = FO_DELETE;
SHFileOperation(&fileOp);Ugh! I'm clearly missing something rather fundamental. Thanks.
strcat(szSrc, "\0\0");
has no effect. Watch the szSrc array in the memory watch window and you'll see. None of the C string functions work with embedded nulls, because the first null ends the string. What I do is zero-fill the array so no matter how long the actual file name is, there will be zeros after it.char szSrc[MAX_PATH+1] = {0};
--Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm -
strcat(szSrc, "\0\0");
has no effect. Watch the szSrc array in the memory watch window and you'll see. None of the C string functions work with embedded nulls, because the first null ends the string. What I do is zero-fill the array so no matter how long the actual file name is, there will be zeros after it.char szSrc[MAX_PATH+1] = {0};
--Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_HelmYeah, I noticed that the strcat(szSrc, "\0\0") did nothing. Thanks for the suggestion (zero filling the array) -- it worked like a charm. I just don't think I would have ever thought of it. BTW, I've enjoyed your articles. Keep up the excellent work and thanks a bunch.