2008-09-27 6 views
2

Я пытаюсь получить либо CreateProcess или CreateProcessW для выполнения процесса с именем < MAX _ PATH символов, но в пути, что это больше, чем MAX _ PATH. Согласно документам по адресу: http://msdn.microsoft.com/en-us/library/ms682425.aspx, мне нужно убедиться, что lpApplicationName не является NULL, а затем lpCommandLine может содержать до 32 768 символов.Как получить CreateProcess/CreateProcessW для выполнения процесса в пути> MAX_PATH символов

Я пробовал это, но я получаю ОШИБКУ _ PATH _ NOT _ НАЙДЕНО.

Я изменил на CreateProcessW, но все равно получаю ту же ошибку. ? Когда я префикс lpApplicationName с \\ \, как описано в http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx при вызове CreateProcessW я получаю другую ошибку, которая заставляет меня думать, что я немного ближе: ОШИБКА _ SXS _ CANT _ GEN _ ACTCTX.

Мой призыв к CreateProcessW является:

CreateProcessW(w_argv0,arg_string,NULL,NULL,0,NULL,NULL,&si,&ipi);

где w_argv0 является \\?\<long absolute path>\foo.exe.

arg_string содержит "< длинный абсолютный путь > \ foo.exe" Foo

си устанавливается следующим образом :

 
    memset(&si,0,sizeof(si)); 
    si.cb = sizeof(si); 
    si.dwFlags = STARTF_USESHOWWINDOW; 
    si.wShowWindow = SW_HIDE;> 

и пи пусто, как в:

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

Я посмотрел в системный журнал событий и есть новая запись каждый раз, когда я пытаюсь это событие с кодом 59, источник SideBySide: Генерация активации контекста Сбой .manifest. Ссылка сообщение об ошибке: Операция успешно завершена.

Файл, который я пытаюсь выполнить, отлично работает в пути < MAX_PATH символов.

Чтобы уточнить, ни один из компонентов < длинный абсолютный путь > больше MAX _ ПУТЬ символов. Имя исполняемого файла, конечно же, не является, даже с. Манифестом в конце. Но, весь путь вместе больше MAX _ символов PATH.

Я получаю ту же ошибку, независимо от того, вставляю ли я ее манифест или нет. Манифест называется foo.exe.manifest и живет в том же каталоге, что и исполняемый файл, если он не встроен. Он содержит:

 
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> 
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type='win32' name='Microsoft.VC80.DebugCRT' version='8.0.50727.762' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

Кто-нибудь знает, как заставить это работать? Возможно:

  • другой способ вызова CreateProcess или CreateProcessW для выполнения процесса в пути> символы MAX_PATH

  • что-то я могу сделать в файле манифеста

Я создание с Visual Studio 2005 на XP SP2 и запуск native.

Благодарим за помощь.

ответ

1

Я не вижу ссылки в документации по CreateProcess, говорящей, что синтаксис «\\? \» Действителен для имени модуля. На странице «Именование файла или каталога» также не указано, что поддерживает CreateProcess, а такие функции, как CreateFile, ссылаются на страницу «Именование файла».

Я сделать видеть, что вы не можете использовать имя модуля больше, чем MAX_PATH в lpCommandLine, что говорит о том, что CreateProcess не поддерживает дополнительные длинные имена файлов. Сообщение об ошибке также указывает на то, что при попытке добавить «.manifest» к вашему пути приложения (то есть длина теперь превышает MAX_PATH) возникает ошибка.

GetShortPathName() может быть полезен здесь, хотя он не гарантирует возврата имени меньше MAX_PATH (он явно указывает, что синтаксис «\\? \» Действителен, хотя). В противном случае вы можете попробовать настроить переменную окружения PATH и передать ее CreateProcess() в lpEnvironment. Или вы можете использовать SetCurrentDirectory() и передать только исполняемое имя.

2

Внедрение манифеста и использование GetShortPathNameW сделали это для меня. Одного или другого сами по себе недостаточно. ?

Перед вызова CreateProcessW с помощью \\ - приставка абсолютного имени пути процесса для выполнения в качестве первого аргумента, я проверяю:

 
wchar_t *w_argv0; 
wchar_t *w_short_argv0; 

... 

if (wcslen(w_argv0) >= MAX_PATH) 
{ 
    num_chars = GetShortPathNameW(w_argv0,NULL,0); 
    if (num_chars == 0) { 
     syslog(LOG_ERR,"GetShortPathName(%S) to get size failed (%d)",
w_argv0,GetLastError()); /* ** Might as well keep going and try with the long name */ } else { w_short_argv0 = malloc(num_chars * sizeof(wchar_t)); memset(w_short_argv0,0,num_chars * sizeof(wchar_t)); if (GetShortPathNameW(w_argv0,w_short_argv0,num_chars) == 0) { syslog(LOG_ERR,"GetShortPathName(%S) failed (%d)",w_argv0,
GetLastError()); free(w_short_argv0); w_short_argv0 = NULL; } else { syslog(LOG_DEBUG,"using short name %S for %S",w_short_argv0,
w_argv0); } } }

, а затем вызвать CreateProcessW (ш _ короткого _ argv0 ж _? short _ argv0: w _ argv0 ...);

запомнить свободный (w _ short _ argv0); после этого.

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