I try to open existing file via CreateFile, but it is always failing with errorcode 2 - like file doesn't exist, but it exists - it's in folder with executable.
hFile = CreateFile( argv[ 1 ], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if ( hFile == INVALID_HANDLE_VALUE )
{
printf( "\nError: Unable to open file (%d)\n", GetLastError( ) );
return -1;
}
it fails even if I replace argv[1] with hardcoded filename string.
app is running as an admin.
The error code is accurate. The file cannot be found. Possible explanations include:
If you wish to interpret the file name as being relative to the directory in which the executable resides then do that. Form an absolute path from the directory containing the executable and the specified file name.
There is no reason to expect a process working directory to be the directory in which the executable resides.
You are attempting to open a file using a relative pathname. Relative pathnames are relative to the current working directory (see GetCurrentDirectory). The current working directory is not necessarily the directory, where the executable image resides. It can be different for a number of reasons, for example:
If you want to open a file located relative to the application's executable image, you need to construct a fully qualified pathname, based on the executable's location and the desired filename. The following code retrieves the executable's directory1):
#include <windows.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
#include <string>
#include <vector>
std::wstring GetExePath() {
// Retrieve fully qualified module pathname
std::vector<wchar_t> buffer( MAX_PATH );
DWORD cbSize = ::GetModuleFileNameW( nullptr, buffer.data(),
static_cast<DWORD>( buffer.size() ) );
while ( cbSize == buffer.size() ) {
buffer.resize( buffer.size() + MAX_PATH );
cbSize = ::GetModuleFileNameW( nullptr, buffer.data(),
static_cast<DWORD>( buffer.size() ) );
}
if ( cbSize == 0 ) {
throw ::GetLastError();
}
// Remove filename from fully qualified pathname
if ( ::PathRemoveFileSpecW( buffer.data() ) ) {
::PathAddBackslashW( buffer.data() );
}
// Construct string object from character buffer
std::wstring str( &buffer[0] );
return str;
}
This can be used as follows:
int wmain( int argc, const wchar_t* argv[] ) {
if ( argc <= 1 ) {
return -1;
}
std::wstring pathname = GetExePath();
pathname += argv[1];
HANDLE hFile = ::CreateFileW( pathname.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL );
if ( hFile == INVALID_HANDLE_VALUE )
{
wprintf( L"\nError: Unable to open file (%d)\n", GetLastError() );
return -1;
}
// ...
::CloseHandle( hFile );
return 0;
}
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