sadmin
sadmin

Reputation: 33

CopyFile from current directory in c++ (windows API)

"myfile.doc" is in the same directory as the c++ executable. But this gives me an error code 2!

CopyFile("myfile.doc","C:\\Destination\\myfile.doc",0);

Upvotes: 1

Views: 3920

Answers (3)

asveikau
asveikau

Reputation: 40284

The current directory is not the same as the one with the executable. You want to call GetModuleFileName with a NULL HMODULE to get its path.

Update: Since you asked, here's a quick and dirty example with all error checks omitted (since your code example uses ANSI strings I will stick to TCHAR, as I say in comments in general I find it easier to just stay with WCHAR or PWSTR everywhere and compile for Unicode):

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(X) (sizeof(X) / sizeof(*X))
#endif

// ISSUE - would be cleaner to do this on heap without artificial size limits
TCHAR Buffer[MAX_PATH];

PTSTR LastSlash;

if (!GetModuleFileName(NULL, Buffer, ARRAY_SIZE(Buffer)))
{
   // TODO - handle error
}

LastSlash = _tcsrchr(Buffer, _T('\\'));
if (!LastSlash)
{
   // TODO - this shouldn't happen.  treat it as an error.
}

LastSlash++;

TCHAR ToAppend[] = _T("myfile.doc");
if (ARRAY_SIZE(ToAppend) > ARRAY_SIZE(Buffer) - (LastSlash - Buffer))
{
   // TODO - you don't have enough space, this is an error
}

memcpy(LastSlash, ToAppend, sizeof(ToAppend));

if (!CopyFile(Buffer,_T("C:\\Destination\\myfile.doc"),0))
{
   // TODO - this is an error
}

Upvotes: 1

IInspectable
IInspectable

Reputation: 51511

You should not rely on using a relative path. Instead construct a fully qualified pathname first. Start by retrieving the fully qualified path of the executable. GetModuleFileName is the way to go:

TCHAR path[MAX_PATH] = {0};
GetModuleFileName(NULL, path, MAX_PATH);

To construct the fully qualified pathname of the file to copy you need to strip off the filename of the executable and append your filename. The Shell Lightweight Utility Library offers PathRemoveFileSpec and PathAppend:

PathRemoveFileSpec(path);
PathAppend(path, _T("myfile.doc"));

At this point, path holds the fully qualified pathname to your file myfile.doc, ready to be used in your call to CopyFile.

Note that this implementation is limited to pathnames of length MAX_PATH (260) characters. Also note that both SHLW calls have been deprecated in favor of safer alternatives PathCchRemoveFileSpec and PathCchApend. The concepts remain the same; I went with the deprecated API calls for brevity.

Upvotes: 1

Srđan Tot
Srđan Tot

Reputation: 235

Are you running app from VS? IDE-s often change working directory of apps according to project properties. Try running app outside VS.

Upvotes: 0

Related Questions