How to get list of folders in this folder?
FindFirstFileEx+FindExSearchLimitToDirectories.
WIN32_FIND_DATA fi;
HANDLE h = FindFirstFileEx(
dir,
FindExInfoStandard,
&fi,
FindExSearchLimitToDirectories,
NULL,
0);
if (h != INVALID_HANDLE_VALUE) {
do {
if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
printf("%s\n", fi.cFileName);
} while (FindNextFile(h, &fi));
FindClose(h);
}
If you can't use .NET & Managed code, you can go through the win32 api's
Here is an example that you can modify to only get Folders.
(Basically the following check:)
...
TCHAR szDir = _T("c:\\"); // or wherever.
HANDLE hFind = FindFirstFile(szDir, &ffd);
...
do {
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// your code on 'ffd'
}
} while (FindNextFile(hFind, &ffd) != 0);
You can use Boost
Or, if you don't want Boost you can check out this thread where alternative options are discussed.
http://www.gamedev.net/community/forums/topic.asp?topic_id=523375
For best portability, use the boost filesystem library. Use opendir()/readdir() and friends for UNIX based systems.
Related
My goal is to only use built in methods of C++/Windows (I don't think std::filesystem is supported on my version of C++) to get the filenames within a folder.
right now I have this:
HANDLE hFind;
WIN32_FIND_DATA data;
hFind = FindFirstFile("C:\\Folder\\*", &data);
if (hFind != INVALID_HANDLE_VALUE) {
do {
//Process File Name
std::wstring ws(data.cFileName);
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
Which seems to be returning blank names and not the names of the files in the folder.
Am I using this FindFirstFile function correctly? Is there a better way to do this?
Your code can't compile as shown. You are calling the ANSI version of FindFirstFile() (by virtue of you passing it a narrow ANSI string literal instead of a wide Unicode string literal), and std::wstring does not have a constructor that accepts a char[] as input.
Baring that mistake, you are also ignoring the data.dwFileAttributes field to distinguish between files and subfolders, and in the case of subfolders you are not checking the contents of data.cFileName to ignore the "." and ".." special folder names.
Try this:
WIN32_FIND_DATAW data;
HANDLE hFind = FindFirstFileW(L"C:\\Folder\\*", &data);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
// Process File Name
std::wstring ws(data.cFileName);
...
}
else
{
if ((lstrcmpW(data.cFileName, L".") != 0) &&
(lstrcmpW(data.cFileName, L"..") != 0))
{
// Process Folder Name
std::wstring ws(data.cFileName);
...
}
}
}
while (FindNextFileW(hFind, &data));
FindClose(hFind);
}
I'm trying to find list of files in a directory programmatically and I've written the following code
CStringArray CCL2ProjectDirectoryPage::GetAllFilesNames()
{
WIN32_FIND_DATA fileData;
memset(&fileData, 0, sizeof(WIN32_FIND_DATA));
HANDLE handle = FindFirstFile("d:\\test\\*", &fileData);
CStringArray strArray;
while(handle != INVALID_HANDLE_VALUE)
{
strArray.Add(fileData.cFileName); // the problem is that the fileData.cFileName always contains "."
if(FALSE == FindNextFile(handle, &fileData))
break;
}
FindClose(handle);
return strArray;
}
The problem is that the fileData.cFileName always contains ".".
"." with the first file, ".." with the second file and so on.
what is wrong with this code?
Thanks in advance.
Your code uses just Win32 API to traverse directory/folder. The MFC way of doing this is much simpler. The framework comes with CFileFind which is much easier to use. Also you can not return CStringArray as it does not have copy constructor. You should be using CStringArray reference as out param of your method
void CCL2ProjectDirectoryPage::GetAllFilesNames(CStringArray& files)
{
CFileFind finder;
// start working for files
BOOL bWorking = finder.FindFile(_T("d:\\test\\*"));
while (bWorking)
{
bWorking = finder.FindNextFile();
// skip . and .. files
if (!finder.IsDots())
{
files.Add(finder.GetFileName());
}
}
}
You want this:
CStringArray GetAllFilesNames()
{
WIN32_FIND_DATA fileData;
memset(&fileData, 0, sizeof(WIN32_FIND_DATA));
HANDLE handle = FindFirstFile("d:\\test\\*", &fileData);
CStringArray strArray;
if (handle != INVALID_HANDLE_VALUE)
{
do
{
if (_tcscmp(fileData.cFileName, _T(".")) != 0 && // ignore "." and ".."
_tcscmp(fileData.cFileName, _T("..")) != 0)
{
strArray.Add(fileData.cFileName);
}
} while (FindNextFile(handle, &fileData));
FindClose(handle);
}
return strArray;
}
Disclaimer: this is untested and minimal error checking code just for demonstration purposes.
I'm writing an app in Qt and trying to use the windows functions FindFirstFile and FindNextFile in order to speed up counting large numbers of files in several directories. I've copied this code almost verbatum off the microsoft site in order to list files, but debugging it shows that it's only listing one file when I trigger the function;
QStringList Manager::returnDirectoryFileData(QString ChangedDirectory)
{
QStringList DirectoryFiles;
WIN32_FIND_DATA FindFileData;
LARGE_INTEGER filesize;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError = 0;
//string directorySearch = "E:\\My Documents\\Visual Studio 2010\\Projects\\SEP-Asignment-One\\Debug\\*";
// Find the first file in the directory.
LPCWSTR ConvertedDir = (const wchar_t*)ChangedDirectory.utf16();
PVOID OldValue = NULL;
if (Wow64DisableWow64FsRedirection(&OldValue))
{
hFind = FindFirstFile(ConvertedDir, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf("Invalid file handle. Error is %u.\n", GetLastError());
}
do
{
QString Newname = "Want to do stuff here";
DirectoryFiles.append(Newname);
printf(" %s <DIR>\n", FindFileData.cFileName);
} while (FindNextFile(hFind, &FindFileData) != 0);
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
DisplayErrorBox(TEXT("FindFirstFile"));
}
FindClose(hFind);
}
Wow64RevertWow64FsRedirection(&OldValue);
return DirectoryFiles;
}
This is a 32 bit program running on 64 bit windows 10, so the Wow64DisableWow64fsredirection is supposed to be called before these functions are used. Anyone know what I'm doing wrong? Thanks!
My aim is to list the textfiles in a specific directory and let the user load one of the files.
I'm using Windows, Unicode is predefined in my compiler.
Question: FileHandle has always INVALID_HANDLE_VALUE. What's the cause of this and how can I correct it?
My last code looks like this:
ListAllTxtFiles(L"C:\\Users\\Tnc\Desktop\\Yazılım Çalışmaları\\Projects\\Oyun Projem\\data\\SaveFiles\\");
void ListAllTxtFiles(const wchar_t *Directory)
{
TCHAR Buffer[2048];
wsprintf(Buffer, L"s%*.txt", Directory);//there are security considerations about this function
WIN32_FIND_DATAW FindData;
HANDLE FileHandle = FindFirstFileW(Buffer, &FindData);
if (FileHandle == INVALID_HANDLE_VALUE)
{
printf("Could not find any files..\n");
}
else
{
do
{
printf("Found %s\\%s\n", Directory, FindData.cFileName);
} while (FindNextFile(FileHandle, &FindData));
CloseHandle(FileHandle);
}
}
wsprintf(Buffer, L"s%*.txt", Directory);
should be
wsprintf(Buffer, L"%s*.txt", Directory);
You just got your wsprintf format string wrong.
I have a C++ DLL that i am writing that needs to check if a particular process is running.
the dll will be launched application will be running in:
c:\Directory\application.exe
there is a subdirectory within that that has another executable in it:
c:\Directory\SubDirectory\application2.exe
What the DLL needs to do when it runs if check that application2.exe is running, most importantly that it is running within that folder -- there will be multiple copies running, so we need to ensure that the correct one is running.
I have the following code that is working well at detecting that the application2.exe is running, but it does not take the file path into consideration:
HANDLE pss = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(pe);
if (Process32First(pss, &pe))
{
do
{
if(wcscmp(pe.szExeFile, L"application2.exe") == 0)
{
CloseHandle(pss);
return (1);
}
}
while(Process32Next(pss, &pe));
}
CloseHandle(pss);
How can I check that the path of the process matches the path of the application which called the DLL?
Use WMI for this.
From the command line you can do:
wmic process where "executablepath = 'c:\path\to\executable.exe'" get ProcessId
You can use the WMI apis from C++ to do something similar.
http://www.codeproject.com/Articles/10539/Making-WMI-Queries-In-C
I have been given a solution that works for this, in case anyone else searching here it is:
HANDLE ProcessSnap;
PROCESSENTRY32 Pe32;
unsigned int LoopCounter = 0;
Pe32.dwSize = sizeof(PROCESSENTRY32);
ProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
Process32First(ProcessSnap, &Pe32);
wchar_t TermPath[MAX_PATH];
GetModuleFileName(NULL, TermPath, MAX_PATH);
wstring WTermPath(TermPath);
int index = WTermPath.find(L"\\application.exe");
wstring Path = WTermPath.substr(0, (index));
Path = Path + L"\\SubDirectory\\Application2.exe";
do
{
HANDLE Process;
wchar_t FilePath[MAX_PATH];
Process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, Pe32.th32ProcessID);
if (Process)
{
GetModuleFileNameEx(Process, 0, FilePath, MAX_PATH);
wstring WFilePath(FilePath);
if(WFilePath == Path)
{
CloseHandle(ProcessSnap);
return (1);
}
CloseHandle(Process);
}
LoopCounter++;
} while (Process32Next(ProcessSnap, &Pe32));
CloseHandle(ProcessSnap);