1

"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);
1

3 Answers 3

1

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.

1

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
}
7
  • And how would you pass that to "CopyFile" without type conversion errors. ' Out LPTSTR lpFilename' and ' In LPCTSTR lpExistingFileName,'
    – sadmin
    Commented Oct 15, 2013 at 22:20
  • 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
  • @RemyLebeau TCHAR buffer[] 'unknown size' and '+' : cannot add two pointers (buffer + "myfile.doc")
    – sadmin
    Commented Oct 15, 2013 at 22:26
  • In addition to what @RemyLebeau says, you should ignore 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.
    – asveikau
    Commented Oct 15, 2013 at 22:27
  • @asveikau Could you write that in a code snippet I can actually compile? I have the multibyte setting.
    – sadmin
    Commented Oct 15, 2013 at 22:29
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.