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

лямбда является просто анонимной функцией - функция, определяемая без имени. На некоторых языках, таких как Схема, они эквивалентны именованным функциям. На самом деле функциональное определение переписывается как привязка лямбды к переменной внутренне. На других языках, как Python, существуют некоторые (довольно бесполезные) различия между ними, но они ведут себя тот же путь иначе.

А закрытие является любой функцией, которая завершения [более чем 1 117] среда , в котором это было определено. Это означает, что может переменные доступа не в его списке параметров. Примеры:

def func(): return h
def anotherfunc(h):
   return func()

Это вызовет ошибку, потому что func не делает близкий [более чем 1 119], среда в anotherfunc - h не определена. func только завершения по глобальной среде. Это будет работать:

def anotherfunc(h):
    def func(): return h
    return func()

, поскольку здесь, func определяется в anotherfunc, и в python 2.3 и больше (или некоторое число как это), когда они [почти 1 122] получили корректные закрытия (мутация все еще не работает), это означает, что завершения [более чем 1 120] anotherfunc среда и может переменные доступа в нем. В Python 3.1 +, мутация работает также при использовании nonlocal ключевое слово .

, Другой важный момент - func продолжит закрывать [более чем 1 112] среду, даже когда это больше не оценивается в [1 113]. Этот код будет также работать:

def anotherfunc(h):
    def func(): return h
    return func

print anotherfunc(10)()

Это распечатает 10.

Это, как Вы замечаете, не имеет никакого отношения лямбда с - им отличающиеся два года (хотя связано) понятия.

26
задан Jeff Atwood 4 June 2010 в 09:26
поделиться

7 ответов

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

24
ответ дан 28 November 2019 в 06:53
поделиться

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

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

// NOTE THE Null-Terminated string too!
LPTSTR cmdArgs = "D:\\email\\smtp.exe name@example.com\0";
5
ответ дан 28 November 2019 в 06:53
поделиться

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

Вместо:

LPTSTR cmdArgs = "name@example.com";

попробуйте:

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

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

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

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

0
ответ дан 28 November 2019 в 06:53
поделиться

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

LPTSTR cmdArgs = "name@example.com";
CString szcmdline("D:\\email\\smtp.exe");
szcmdline += _T(" ") + cmdArgs ;

//Leave first param empty and pass path + argms in 
    if(CreateProcess(NULL, szcmdline, second
2
ответ дан 28 November 2019 в 06:53
поделиться

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

Поэтому вы можете попробовать использовать LPTSTR cmdArgs = _tcsdup (" name@example.com ") .

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

0
ответ дан 28 November 2019 в 06:53
поделиться

If the first parameter to CreateProcess() is non-NULL, it will use that to locate the image to launch.

If it is NULL, it will parser the 2nd argument to try to get the executable to launch from the 1st token.

In either case, the C runtime will use the second argument to populate the argv array. So the first token from that parameter shows up in argv[0].

You probably want something like the following (I've change the smtp.exe program to echoargs.exe - a simple utility I have to help figure out just this kind of issue):

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

Here's the output I get from that program:

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

Yohoo!
19
ответ дан 28 November 2019 в 06:53
поделиться

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

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

5
ответ дан 28 November 2019 в 06:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: