Search code examples
c++stringvisual-c++castinglptstr

Convert char[] array to LPTSTR in vc++


I want to use the Win API CreateProcess for which accepts 2nd parameter as "LPTSTR".

But I've the path to my exe in a char array. My VS2013 project (static library) is Unicode encoding type. Code snippert below. IN this line

"appPath = (LPTSTR)TestEXEPath;"

of the below code snippet where the type cast is happening, I see that the characters in "appPath" gets converted to some junk characters whereas the RHS of this expression "TestEXEPath" does have valid characters. However tehre is no compilation error here. It is at run time this characters get corrupted in "appPath".

I know this typecast is creating this problem. But how do I solve this, how do I type cast this char array to LPTSTR typr which is needed by "CreateProcess() API.

Or is there any better way of doing this so as to avoid the char array itself.

LPTSTR  appPath;
char cwd[_MAX_PATH];
getcwd(cwd, _MAX_PATH);
char TestEXEPath[_MAX_PATH];
strcpy(TestEXEPath, cwd);

strcat(TestEXEPath, "\\pwrtest.exe /sleep /c:1");

appPath = (LPTSTR)TestEXEPath; // The characters in this gets converted to some junk characters.
.......................
......................

CreateProcess(NULL, appPath, NULL, NULL, FALSE, 0, NULL, workingDir, &sI, &pI))

Solution

  • You are compiling for Unicode, so LPTSTR expands to wchar_t*. But you have ANSI data, char*. In that case it is simplest to call CreateProcessA and pass the ANSI data.

    BOOL retval = CreateProcessA(..., TestExePath, ...));
    

    If you want to avoid using ANSI functions then you can stick to wchar_t arrays.

    whar_t exepath[MAX_PATH + 100]; // enough room for cwd and the rest of command line
    GetCurrentDirectory(MAX_PATH, exepath);
    wcscat(exepath, L"\\pwrtest.exe /sleep /c:1");
    BOOL retval = CreateProcess(..., exepath, ...);
    

    Note that I switched from getcwd to GetCurrentDirectory in order to get a wide char version of the working directory.

    Note also that your code should check for errors. I neglected to do that here due to laze. But in your real code, you should not be as lazy as I have been.


    The fact that you had to cast should have set off warning signals for you. Well, judging from the question, it probably did. When you write:

    appPath = (LPTSTR)TestEXEPath;
    

    That simply tells the compiler to treat TestEXEPath as LPTSTR whether or not it really is. And the fact that the program won't compile without the cast tells you that TestEXEPath is not LPTSTR. The cast does not change that reality, it merely shuts the compiler up. Always a bad move.