I guess my question is this - How would I get the directory of the exe location as an LPCWSTR so that I can input it into my code
#include <iostream>
#include <Windows.h>
int main(int argc, char **argv)
{
WIN32_FIND_DATA a;
HANDLE swap = FindFirstFile(/*(LPCWSTR)__exe_directory__*/,&a);
if (swap!=INVALID_HANDLE_VALUE)
{
do
{
char *sptn = new char [lstrlen(a.cFileName)+1];
for (int c=0;c<lstrlen(a.cFileName);c++)
{
sptn[c]=char(a.cFileName[c]);
}
sptn[lstrlen(a.cFileName)]='\0';
std::cout<<sptn<<std::endl;
}
while (FindNextFile(swap,&a));
}
else std::cout<<"undetected file\n";
FindClose(swap);
system("pause");
}
And it would return the listed files in the directory without error. I know for a fact that my code already works given the directory, I tested it already.
The key is to use GetModuleFileName()
(passing nullptr
as module handle, to refer to current process EXE), and then call PathRemoveFileSpec()
(or PathCchRemoveFileSpec()
, if you don't care about Windows versions prior to Windows 8) to strip the file spec from the path.
To use PathRemoveFileSpec()
you must link with Shlwapi.lib, as stated in MSDN documentation.
See this compilable code as an example:
#include <iostream> // For console output
#include <exception> // For std::exception
#include <stdexcept> // For std::runtime_error
#include <string> // For std::wstring
#include <Windows.h> // For Win32 SDK
#include <Shlwapi.h> // For PathRemoveFileSpec()
#pragma comment(lib, "Shlwapi.lib")
// Represents an error in a call to a Win32 API.
class win32_error : public std::runtime_error
{
public:
win32_error(const char * msg, DWORD error)
: std::runtime_error(msg)
, _error(error)
{ }
DWORD error() const
{
return _error;
}
private:
DWORD _error;
};
// Returns the path without the filename for current process EXE.
std::wstring GetPathOfExe()
{
// Get filename with full path for current process EXE
wchar_t filename[MAX_PATH];
DWORD result = ::GetModuleFileName(
nullptr, // retrieve path of current process .EXE
filename,
_countof(filename)
);
if (result == 0)
{
// Error
const DWORD error = ::GetLastError();
throw win32_error("Error in getting module filename.",
error);
}
// Remove the file spec from the full path
::PathRemoveFileSpec(filename);
return filename;
}
int main()
{
try
{
std::wcout << "Path for current EXE:\n"
<< GetPathOfExe()
<< std::endl;
}
catch (const win32_error & e)
{
std::cerr << "\n*** ERROR: " << e.what()
<< " (error code: " << e.error() << ")"
<< std::endl;
}
catch (const std::exception& e)
{
std::cerr << "\n*** ERROR: " << e.what() << std::endl;
}
}
In console:
C:\Temp\CppTests>cl /EHsc /W4 /nologo /DUNICODE /D_UNICODE get_exe_path.cpp get_exe_path.cpp C:\Temp\CppTests>get_exe_path.exe Path for current EXE: C:\Temp\CppTests
PS
In your code, you seem to refer to the Unicode version of FindFirtFile()
(i.e. FindFirstFileW()
, since in the comment you expect a LPCWSTR
, i.e. const wchar_t*
), but then in the following code you use ANSI/MBCS strings (i.e. char*
).
I'd suggest you to always use Unicode UTF-16 wchar_t*
strings in modern Windows C++ code: it's better for internationalization, and modern Win32 APIs only come with a Unicode version.
Note also that, since you are using C++, it's better to use a robust convenient string class (e.g. std::wstring
for Unicode UTF-16 strings with Microsoft Visual C++), instead of C-like raw character pointers. Use the raw pointers at the API interface (since the Win32 API has a C interface), and then safely convert to a std::wstring
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With