Подтвердить что ты не робот

CreateProcess не передает аргументы командной строки

Здравствуйте, у меня есть следующий код, но он не работает должным образом, не могу понять, в чем проблема.

В принципе, я выполняю процесс (процесс .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 = "[email protected]";

    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;
}

EDIT:. Еще одна вещь, если я передаю свой cmdArgs следующим образом:

// a space as the first character
LPTSTR cmdArgs = " [email protected]";

Затем я получаю ошибку, затем CreateProcess возвращает TRUE, но мой целевой процесс не выполняется.

Object reference not set to an instance of an object
4b9b3361

Ответ 1

Вы должны указать также имя модуля в параметрах: LPTSTR cmdArgs = "App [email protected]"; Это должна быть вся командная строка (включая argv [0]).

Ответ 2

Если первый параметр CreateProcess() не равен NULL, он будет использовать его для поиска изображения для запуска.

Если он равен NULL, он проанализирует второй аргумент, чтобы попытаться запустить исполняемый файл из первого токена.

В любом случае среда выполнения C будет использовать второй аргумент для заполнения массива 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 [email protected]";

    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 [email protected]
[0]: echoargs.exe
[1]: [email protected]

Yohoo!

Ответ 3

Не похоже, что вы правильно используете 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, указывает исполняемый модуль, а строка с нулевым завершением, на которую указывает lpCommandLine, указывает командную строку. Новый процесс может использовать GetCommandLine для извлечения всей командной строки. Консольные процессы, написанные на C, могут использовать аргументы argc и argv для синтаксического анализа командной строки. Поскольку argv [0] - это имя модуля, программисты C обычно повторяют имя модуля в качестве первого токена в командной строке.

Итак, в вашем случае вам нужно это как аргумент команды и, вероятно, нужно передать NULL для первого параметра, чтобы получить нужное поведение.

// NOTE THE Null-Terminated string too!
LPTSTR cmdArgs = "D:\\email\\smtp.exe [email protected]\0";

Ответ 4

Ниже приведена сокращенная версия кода, используемого 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 [email protected]";

Из того, что я могу сказать, единственное реальное различие между ними состоит в том, что в примере Zeus аргумент dwCreationFlags установлен в значение CREATE_NEW_PROCESS_GROUP.

Ответ 5

Попробуйте следующее:

LPTSTR cmdArgs = "[email protected]";
CString szcmdline("D:\\email\\smtp.exe");
szcmdline += _T(" ") + cmdArgs ;

//Leave first param empty and pass path + argms in 
    if(CreateProcess(NULL, szcmdline, second

Ответ 6

Unicode-версия этой функции CreateProcessW может изменять содержимое этой строки. Поэтому этот параметр не может быть указателем на постоянную память (например, константную переменную или литеральную строку). Если этот параметр является константой, функция может вызвать нарушение доступа.

Поэтому вы можете попробовать использовать LPTSTR cmdArgs = _tcsdup("[email protected]").

Другая проблема заключается в следующем: как целевой процесс считывает аргументы? используя argv [0] в качестве имени приложения? Затем вы также добавите имя приложения в качестве первого параметра.

Ответ 7

Вы не выделяете память для своей строки.

Вместо:

LPTSTR cmdArgs = "[email protected]";

попробовать:

TCHAR cmdArgs[] = "[email protected]";

Изменить: затем вызовите:

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

Это создаст локальный массив в стеке, а затем передаст указатель на этот массив.

Ответ 8

Вы можете добавить пробел как первый символ строки cmdArgs:

LPTSTR cmdArgs = " [email protected]";

По-видимому, Windows добавляет вторую строку аргумента к имени приложения, представленному первым аргументом, и результат передается в качестве аргументов командной строки для исполняемого файла. Таким образом, добавление пространства будет правильно разделять аргументы.