How to delete folder into recycle bin - c++

I am programing under C++, MFC, windows.
I want to delete a folder into recycle bin.
How can I do this?
CString filePath = directorytoBeDeletePath;
TCHAR ToBuf[MAX_PATH + 10];
TCHAR FromBuf[MAX_PATH + 10];
ZeroMemory(ToBuf, sizeof(ToBuf));
ZeroMemory(FromBuf, sizeof(FromBuf));
lstrcpy(FromBuf, filePath);
SHFILEOPSTRUCT FileOp;
FileOp.hwnd = NULL
FileOp.wFunc=FO_DELETE;
FileOp.pFrom=FromBuf;
FileOp.pTo = NULL;
FileOp.fFlags=FOF_ALLOWUNDO|FOF_NOCONFIRMATION;
FileOp.hNameMappings=NULL;
bRet=SHFileOperation(&FileOp);
Any thing wrong with the code above?
It always failed.
I found the problem:
filePath should be : "c:\abc" not "c:\abc\"

The return value from SHFileOperation is an int, and should specify the error code. What do you get?

i know it is not the right way but if you cant find a solution you can try this..
download file nircmd.exe or another exe that can empty recycle bin.
then you call these functions by system("nircmd.exe emptybin")

You have found a solution that works, however it's only by accident. The actual problem here is that the pFrom parameter is in a special format. According to the MSDN docs for SHFILEOPTS, it stores a list of file paths, each one null-terminated, and an extra null after the last one.
In your case this happens to work because the FromBuf array is longer than the filename and all the entries are initialised to zero. The more general solution is to create a buffer that is long enough for the filename and then add two nul characters after it. Note that Windows filenames can be longer than _MAX_PATH, eg see https://learn.microsoft.com/en-us/windows/desktop/fileio/naming-a-file#maximum-path-length-limitation

Related

CFileDialog::GetNextPathName return a truncated path if it is too long [duplicate]

Using CFileDialog class, I select multiple files placed in a directory with a long path. It's OK when I select only one or two files; but when I select three files at the same time it returns only a part of the third file path. (Looks like it's limited to 512 characters possibly) How can I resolve this?
MFC uses a default buffer of size _MAX_PATH and that's why you are seeing that behavior. Look at dlgfile.cpp for the implementation of CFileDialog::CFileDialog and you will see m_ofn.lpstrFile and m_ofn.nMaxFile being set.
You can specify a larger buffer if you want to. Before calling DoModal you can either access the CFileDialog::m_pOFN member to get a pointer to the OPENFILENAME that the CFileDialog will use and update it directly or call CFileDialog::GetOFN to get a reference to the structure and update that.
Either way you will find this helpful: http://msdn.microsoft.com/en-US/library/ms646839(v=vs.80).aspx
Assuming that your code looks something like this:
CFileDialog dialog(...);
dialog.DoModal();
Determine the maximum number of files that you wish to support, for example:
#define MAX_FILE_NAMES 256
Add this before calling DoModal:
CString data;
dialog.m_pOFN->nMaxFile = (MAX_FILE_NAMES*(MAX_PATH+1))+1;
dialog.m_pOFN->lpstrFile = data.GetBuffer((MAX_FILE_NAMES*(MAX_PATH+1))+1);
Add this after calling DoModal:
data.ReleaseBuffer();

Why CFileDialog::GetNextPathName doesn't work when the file path is long?

Using CFileDialog class, I select multiple files placed in a directory with a long path. It's OK when I select only one or two files; but when I select three files at the same time it returns only a part of the third file path. (Looks like it's limited to 512 characters possibly) How can I resolve this?
MFC uses a default buffer of size _MAX_PATH and that's why you are seeing that behavior. Look at dlgfile.cpp for the implementation of CFileDialog::CFileDialog and you will see m_ofn.lpstrFile and m_ofn.nMaxFile being set.
You can specify a larger buffer if you want to. Before calling DoModal you can either access the CFileDialog::m_pOFN member to get a pointer to the OPENFILENAME that the CFileDialog will use and update it directly or call CFileDialog::GetOFN to get a reference to the structure and update that.
Either way you will find this helpful: http://msdn.microsoft.com/en-US/library/ms646839(v=vs.80).aspx
Assuming that your code looks something like this:
CFileDialog dialog(...);
dialog.DoModal();
Determine the maximum number of files that you wish to support, for example:
#define MAX_FILE_NAMES 256
Add this before calling DoModal:
CString data;
dialog.m_pOFN->nMaxFile = (MAX_FILE_NAMES*(MAX_PATH+1))+1;
dialog.m_pOFN->lpstrFile = data.GetBuffer((MAX_FILE_NAMES*(MAX_PATH+1))+1);
Add this after calling DoModal:
data.ReleaseBuffer();

Deleting registry keys - error in MSDN sample

