2012-07-19 25 views
10

私はここで深刻な問題を抱えています。コンソールウィンドウを表示せずにC++経由でCMDコマンドラインを実行する必要があります。したがって、system(cmd)は使用できません。ウィンドウが表示されるからです。C++ CMDコマンドを実行しています

私はwinExec(cmd, SW_HIDE)を試しましたが、これは動作しません。 CreateProcessは私が試したもう1つです。ただし、これはプログラムやバッチファイルを実行するためのものです。

私はShellExecuteをしようとしてしまっています

ShellExecute(NULL, "open", 
    "cmd.exe", 
    "ipconfig > myfile.txt", 
    "c:\projects\b", 
    SW_SHOWNORMAL 
); 

誰もが上記のコードに何かを見ることができますか?この作品が分かるまで私はSW_SHOWNORMALを使いました。

私は本当にこれについていくつかの助けが必要です。何も光に来ていない、と私はかなりの間しようとしています。誰でも助けてくれるアドバイスは素晴らしいでしょう:)

+0

戻りコードを確認しましたか? – Collin

+1

私はあなたに答えがあることを知っていますが、それがうまくいかないことを言うのは良い考えです。 – Deanna

+0

なぜWMI_関数を呼び出して結果をファイルに書き込まないのでしょうか。ウィンドウがなく、必要なデータだけです。 –

答えて

6

が整然と解決策であるが、これは正常に動作します:

ShellExecute(0, "open", "cmd.exe", "/C ipconfig > out.txt", 0, SW_HIDE); 

あなたはCMDウィンドウが表示されないと予想されるように出力がリダイレクトされます。

"c:\\projects\\b"ではなく、パスを"c:\projects\b"と指定しているため、コードがおそらく失敗しています(/C以外)。

4

CreateProcesscmd.exeとし、/Cパラメータを使用してipconfigコマンドをトンネルする必要があります。 >はコマンドライン上では動作しません。あなたはredirect programmatically the stdoutです。それは、出力ファイルを作成避けるために、独自のパイプに出力をリダイレクト

+0

'cmd/c'コマンドラインであれば、もちろん'> 'リダイレクトが機能します。 – eryksun

3

DOSコマンドを(黙って)実行し、生成された出力をUnicode文字列として取得できるDosExec関数を実装しました。

// 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; 
} 
+0

サンプルコードをありがとう! –

0

私はgithubの上の同様のプログラム[Windows7のとテスト10]を持っている

https://github.com/vlsireddy/remwin/tree/master/remwin

これは、インターフェースの名前 "ローカルエリア接続" の

  1. 聴取するサーバプログラムですUDPポート(5555)用のウィンドウを開き、udpパケットを受信します。
  2. udpパケットの内容がcmd.exeで実行されました[コマンドが実行された後にcmd.exeが閉じられず、[実行されたコマンドの出力]が同じudpポートを介してクライアントプログラムにフィードバックされないようにしてください。 >クライアントプログラムに同じポートで返送された出力は

これは、「コンソールウィンドウ」が表示されません - > UDPパケット解析された - - > cmd.exeの上で実行言い換えれば

  • 、 コマンドは、UDPパケットで受信しました 誰かがcmd.exeで手動でコマンドを実行する必要はありません remwin.exeはバックグラウンドで動作し、シン・サーバ・プログラムである可能性があります

    +0

    こんにちは、ポリシングのあまりのように見えます、私は有効なテスト済みのリンクを入れて、テストされたコードで特定の答えに特定の質問に答える、あなたの削除レビューの推奨を理解していない。コード[MSVC]を実行し、出力をチェックしてテストし、適合しない場合は削除します。 – particlereddy

    +0

    申し訳ありませんが、私は自分のコメントを削除しました。私はトリガーであまりにも速かった... – Jolta

    +0

    あなたの答えを読んで、それはあなたが問題を解決したように私に見えます。しかし、スタックオーバーフローは、外部リンクの形で解決策を提供する回答を失望させます。 – Jolta

    関連する問題