Reputation: 11
what i tried to do: do start an external .exe file (which is compiled from fortran) on windows via another c++ program
I have tried many different versions, like:
system("C:/IPSE_temp/CEA_schwing.exe");
compiling was ok, but when i executed the file he missed some libraries such as RUND32.dll...
Then i tried to use this kind of code (CreateProcess) in different variations
std::string rt = "C:/IPSE_temp/CEA_schwing.exe";
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
if (CreateProcess(NULL, (LPWSTR) rt.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);)
{
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
cause i wanna know too, when the program is finished (program should wait until external .exe has finished it's work). Compiling was ok, but he never runs the .exe
I hope that i skipped nothing in de description, an i'm looking forward to your help. Thanks in advance
And yes, i'm new into programming in c++ ;)
best regards
hanks to Barmak Shemirani, the program is now running.
unfortunately there is an additional error:
my CEA_schwing.exe is reading a file "SINGLE_TP.inp" from the same directory. this is working fine wenn i run die exe through the windows explorer.
But by running the .exe through my c++ program, he isn't able to find the file anymore. Does anybody know why he doesn't get the file anymore?
Upvotes: 1
Views: 4894
Reputation: 31599
rt.c_str()
should be the first parameter in CreateProcess()
.
Moreover, you are mixing ANSI and Unicode. You are clearly compiling for Unicode, where CreateProcess()
maps to CreateProcessW()
. std::string
contains char
data, so c_str()
returns a const char *
pointer, but CreateProcessW()
is expecting a wchar_t*
pointer instead. Casting with (LPWSTR)rt.c_str()
will simply hide the compiler error, but it doesn't fix the actual problem of you passing ANSI data where Unicode data is expected.
Use a wide string instead when declaring Unicode strings (Note the L
prefix):
std::wstring rt = L"C:/IPSE_temp/CEA_schwing.exe";
if (CreateProcess(rt.c_str(), NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
...
That works because rt.c_str()
is now compatible with the first parameter of CreateProcess()
, which is an LPCWSTR
and will accept a const wchar_t *
pointer from c_str()
(the second parameter does not accept a const
pointer).
Alternatively, you can declare wchar_t buf[MAX_PATH]
and use it as the second parameter in CreateProcess()
, which is of type LPWSTR
(non-const):
wchar_t buf[MAX_PATH];
wcscpy_s(buf, L"C:/IPSE_temp/CEA_schwing.exe");
CreateProcess(0, buf, ...);
You can also set the working directory in the 8th parameter:
wchar_t buf[MAX_PATH];
wcscpy_s(buf, L"C:\\IPSE_temp\\CEA_schwing.exe");
std::wstring dir = L"C:\\IPSE_temp";
CreateProcess(0, buf, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, dir.c_str(), &si, &pi);
Upvotes: 4