Получение кода ошибки пакетного скрипта - PullRequest
3 голосов
/ 20 апреля 2009

Я бы хотел, чтобы процесс Win32 запустил внешний скрипт и смог получить ERRORLEVEL, который он возвращает.

Обратный путь довольно прост. Просто используйте exit (errorcode) или return errorcode; в вашем приложении Win32, и вызывающий скрипт получает значение ERRORLEVEL, установленное правильно.

Но из вызывающего приложения Win32 получение кода ошибки скрипта не совсем то же самое.

Я пытался использовать CreateProcess () и вызывать GetExitCodeProcess (), но он всегда возвращает 0, а не фактическое значение ERRORLEVEL. Даже если я завершу свой вызываемый скрипт с помощью exit% ERRORLEVEL%

Мое лучшее предположение заключается в том, что сценарий - это , а не процесс за слово. Скорее всего, вместо этого выполняется CMD.EXE, и, скорее всего, он всегда заканчивается значением ExitCode, равным 0. Я знаю, что значение ERRORLEVEL отличается от значения ExitCode процесса, я бы надеялся, что CMD.EXE отразит его.

EDIT:

Извините, я спросил! Я только что обнаружил проблему MY . Я использовал exit / b errorcode вместо exit errorcode в моем пакетном файле. Похоже, что параметр / b имеет преимущество только в том, что закрывает работающий скрипт, а не CMD.EXE при тестировании из командной строки. Но недостаток в том, что вы не устанавливаете правильный ExitCode для CMD.EXE.

Итак, для потомков то, что я делаю, это:

int LaunchScript(TCHAR *pCmdLineParam)
{
    bool bResult;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);

    TCHAR   cmdLine[256];
    _tcscpy(cmdLine,L"Test.cmd");
    _tcscat(cmdLine,L" ");
    _tcscat(cmdLine,pCmdLineParam);

    _tprintf(L"Process executing: %s\n",cmdLine);

    bResult = CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)?true:false;
    if (!bResult) {
        _tprintf(L"CreateProcess() error - %d", GetLastError());
        return -1;
    }

    DWORD result = WaitForSingleObject(pi.hProcess,15000);
    if( result == WAIT_TIMEOUT ) {
        return -2;
    }

    DWORD exitCode=0;
    if( !GetExitCodeProcess(pi.hProcess,&exitCode) ) {
        _tprintf(L"GetExitCodeProcess() error - %d", GetLastError());
        return -1;
    }

    _tprintf(L"Process exitcode=%d\n",exitCode);

    return exitCode;
}

Мой пакетный файл "точка входа" выглядит так:

@call %*
@exit %ERRORLEVEL%

И я передаю свой сценарий для запуска в качестве параметра сценарию точки входа. Другие файлы «подпрограмм» могут вызывать exit / b или exit, потому что все покрыто.

Ответы [ 3 ]

1 голос
/ 20 апреля 2009

Это работает для меня:

int DoDOS(string parms)
{

Process p=new Process();
ProcessStartInfo ProcInfo=new ProcessStartInfo();

ProcInfo.Arguments="/C "+parms;
ProcInfo.CreateNoWindow=true;
ProcInfo.ErrorDialog=false;
ProcInfo.ErrorDialogParentHandle=IntPtr.Zero;
ProcInfo.FileName="cmd.exe";
ProcInfo.RedirectStandardError=false;
ProcInfo.RedirectStandardInput=false;
ProcInfo.RedirectStandardOutput=false;
ProcInfo.UseShellExecute=false;
ProcInfo.Verb="";
ProcInfo.WindowStyle=ProcessWindowStyle.Hidden;
p=Process.Start(ProcInfo);

while (!p.HasExited)
      {
      if (laRunning.Text!=RunningTxt) laRunning.Text=RunningTxt;
      else                            laRunning.Text="";
      Application.DoEvents();
      Thread.Sleep(500);
      }

return p.ExitCode; 
}
1 голос
/ 20 апреля 2009

Просто выстрел в темноте (так как я дома и у меня нет окон):

Мы используем 'cmd /c call <script>' на работе. Может быть, это работает для вашей проблемы.

0 голосов
/ 20 апреля 2009

Попробуйте передать это как lpCommandLine параметр CreateProcess:

cmd /v:on /k <script_name> & exit !errorlevel!

Будет включено задержка расширение переменной среды (в противном случае %ERRORLEVEL% развертывается перед выполнением <script_name>) и явное возвращение ERRORLEVEL, возвращаемого сценарием, как cmd.exe код возврата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...