32

こんにちは、私は次のコードを持っていますが、期待どおりに動作していません。問題が何であるかを理解できません。

基本的に、プロセス (.NET プロセス) を実行してコマンド ライン引数を渡しています。CreateProcess() によって正常に実行されますが、CreateProcess() はコマンド ライン引数を渡しません。

ここで何が間違っていますか??

int main(int argc, char* argv[])
{
    PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter

    STARTUPINFO StartupInfo; //This is an [in] parameter

    ZeroMemory(&StartupInfo, sizeof(StartupInfo));
    StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field

    LPTSTR cmdArgs = "name@example.com";

    if(CreateProcess("D:\\email\\smtp.exe", cmdArgs, 
        NULL,NULL,FALSE,0,NULL,
        NULL,&StartupInfo,&ProcessInfo))
    { 
        WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);

        printf("Yohoo!");
    }  
    else
    {
        printf("The process could not be started...");
    }

    return 0;
}

編集:もう1つ、次のように渡すとcmdArgs:

// a space as the first character
LPTSTR cmdArgs = " name@example.com";

その後、エラーが発生し、CreateProcess が返されますTRUEが、ターゲット プロセスが実行されません。

Object reference not set to an instance of an object
4

8 に答える 8

27

パラメータでモジュール名指定する必要があります。LPTSTR cmdArgs = "App name@example.com"; これは、コマンド ライン全体 (argv[0] を含む) である必要があります。

于 2009-07-16T06:51:53.657 に答える
22

最初のパラメータがCreateProcess()NULL でない場合、それを使用して起動するイメージを見つけます。

NULL の場合、2 番目の引数を解析して、最初のトークンから実行可能ファイルを起動しようとします。

いずれの場合も、C ランタイムは 2 番目の引数を使用してargv配列を設定します。したがって、そのパラメータの最初のトークンが に表示されargv[0]ます。

おそらく、次のようなものが必要です (smtp.exe プログラムを echoargs.exe に変更しました。これは、この種の問題を解決するのに役立つ単純なユーティリティです)。

int main(int argc, char* argv[])
{
    PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter

    STARTUPINFO StartupInfo; //This is an [in] parameter
    char cmdArgs[] = "echoargs.exe name@example.com";

    ZeroMemory(&StartupInfo, sizeof(StartupInfo));
    StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field


    if(CreateProcess("C:\\util\\echoargs.exe", cmdArgs, 
        NULL,NULL,FALSE,0,NULL,
        NULL,&StartupInfo,&ProcessInfo))
    { 
        WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);

        printf("Yohoo!");
    }  
    else
    {
        printf("The process could not be started...");
    }

    return 0;
}

そのプログラムから得られる出力は次のとおりです。

echoargs.exe name@example.com
[0]: echoargs.exe
[1]: name@example.com

Yohoo!
于 2009-07-17T01:49:45.450 に答える
7

CreateProcess を正しく使用していないようです。 http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspxを参照してください。

  • 実行するコマンドライン。この文字列の最大長は 32,768 文字で、Unicode 終了ヌル文字を含みます。lpApplicationName が NULL の場合、lpCommandLine のモジュール名部分は MAX_PATH 文字に制限されます。

  • lpCommandLine パラメータは NULL にすることができます。その場合、関数は lpApplicationName が指す文字列をコマンド ラインとして使用します。

  • lpApplicationName と lpCommandLine の両方が NULL でない場合、lpApplicationName が指す null で終わる文字列は実行するモジュールを指定し、lpCommandLine が指す null で終わる文字列はコマンド ラインを指定します。新しいプロセスは、GetCommandLine を使用してコマンド ライン全体を取得できます。C で記述されたコンソール プロセスは、argc および argv 引数を使用してコマンド ラインを解析できます。argv[0] はモジュール名であるため、C プログラマーは通常、コマンド ラインの最初のトークンとしてモジュール名を繰り返します。

したがって、あなたの場合、コマンド引数としてこれが必要であり、最初のパラメーターに NULL を渡して、必要な動作を取得する必要があります。

// NOTE THE Null-Terminated string too!
LPTSTR cmdArgs = "D:\\email\\smtp.exe name@example.com\0";
于 2009-07-16T06:51:57.493 に答える
6

以下は、Zeus IDEが外部プロセスを実行するために使用するコードの簡略版です。

bool createProcess(const char *pszTitle, const char *pszCommand)
{
  STARTUPINFO StartInfo;

  memset(&StartInfo, 0, sizeof(StartInfo));

  StartInfo.cb      = sizeof(StartInfo);
  StartInfo.lpTitle = (pszTitle) ? (char *)pszTitle : (char *)pszCommand;

  StartInfo.wShowWindow = SW_NORMAL;
  StartInfo.dwFlags    |= STARTF_USESHOWWINDOW;

  if (CreateProcess(0, (char *)pszCommand, 
                    0, 0, TRUE,
                    CREATE_NEW_PROCESS_GROUP, 0, 0, 
                    &StartInfo, &ProcessInfo))
  {
    lErrorCode = 0;
  }
  else
  {
    lErrorCode = GetLastError();
  }

  return (lErrorCode == 0);
}

pszCommandは、完全な実行可能パス、ファイル名、および引数になります。たとえば、次のようになります。

pszCommand = "D:\\email\\smtp.exe name@example.com";

私が知る限り、この 2 つの違いは、Zeusの例ではdwCreationFlags引数がCREATE_NEW_PROCESS_GROUP値に設定されていることだけです。

于 2009-07-21T05:53:50.317 に答える
-1

文字列にメモリを割り当てていません。

それ以外の:

LPTSTR cmdArgs = "name@example.com";

試す:

TCHAR cmdArgs[] = "name@example.com";

編集:次に呼び出します:

 CreateProcess("D:\\email\\smtp.exe", &cmdArgs[0], ...

これにより、スタック上にローカル配列が作成され、その配列へのポインターが渡されます。

于 2009-07-16T07:48:02.717 に答える