You can call the 'CreateProcess' WinAPI Function with the 'CREATE_NO_WINDOW' flag in the Set-UP of the object. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
Thanks for helping, can i retrieve the output flow of my command with this function ? In fact like with popen()
Yes, look at the STARTUPINFO struct and the hStdOutput field (refer here for an example on creating a pipe so you can get this output). You will need to wait for the process to exit first before doing this. Use WaitForSingleObject with hProcess from the PROCESS_INFORMATION struct (last parameter) and INFINITE as the wait time.
Is this part of code good to begin with: ExpandEnvironmentStrings("%windir%\\System32\\cmd.exe",buff,299);//Outputs C:\\windows\\System32\\cmd.exe in buff CreateProcess(buff, "/k cscript.exe %windir%\\System32\\slmgr.vbs -dlv",0,0,TRUE,CREATE_NO_WINDOW,0,0,&si,&pi); WaitForSingleObject(pi.hProcess,1000);//Wait 4 hProcess(cmd.exe) to end: handle to proc,time in milliseconds /* Here redirect to pipe, got to learn how to do this */ CloseHandle(pi.hProcess); CloseHandle(pi.hThread);
Code: BOOL Test() { // Create the read and write handles for stdout. HANDLE stdOutHandles[2]; // Setup the security attributes. SECURITY_ATTRIBUTES saAttr; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Create the pipe for stdout. if(!CreatePipe(&stdOutHandles[0], &stdOutHandles[1], &saAttr, 0)) return FALSE; PROCESS_INFORMATION pInfo; ZeroMemory(&pInfo, sizeof(PROCESS_INFORMATION)); // Specify the pipe handle and make sure the window is hidden. STARTUPINFO startInfo; ZeroMemory(&startInfo, sizeof(STARTUPINFO)); startInfo.cb = sizeof(STARTUPINFO); startInfo.hStdOutput = stdOutHandles[1]; startInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; startInfo.wShowWindow = SW_HIDE; // Call cscript.exe with slmgr.vbs -dlv as the parameters. Because of the nature of this command, I left the first parameter as NULL. char expandedCScript[MAX_PATH]; ExpandEnvironmentStrings("%windir%\\System32\\cscript.exe //nologo \"%windir%\\System32\\slmgr.vbs\" -dlv", expandedCScript, MAX_PATH); if(!CreateProcess(NULL, expandedCScript, NULL, NULL, TRUE, 0, NULL, NULL, &startInfo, &pInfo)) { CloseHandle(stdOutHandles[0]); CloseHandle(stdOutHandles[1]); return FALSE; } // Wait for cscript.exe to exit. WaitForSingleObject(pInfo.hProcess, INFINITE); // Read the output from cscript.exe char buffer[2048]; DWORD readBufferSize; BOOL result; if((result = ReadFile(stdOutHandles[0], buffer, 2048, &readBufferSize, NULL))) { // ReadFile does not null-terminate the buffer so we do that manually. buffer[readBufferSize] = '\0'; // Display the output. MessageBox(NULL, buffer, NULL, MB_OK); } // Close the handles. CloseHandle(stdOutHandles[0]); CloseHandle(stdOutHandles[1]); CloseHandle(pInfo.hProcess); CloseHandle(pInfo.hThread); return result; }
Thanks master131. But i have a question: why to declare a SECURITY_ATTRIBUTES for inheriting created process's handles isn't it useless cuz we already set it to TRUE in CreateProcess() ? If you can also give me a link to learn better about pipe structure,how they work in detail cuz it seems interresent Thank you very much for helping
Hey thanks master131, i think i found why to declare SECURITY_ATTRIBUTES with TRUE inherit handle. See this from MSDN concerning TRUE inherit handle: Then see this for SECURITY_ATTRIBUTES from MSDN: The first makes child process inherit parent process handles. The 2nd makes parent process inherit child ones. I think that's it. Anyway, thanks dude!