start on certain PID c++ - c++

I'am trying to start batch file on certain PID, or get PID what program started on. I really have no idea how to do that.
system("start C:\\testing\\vw.bat");
Sleep(2000); //1000 = 1s
After this code is executed I need to close "vw.bat", but not close other batch files that are running.

PROCESS_INFORMATION pi;
STARTUPINFO si{};
si.cb = sizeof(si);
BOOL success = CreateProcess("start C:\\testing\\vw.bat", NULL, NULL, NULL, TRUE, 0, NULL, "C:\\testing\\", &si, &pi);
if (success)
{
int pid = pi.dwProcessId;
}

You can get the PID of your process using system-dependant system calls. For instance, on linux, using pidof. Now, please note using the system() function is not recommended, and other ways of doing what you want exist, like spawning a child process, which will let you kill the process easily.

Related

CreateProcess calling cmd.exe incl. arguments with no showing (flashing) window?

The saga continues...
I've searched the web, i've searched on StackOverflow, i found many hope giving answers/solutions, but somehow they have all failed (up)on me (including the ones related to ShellExecute(Ex) ).
How to hide a (flashing) CMD window (incl. arguments) using CreateProcess??
I basically want to call/execute a set of conditional/native cmd.exe commands (i.e. FOR /F, and ||), but also an external command FIND(STR).exe. And this, without showing a (flashing) CMD window.
But even hiding something as simple as "cmd.exe /C ECHO ...flashing window is bad..." seems impossible to do.
The code i've tried (including many variations related to the dwFlags and wShowWindow flags
#include <windows.h>
int main()
{
char cmdline[] = "cmd.exe /c ECHO ...flashing window is bad...";
PROCESS_INFORMATION pi;
STARTUPINFO si;
// memset(&si,0,sizeof(STARTUPINFO));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
// si.dwFlags = STARTF_USESTDHANDLES;
// si.dwFlags = CREATE_NO_WINDOW;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
// si.wShowWindow = CREATE_NO_WINDOW;
CreateProcess(NULL, (LPSTR) cmdline, NULL, NULL, 0, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
// ExitProcess;
return 0;
}
I don't want to rely on external programs i.e. .vbs (Windows Scripting Host) or shortcut tricks, but simply a standalone compiled .exe.
Is this (really) too much to ask, or am i doing it (completely) wrong?
Thanks...
Update: You also seem to confuse CreateProcess flags (its dwCreationFlags argument) with the member of STARTUPINFO structure. These are different flags, CREATE_NO_WINDOW should not be in STARTUPINFO.
You have to pass the CREATE_NO_WINDOW flag, then the console window won't show. Originally I've answered that you have to redirect the standard handles which is not correct (but still highly recommanded).
Set STARTF_USESTDHANDLES and fill in appropriate handles. If you are interested in the output of the process, create pipes, otherwise you can just open nul an pass that.
Try Using ProcessBuilder. Here is an example of some code that I have that seems to work just fine. In my code below, the shellScript is a StringBuilder that I am dynamically creating that contains the command and it's parameters that I want to execute.
String[] scriptArray = shellScript.toString().split(" ");
ProcessBuilder builder = new ProcessBuilder(scriptArray);
File outputFile = new File("/logs/AgentOutputLog.txt");
File errorFile = new File("/logs/AgentErrorLog.txt");
builder.redirectOutput(outputFile);
builder.redirectError(errorFile);
Process process = builder.start();
int errCode = process.waitFor();
//errCode = 0 means online
if(errCode == 0){
success = true;
break;
//errCode = 1 means offline
} else if (errCode == 1){
success = false;
break;
}

CreateProcessWithLogon returns Function not supported

I'm trying to start a program that starts another program as another user with the Win32 function CreateProcessWithLogon on a Windows 7 system but it returns error 120 which stands for function not supported.
If I run the program in the command it works correctly. If I on the other hand start the program with ShellExecute then I get the error.
Cmd Line -> Start Program A -> Program A executes CreateProcessWithLogon. OK
32 bit program -> Start Program A -> Program A executes CreateProcessWithLogn. ERROR
if (!CreateProcessWithLogonW(L"username", L"domain", L"password",
LOGON_NETCREDENTIALS_ONLY, L"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe", L"iexplore",
NULL, NULL, NULL,
&si, &pi))
DisplayError(L"CreateProcessWithLogonW");
if you want starts program as another user not use LOGON_NETCREDENTIALS_ONLY flag - use LOGON_WITH_PROFILE instead.
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
if (CreateProcessWithLogonW(L"username", L"domain", L"password", LOGON_WITH_PROFILE,
L"C:\\windows\\notepad.exe", L"notepad.exe", 0, NULL, NULL, &si, &pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
if you use flag LOGON_NETCREDENTIALS_ONLY
The system does not validate the specified credentials.
so really you not need provide real name or password. because system not do real login but
The new process uses the same token as the caller, but the system
creates a new logon session within LSA
so this logon type clone caller current token but specify new logon session in it. your program will be run as same user (SID , groups, privileges) but in separate logon session
only one trick need, not documented - lpUsername must be in UPN format - containing # symbol.
so code must be like this:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
if (CreateProcessWithLogonW(L"#", 0, 0, LOGON_NETCREDENTIALS_ONLY,
L"C:\\windows\\notepad.exe", L"notepad.exe", 0, NULL, NULL, &si, &pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
as result will be created new LogonSession with NewCredentials as SECURITY_LOGON_TYPE , AuthenticationPackage == Negotiate

trying to run commend on cmd throw c++ using createprocces (API)?

bool execute()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
bool flag = true;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
string f = "dir desktop"
if (CmdLine.parameter != "")
{
LPSTR l1 = const_cast<char *>(f.c_str());
CreateProcess(NULL, l1, NULL, NULL, false, 0, NULL, NULL, &si, &pi);
flag = true;
// WaitForSingleObject(pi.hProcess, INFINITE);
// // Close process and thread handles.
// CloseHandle(pi.hProcess);
// CloseHandle(pi.hThread);
//}
}
return flag;
}
I'm trying to run cmd command by visual studio.
I'm using createprocces (API) in order to run this thing
but I can't understand why it doesn't run anything.
dir is a command understood by cmd.exe, it's not a program you can execute.
You can try the command cmd /k "dir desktop", properly expressed as a C++ string.
E.g.,
auto execute()
-> bool
{
STARTUPINFO si = { sizeof( si ) };
PROCESS_INFORMATION pi = {};
string f = "cmd /k \"dir desktop\"\0";
bool const ok = !!CreateProcess( 0, &f[0], 0, 0, false, 0, 0, 0, &si, &pi );
if( !ok ) { return false; }
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
Note how the calls to ZeroMemory have been replaced with C++ initialization.
Just by letting the compiler do its job you get shorter, more clear code that is more likely correct, and just as efficient (possibly more). Win win win.
Disclaimer: code not reviewed by compiler.
If the intent is to list the contents of the user's desktop folder, then note that dir desktop doesn't do that. As an interactive command in the command interpreter you could use dir %userprofile%\desktop, and that also works via the Windows Run-dialog. Depending on the command interpreter's behavior for command line arguments it may work directly via CreateProcess, or not.
Generally, when using Windows API level functions it's preferable to use the wchar_t-based text based functions, i.e. define UNICODE before including <windows.h> (or use the ...W functions explicitly).
If you call CreateProcess() with the first parameter set to NULL, then you have to make sure that l1 starts with the module name to call.
As dir is an internal command of the command processor and not an executable, you have to use cmd as module name and give the rest of the parameter as cmd expects them.
So try the following:
string f = "cmd /c=dir desktop";

Creating independent process!

I am trying to create a process from a service in C++. This new process is creating as a child process. I want to create an independent process and not a child process...
I am using CreateProcess function for the same. Since the new process i create is a child process when i try to kill process tree at the service level it is killing the child process too... I dont want this to happen. I want the new process created to run independent of the service.
Please advice on the same..
Thanks..
Code
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si); // Start the child process.
ZeroMemory( &pi, sizeof(pi) );
si.dwFlags = STARTF_USESHOWWINDOW;
if(bRunOnWinLogonDesktop)
{
if(csDesktopName.empty())
si.lpDesktop = _T("winsta0\\default");
else
_tcscpy(si.lpDesktop, csDesktopName.c_str());
}
if(bHide)
si.wShowWindow = SW_HIDE; /* maybe even SW_HIDE */
else
si.wShowWindow = SW_SHOW; /* maybe even SW_HIDE */
TCHAR szCmdLine[512];
_tcscpy(szCmdLine, csCmdLine.c_str());
if( !CreateProcess( NULL,
szCmdLine,
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP,
NULL,
NULL,
&si,
&pi ) )
After closing thread and process handlers of the child process, it's still a child in the Process Explorer, but ending parent process doesn't cause termination of the child one.
CreateProcess( NULL,
szCmdLine,
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP,
NULL,
NULL,
&si,
&pi );
if(pi.hThread)
CloseHandle(pi.hTread);
if(pi.hProcess)
CloseHandle(pi.hProcess);
I've found this decision in sources of cmd.exe of the ReactOS, in the procedure of executing 'start' command.
Create an intermediate process (use create_new_process_group), which then creates the real process.
Service
-> Intermediate Process
-> Real Process
The Intermediate process should exit as soon as it's launched the real process.

Launching external application and block current application till the launched application quit

I am not sure whether there is a way to
Launch an external application, and block current application till the launched application had quit.
Currently, I am using the following non-blocking method (MFC) to launch
std::string str = "Notepad2.exe";
// Non-blocking. Return immediately.
WinExec(str.c_str(), SW_SHOW);
code:
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof (SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = "open";
sei.lpFile = "notepad.exe";
sei.nShow = SW_SHOWNORMAL;
if (ShellExecuteEx (&sei))
{
WaitForSingleObject (sei.hProcess, INFINITE);
}
As Jerry points out, this is bad for your own GUI. But if the process you launch, directly or indirectly, does a broadcast SendMessage then this can cause catastrophic deadlock, because your process has a window but isn't pumping any messages: the launched process is waiting for your code to handle its message, and you're waiting for it. Clang...
You could use MsgWaitForMultipleObjects instead, or better still, split the launch-and-wait off into a thread and simply disable any part of your UI you don't want the user to interact with.
ShellExecuteEx with SEE_MASK_NOCLOSEPROCESS will (among other things) give you a handle to the new process. You can do a WaitForSingleObject on that handle, which will be signaled when it terminates. BTW, for a GUI program, this is almost always a bad idea -- making your GUI unresponsive until another program exits is really a poor idea.
If you just want to launch a process, you don't have to use ShellExecuteEx, use CreateProcess instead. Here is an untested example:
std::wstring commandLine = L"Notepad2.exe"
std::wstring::size_type length = commandLine.size();
boost::scoped_array<WCHAR> buffer(new WCHAR[length + 1]);
std::copy(commandLine.begin(), commandLine.end(), buffer.get());
buffer[length] = L'\0';
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo, sizeof startupInfo);
startupInfo.cb = sizeof startupInfo;
PROCESS_INFORMATION processInfo;
CreateProcess(NULL, buffer.get(), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo);
CloseHandle(processInfo.hThread);
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);