This MSDN article is supposed to demonstrate how to delete a registry key which has subkeys, but the code is flawed.
The line that says
StringCchCopy (lpEnd, MAX_PATH*2, szName);
causes an exception, which is due to trying to copy to beyond the buffer of lpEnd. I tried correcting the solution by replacing that line with the following
size_t subKeyLen = lstrlen(lpSubKey);
size_t bufLen = subKeyLen + lstrlen(szName)+1;
LPTSTR buf = new WCHAR[bufLen];
StringCchCopy(buf,bufLen,lpSubKey);
StringCchCopy(buf+subKeyLen,lstrlen(szName)+1,szName);
buf[bufLen-1]='\0';
I'm unable to step through the code as the target platform and dev platform are different, but from the logging I've put in the code it looks like it just freezes up, but doesn't throw an exception.
It's frustrating that MSDN articles are wrong...you'd think they would be checked.
Any ideas on how to correct this?
Thanks.
If you don't mind having Shlwapi.dll as an additional dependency, it may be easier for you just to use SHDeleteKey. If you're only targetting Vista+, RegDeleteTree (which lives in Advapi32.dll) is another alternative.
That change by itself would not be sufficient. The line of code following it:
if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
break;
would also need to change. lpSubKey would need to be replaced with buf since that now contains the full key.
And it probably goes without saying, but be sure to free (delete) buf as part of the cleanup.
However, for correctness, it seems as if it would be better just to fix the original line of code by changing it to pass the correct length (which should be okay since I believe the maximum key length in the registry is 255):
StringCchCopy (lpEnd, MAX_PATH*2 - lstrlen(lpSubKey), szName);

How to get the path of the exexuter in C++?

I am using Visual studio 2008 and I want to get the absolute path of the .exe file?
meaning when the user opens the exe file, I need to know its absolute path??
thanks in advance
Under Windows try the following:
char ExeName[8192]; // or what ever max. size you expect.
if (0 != GetModuleFileName (NULL, ExeName, sizeof (ExeName)))
{
printf ("Your array was probably not large enough. Call GetLastError for details\n");
}
If you compile for unicode use wchar_t.
Using the _pgmptr or _wpgmptr global variable is probably the easiest way.* (They're in stdlib.h.)
*Note: Under some rather rare circumstances, it's possible that this won't work... in that case, use GetModuleFileName(NULL, ...);
If you want to obtain a path of the current process, you should use API function:
GetModuleFileName
But, if you want to obtain a full path of the process that is not written by you, use
GetModuleFileNameEx
Above function expects one argument more than GetModuleFileName - it is a HANDLE of a process which path is supposed to be obtained. It is explained in more details on MSDN.

image subdirectory in c++

Basically, I was hoping to sort of keep my files sorted instead of having them all in the same folder as my executable, but referencing files in sub folders relative to my executable has proven difficult.
// DEFINES
#define IMAGE_BACKGROUND "\\content\\images\\background.bmp"
#define FONT_MAIN "\\content\\fonts\\sai.ttf"
The above code obviously does not work.
I read supposedly args[0] is somehow my path? Anyone care to elaborate a little more?
int main(int argc, char* args[])
{
I should mention that Boost.Filesystem is a nice library that can help you out.
args[0] is the full path name (well, but that is also decided by the OS and shell, so you may get a short file name which is not full) to your "executable file", not its folder. you must truncate it.
try splitpath and joinpath.
args[0] is the name used to call your executable, which is not necessarily the full path of your executable. You're interested in the working directory of your executable, which is OS-dependent.
In any case, you have to be careful with relative paths. If your user calls your program from a different directory, your working directory may be something unexpected, and you won't properly reference your files.
Since you're in Windows, you can use the GetModuleFileName function (see the documentation) to get the full name of your executable, like so:
GetModuleFileName(NULL, buffer, length);
Have you tryed doing:
#define IMAGE_BACKGROUND "\content\images\background.bmp"
That might be the problem (as i have used images from sub folders like that before)
This code should work:
#define IMAGE_BACKGROUND "\\content\\images\\background.bmp"
int main(int argc, char* args[])
{
char buf[512];
int endOfPath = strrchr(args[0], '\\') - args[0];
strncpy_s(buf, sizeof(buf), args[0], endOfPath);
strcat(buf, IMAGE_BACKGROUND);
Like the other person said, args[0] is the full path of the executeble, so you can't use that as is. The strrchr function (TWO r's in the middle) finds the last occurrence of a given character and returns a pointer to it. Assuming that you are using one-byte characters, subtracting args[0] from the returned pointer will give you the number of characters between the two pointers -- When you subtract two pointers, your actually subtracting the memory addresses, so what you're left with is an offset, or distance between the pointers. This distance is like the index of the character that was found.
I then use the strncpy_s function to copy endOfPath number of characters from args[0] to our temporary buffer. Now, if your program path was
"C:\Windows\Users\Me\Desktop\myProgram\theProgram.exe"
the buf variable will contain
"C:\Windows\Users\Me\Desktop\myProgram"
I then used the strcat (conCATenation) function to append your constant onto the end.
Note that with your #define, the "\\" is REQUIRED in C/C++, and also note that the " marks will be included where ever you use IMAGE_BACKGROUND.
After those lines of code, buf will contain:
"C:\Windows\Users\Me\Desktop\myProgram\content\images\background.bmp"
Hope that helps and is not too confusing...
I actually solved it by using the following code, thank you all for the responses:
// DEFINES
#define IMAGE_BACKGROUND ".\\content\\images\\background.png"
#define IMAGE_BLUEBLOCK ".\\content\\images\\blueblock.png"
#define FONT_MAIN ".\\content\\fonts\\sai.ttf"
Turns out the . gets the "working path directory".