2012-07-05 11 views
12

私の目的は、自分のプログラムで外部実行可能ファイルを実行することです。まず、system()機能を使用しましたが、私はコンソールをユーザーに見せたくありません。だから、私はちょっと調べて、CreateProcess()の機能を見つけました。しかし、私はそれにパラメータを渡そうとすると、私はなぜそれが失敗するのか分からない。私はMSDNからこのコードを取り出し、ビットを変更しました。CreateProcess()がアクセス違反で失敗する

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

void _tmain(int argc, TCHAR *argv[]) 
{ 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 

    ZeroMemory(&si, sizeof(si)); 
    si.cb = sizeof(si); 
    ZeroMemory(&pi, sizeof(pi)); 
    /* 
    if(argc != 2) 
    { 
     printf("Usage: %s [cmdline]\n", argv[0]); 
     return; 
    } 
    */ 
    // Start the child process. 
    if(!CreateProcess(NULL, // No module name (use command line) 
     L"c:\\users\\e\\desktop\\mspaint.exe",  // 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); 
} 

ただし、このコードは何とかアクセス違反を明らかにしました。ユーザにコンソールを表示せずにmspaintを実行できますか?

ありがとうございました。

+2

、 'CreateProcess'は(提供された場合)その2番目のパラメータは非const文字列である必要があります。実際にはこれが問題なのかどうかはわかりませんが、完全性のために言及したいと思います。 – reuben

+0

...そうでなければ、どこでAVが起こっていますか?コールスタックがありますか? – reuben

+0

@reuben Uhm ...私は確信していませんが、これはコールスタックの出力であると思います: 'kernel32.dll!76da70ac()\t \t [下のフレームは正しくありませんkernel32.dllのために] \t > \t msvcr100d.dll!_nh_malloc_dbg(unsigned int型nsizeの場合、int型nhFlag、int型nBlockUse、constのchar型* szFileName、INT NLINE)線302 + 0x1Dのバイト\t C++ ' –

答えて

7

これを試してください、それは動作するはずです。これにコード

TCHAR lpszClientPath[500]= TEXT("c:\\users\\e\\desktop\\mspaint.exe"); 
if(!CreateProcess(NULL, lpszClientPath, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|CREATE_UNICODE_ENVIRONMENT,NULL, NULL, &si, &pi)) 
      { 
    printf("CreateProcess failed (%d).\n", GetLastError()); 
     return; 
      } 
... 
... 
18

第2引数はLPTSTRです。つまり、非const char配列へのポインタです。 docsは、具体的に言う:

このパラメータは(例えば CONST変数またはリテラル文字列など)読み取り専用メモリポインタ

ことができない文字列リテラルを渡す理由は問題です。

システムは、コマンドライン 文字列に終止ヌル文字を追加して、ファイル名と引数を区切ります。これにより、元の文字列 が内部処理用の2つの文字列に分割されます。

あなたの場合は、読み取り専用メモリを変更しようとします。つまり、クラッシュします。

+0

私はLPTSTRのいずれかを割り当てることはできません。 「c:\ users \ e \ desktop \」にあるmspaintを実行するために、私の2番目の議論は、私が求めるかもしれないものは何でしょうか?どうもありがとうございました。 –

+2

@JohnDoe: 'wchar_t path [] = L" C:\\ユーザー\\ e \\デスクトップ\\ "' – hmjd

+0

'wchar_t path [] = L" C:\\ blahblah "'は 'LPWSTR path = L "C:\\ blahblah" 'しかし、' wchar_t * path = L "C:\\ blahblah" 'と同じです。 @hmjdが提案したものを使うか、 'LPWSTR path'を定義してから、このvarにメモリを割り当ててパスをコピーしてください。 –

0

変更します:一つには

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

void _tmain(int argc, TCHAR *argv[]) 
{ 
    TCHAR ProcessName[256]; 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 

    wcscpy(ProcessName,L"c:\\users\\e\\desktop\\mspaint.exe"); 
    ZeroMemory(&si, sizeof(si)); 
    si.cb = sizeof(si); 
    ZeroMemory(&pi, sizeof(pi)); 
    /* 
    if(argc != 2) 
    { 
     printf("Usage: %s [cmdline]\n", argv[0]); 
     return; 
    } 
    */ 
    // Start the child process. 
    if(!CreateProcess(NULL, // No module name (use command line) 
     ProcessName,  // 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); 
} 
関連する問題