"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);
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.
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
}
GetModueFileName()
fills a TCHAR[]
buffer that you provide. CopyFile()
expects LPTSTR
input values. You can pass a TCHAR[]
to a LPTSTR
. So there is no mismatch.
Commented
Oct 15, 2013 at 22:22
TCHAR
, PTSTR
etc., compile for Unicode, and use WCHAR
, PWSTR
everywhere when writing Windows specific code. String literals should come prefaced with L
, i.e. L"Hello world"
. If you need to work with a library that uses 8-bit strings (hopefully UTF-8) you should use MultiByteToWideChar
, WideCharToMultiByte
.
Are you running app from VS? IDE-s often change working directory of apps according to project properties. Try running app outside VS.