Program stop to running when calls a process - c++

I am trying to create a program that calls another process using CreateProcess. After some problems, I change my program to just open a known program:
if( !CreateProcess( (LPWSTR)"C:\\Program Files\\Opera\\Opera.exe", // No module name (use command line)
NULL, ,
// Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
I found this example in msdn, but every time I run my program, windows (Vista) shows a error msg: The program stop running...
Does anybody know what is the problem?
Regards,
Leandro Lima

This line is wrong:
(LPWSTR)"C:\\Program Files\\Opera\\Opera.exe"
LPWSTR is a typedef for wchar_t*. So you're casting a plain string (array of chars, which will decay to a const char*) to a wchar_t*. The end result is likely not even null-terminated!
Either use CreateProcessA and drop the cast, or use a wide string:
L"C:\\Program Files\\Opera\\Opera.exe",

Related

Is there any way to get text from the console of another application?

I have a third party console application in term as "reg.exe". When I run it, it shows me a text message. I want to use this string in my application.
How do I get this string?
I want to use CreatProcess to execute "reg.exe",
CreateProcess( NULL, // No module name (use command line)
argv[1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
Then use
WaitForSingleObject( pi.hProcess, INFINITE );
to wait it to be finished.

C++ - CreateProcess failed code 2

I am trying to use the CreateProcess() function in order to launch an .exe application that is in a folder in my root directory (the directory where my VS solution is). Seems simple right? It probably is but I can't for the life of me notice what I have done wrong. Every time I try to launch the .exe I get the error message "CreateProcess failed code 2" which means that the .exe file I am trying to launch cant be found.
My code:
void HavNetProfiler::LaunchClumsy()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Start the child process.
if (!CreateProcess((LPCTSTR)"Clumsy\\clumsy.exe", // No module name (use command line)
NULL, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi) // Pointer to PROCESS_INFORMATION structure
)
{
printf("CreateProcess failed (%d).\n", GetLastError());
return;
}
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
Am I using this function wrong? Have I misunderstood how it works or have I simply missed some minor detail? I am calling the function LaunchClumsy() in a file that is placed in a different folder (that folder exists in the root folder just like the "Clumsy" folder though). Would that make a difference?
Thanks!
There are 2 immediate bugs in the code:
The LPCTSTR cast is wrong. If your code does not compile without that cast, you have passed an argument with the wrong character encoding. Change it to L"Clumsy\\clumsy.exe" to explicitly pass a wide-character string.
Using a relative path is very likely to fail. The system searches starting from the current working directory. That is a process-wide property, that can be altered by any thread, at any time. Use an absolute path instead.

Do I need to specify an exe path as the 1st parameter in lpCommandLine when calling CreateProcessAsUser?

I can't seem to find a definitive answer to this. My goal is to start a process using a user token. Say, the process in question is started as such:
"C:\My folder\My proc.exe" param=1
So when I specify lpCommandLine parameter for the CreateProcessAsUser API, do I need to specify executable path as the 1st parameter as such:
LPCTSTR pStrExePath = L"C:\\My folder\\My proc.exe";
TCHAR buffCmdLine[MAX_PATH];
if(SUCCEEDED(::StringCchPrintf(buffCmdLine, MAX_PATH,
L"\"%s\" %s", pStrExePath, L"param=1")))
bResult = CreateProcessAsUser(
hToken, // client's access token
pStrExePath, // file to execute
buffCmdLine, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, // creation flags
envBlock, // pointer to new environment block
NULL, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
Or can I omit the exe path and do this?
LPCTSTR pStrExePath = L"C:\\My folder\\My proc.exe";
TCHAR buffCmdLine[MAX_PATH];
if(SUCCEEDED(::StringCchCopy(buffCmdLine, MAX_PATH, L"param=1")))
bResult = CreateProcessAsUser(
hToken, // client's access token
pStrExePath, // file to execute
buffCmdLine, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, // creation flags
envBlock, // pointer to new environment block
NULL, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
They both seem to work.
Reading the documentation, both cases should work.
From MSDN
If both lpApplicationName and lpCommandLine are non-NULL,
*lpApplicationName specifies the module to execute, and *lpCommandLine specifies the command line. The new process can use GetCommandLine to
retrieve the entire command line. Console processes written in C can
use the argc and argv arguments to parse the command line. Because
argv[0] is the module name, C programmers generally repeat the module
name as the first token in the command line.
I agree that the documentation may be clearer saying that it accepts the argument part of the command line or the full command line in lpCommandLine when lpApplicationName is non-NULL.
UPDATE :
The documentation is better in the case lpApplicationName is NULL
If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name...
UPDATE 2 :
There is a nice documentation about these arguments Understanding CreateProcess and Command-line Arguments.
Reading this documentation, I understand that there is a difference between your two cases. When you provide lpApplicationName and arguments in lpCommandLine the child process will parse the command line as it is in lpCommandLine. So if you do not duplicate the exe path, argv[0] will not represent the exe path as usual but param=1.

ERROR_INVALID_HANDLE when calling GetModuleFileNameEx after CreateProcess

After a successful call to CreateProcess, I am trying to get the path of the created process using GetModuleFileNameEx (lpApplicationName and lpCommandLine parameters can vary or be null so they aren't reliable in this case).
The problem is that GetModuleFileNameEx fails with error 6 (ERROR_INVALID_HANDLE), leaving its buffer with invalid data. I cannot understand the reason, since CreateProcess succeeds and process handle should have been saved correctly in pi.hProcess.
Hope you can shed some light, thanks in advance!
EDIT: An update: I noticed that removing the CREATE_SUSPENDED removes this problem too, but I need that flag set. How can I do?
// Defining GetModuleFileNameExA function
typedef DWORD (WINAPI *fGetModuleFileNameExA)
(
HANDLE hProcess,
HMODULE hModule,
LPSTR lpFilename,
DWORD nSize
);
//Load dinamically DLL function on program startup:
fGetModuleFileNameExA _GetModuleFileNameExA = (fGetModuleFileNameExA) GetProcAddress( LoadLibraryA("Psapi.dll"), "GetModuleFileNameExA");
// **** OTHER UNRELATED CODE HERE ****
PROCESS_INFORMATION pi;
//This call succeeds
if (!CreateProcessW( ApplicationName,
CommandLine,
NewProcess.lpProcessAttributes,
NewProcess.lpThreadAttributes,
NewProcess.bInheritHandles,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
NULL,
CurrentDirectory,
&NewProcess.bufStartupInfo,
&pi)
) MessageBoxA(0, "Error creating process", "", 0);
char ProcessPath[MAX_PATH];
//Problem here: call fails with error 6
if (!_GetModuleFileNameExA(pi.hProcess, NULL, ProcessPath, MAX_PATH)) {GetLastError();}
//Invalid data is displayed
MessageBoxA(0, ProcessPath, "GetModuleFileNameEx",0);
From the CreateProcess documentation on MSDN:
Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
...
The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process.
Similar question

CreateProcess function fails to launch an application completely

I have two application. I will just call them A and B. I have access to the code of application A.
I want to launch the applicaiton B and open a file in that application from A. I am using
CreateProcess method to acheive it. But the application B is not getting opened completely.
I am not sure whether there are any common dlls or other dependencies between these two applications.
The code that I use to open the applicaiton B form A is:
std::wstring appBPath(L"C:\\B.exe");
std::wstring filePath(L"C:\\file.pdf");
std::wstring cmdLineCommand = L"\"" + appBPath+ L"\" \"" + filePath + L"\"";
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
// set the size of the structures
SecureZeroMemory( &startupInfo, sizeof(startupInfo) );
startupInfo.cb = sizeof(startupInfo);
SecureZeroMemory( &processInfo, sizeof(processInfo) );
CreateProcess( NULL, // No module name (use command line)
&cmdLineCommand[0], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
CREATE_NEW_CONSOLE, // New process has a new console
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&startupInfo, // Pointer to STARTUPINFO structure
&processInfo ); // Pointer to PROCESS_INFORMATION structure
The exe file starts to load but it gets stuck during the initialisation. But, the application B doesn't terminate.
It goes to some inconsistent state. This issue is happens only only for application A that's installed from it's installer.
It doesn't occur when I run the release or debug build. For the release and debug build we are using VC10. But for installer
build we use VC12. I am not sure on the compiler optimization that are there in place for the installer build.
The CreateProcess function returns success.
Thread state of the application B from process explorer: