我在这里有一个严重的问题。 我需要通过C ++执行CMD命令行,而不显示控制台窗口。 所以我不能使用system(cmd)
,因为窗口会显示。
我已经尝试winExec(cmd, SW_HIDE)
,但这也不起作用。 CreateProcess
是我尝试的另一个。 但是,这是用于运行程序或batch file。
我已经结束了尝试ShellExecute
:
ShellExecute( NULL, "open", "cmd.exe", "ipconfig > myfile.txt", "c:\projects\b", SW_SHOWNORMAL );
任何人都可以看到上面的代码有什么问题吗? 我已经使用SW_SHOWNORMAL
直到我知道这个工程。
我真的需要一些帮助。 没有任何东西显露出来,我一直在尝试一段时间。 任何人可以给的build议将是伟大的:)
将输出重定向到你自己的管道是一个更整洁的解决方案,因为它避免了创建输出文件,但是这个工作正常:
ShellExecute(0, "open", "cmd.exe", "/C ipconfig > out.txt", 0, SW_HIDE);
您没有看到cmd窗口,并且输出按预期重定向。
您的代码可能会失败(除了/C
之外),因为您将路径指定为"c:\projects\b"
而不是"c:\\projects\\b"
。
您应该使用cmd.exe
上的CreateProcess和/C
参数来隧道ipconfig命令。 >本身在命令行上不起作用。 您必须以编程方式重定向stdout 。
这里是我的DosExec函数的实现,它允许(静默)执行任何DOS命令,并以unicode字符串的形式检索生成的输出。
// Convert an OEM string (8-bit) to a UTF-16 string (16-bit) #define OEMtoUNICODE(str) CHARtoWCHAR(str, CP_OEMCP) /* Convert a single/multi-byte string to a UTF-16 string (16-bit). We take advantage of the MultiByteToWideChar function that allows to specify the charset of the input string. */ LPWSTR CHARtoWCHAR(LPSTR str, UINT codePage) { size_t len = strlen(str) + 1; int size_needed = MultiByteToWideChar(codePage, 0, str, len, NULL, 0); LPWSTR wstr = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * size_needed); MultiByteToWideChar(codePage, 0, str, len, wstr, size_needed); return wstr; } /* Execute a DOS command. If the function succeeds, the return value is a non-NULL pointer to the output of the invoked command. Command will produce a 8-bit characters stream using OEM code-page. As charset depends on OS config (ex: CP437 [OEM-US/latin-US], CP850 [OEM 850/latin-1]), before being returned, output is converted to a wide-char string with function OEMtoUNICODE. Resulting buffer is allocated with LocalAlloc. It is the caller's responsibility to free the memory used by the argument list when it is no longer needed. To free the memory, use a single call to LocalFree function. */ LPWSTR DosExec(LPWSTR command){ // Allocate 1Mo to store the output (final buffer will be sized to actual output) // If output exceeds that size, it will be truncated const SIZE_T RESULT_SIZE = sizeof(char)*1024*1024; char* output = (char*) LocalAlloc(LPTR, RESULT_SIZE); HANDLE readPipe, writePipe; SECURITY_ATTRIBUTES security; STARTUPINFOA start; PROCESS_INFORMATION processInfo; security.nLength = sizeof(SECURITY_ATTRIBUTES); security.bInheritHandle = true; security.lpSecurityDescriptor = NULL; if ( CreatePipe( &readPipe, // address of variable for read handle &writePipe, // address of variable for write handle &security, // pointer to security attributes 0 // number of bytes reserved for pipe ) ){ GetStartupInfoA(&start); start.hStdOutput = writePipe; start.hStdError = writePipe; start.hStdInput = readPipe; start.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; start.wShowWindow = SW_HIDE; // We have to start the DOS app the same way cmd.exe does (using the current Win32 ANSI code-page). // So, we use the "ANSI" version of createProcess, to be able to pass a LPSTR (single/multi-byte character string) // instead of a LPWSTR (wide-character string) and we use the UNICODEtoANSI function to convert the given command if (CreateProcessA(NULL, // pointer to name of executable module UNICODEtoANSI(command), // pointer to command line string &security, // pointer to process security attributes &security, // pointer to thread security attributes TRUE, // handle inheritance flag NORMAL_PRIORITY_CLASS, // creation flags NULL, // pointer to new environment block NULL, // pointer to current directory name &start, // pointer to STARTUPINFO &processInfo // pointer to PROCESS_INFORMATION )){ // wait for the child process to start for(UINT state = WAIT_TIMEOUT; state == WAIT_TIMEOUT; state = WaitForSingleObject(processInfo.hProcess, 100) ); DWORD bytesRead = 0, count = 0; const int BUFF_SIZE = 1024; char* buffer = (char*) malloc(sizeof(char)*BUFF_SIZE+1); strcpy(output, ""); do { DWORD dwAvail = 0; if (!PeekNamedPipe(readPipe, NULL, 0, NULL, &dwAvail, NULL)) { // error, the child process might have ended break; } if (!dwAvail) { // no data available in the pipe break; } ReadFile(readPipe, buffer, BUFF_SIZE, &bytesRead, NULL); buffer[bytesRead] = '\0'; if((count+bytesRead) > RESULT_SIZE) break; strcat(output, buffer); count += bytesRead; } while (bytesRead >= BUFF_SIZE); free(buffer); } } CloseHandle(processInfo.hThread); CloseHandle(processInfo.hProcess); CloseHandle(writePipe); CloseHandle(readPipe); // convert result buffer to a wide-character string LPWSTR result = OEMtoUNICODE(output); LocalFree(output); return result; }
我有一个类似的程序(windows7和10测试)在github上
https://github.com/vlsireddy/remwin/tree/master/remwin
这是服务器程序
这不显示“控制台窗口”没有人需要执行cmd.exe手动命令remwin.exe可以在后台运行,其瘦服务器程序