2015-02-18 1 views
2

Я искал и экспериментировал все утро с этим, и я в тупике. У меня есть страница aspx, работающая в IIS и вызывающая следующую функцию C#. Я пытаюсь запустить его cmd-файл и вернуть результат из cmd-файла. Я экспериментировал с пятью различными вариантами в коде ниже:Process.Start cmd.exe не будет запускать cmd-файл, который передается как приложение при запуске в IIS

protected String RunMyCmdFileAndGetResponse() { 
    Process proc = new Process(); 
    proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe"; 
// proc.StartInfo.Arguments = @"/c echo hello";     <== 1 
// proc.StartInfo.Arguments = @"/c c:\mypath\myfile_badname.cmd"; <== 2 
// proc.StartInfo.Arguments = @"/c type c:\mypath\myfile.cmd";  <== 3 
    proc.StartInfo.Arguments = @"/c c:\mypath\myfile.cmd";  // <== 4 
// proc.StartInfo.Arguments = @"/c call c:\mypath\myfile.cmd";  <== 5 
    proc.StartInfo.UseShellExecute = false; 
    proc.StartInfo.RedirectStandardOutput = true; 
    proc.StartInfo.RedirectStandardError = true; 
    proc.StartInfo.CreateNoWindow = true; 

    proc.Start(); 
    string response = proc.StandardOutput.ReadToEnd(); 
    response += proc.StandardError.ReadToEnd(); 
    proc.WaitForExit(); 
    return response; 
} 

Cmd файл C: \ mypath \ myfile.cmd содержание:

@echo test line 1 > c:\mypath\myfilelog.txt 
@echo test line 2 

Этот CMD файл работает, как ожидалось, когда выполняются вручную , создавая файл myfilelog.txt и возвращающую тестовую строку 2. При выполнении с кодом C#:

  • Вариант 1 работает - возвращает ответ «привет», как ожидалось.
  • Вариант 2 не подходит, как ожидается, с указанием myfile_badname.cmd не распознается как действительная команда
  • Вариант 3 работает как ожидалось - он возвращает содержимое myfile.cmd в качестве ответа - это подтверждает, что я могу найти и прочитать файл.
  • Вариант 4 не работает - как можно ближе к нему, он должен. Он не зависает, но также не возвращает никакого ответа вообще и не выполняет cmd-файл (без создания файла myfilelog.txt).
  • Вариант 5 - такие же результаты, как вариант 4.

Примечание - Я также попытался модифицировать myfile.cmd удалить строку 1 (создание файла журнала) и оставить только строку 2 эхо ответа. На всякий случай это проблема с разрешением, создающая файл журнала. Тот же результат.

Любая помощь будет оценена!

Обновлено добавить решение:

Ответ от @MaxOvrdrv заставил меня думать по-другому. Кажется, что существует какое-то ограничение при запуске Process.Start в контексте IIS с помощью UseShellExecute = false - если основным аргументом является исполняемый файл (cmd-файл, файл сценария и т. Д.), Он не запускает его. Я попытался передать SomeExample.cmd в cmd.exe и SomeExample.js в cscript.exe.

Однако ... Мне удалось обмануть его с уровнем косвенности, так что имя исполняемого файла больше не является первым аргументом, и оно отлично работает именно так.

Чтобы запустить CMD файл:

string theResponse = RunMyCmdAndGetResponse(@"c:\somepath\mycmd.cmd"); 

protected String RunMyCmdAndGetResponse(string cmdPath) { 
    Process proc = new Process(); 
    proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe"; 
    proc.StartInfo.Arguments = "/c cmd /c " + cmdPath; 
    proc.StartInfo.UseShellExecute = false; 
    proc.StartInfo.RedirectStandardOutput = true; 
    proc.StartInfo.RedirectStandardError = true; 
    proc.StartInfo.CreateNoWindow = true; 

    proc.Start(); 
    proc.WaitForExit(); 
    string response = proc.StandardOutput.ReadToEnd(); 
    response += proc.StandardError.ReadToEnd(); 
    return response; 
} 

Для запуска файла сценария:

string theResponse = RunMyScriptAndGetResponse(@"c:\somepath\myscript.js"); 

protected String RunMyScriptAndGetResponse(string scriptPath) { 
    Process proc = new Process(); 
    proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe"; 
    proc.StartInfo.Arguments = "/c cscript //nologo " + scriptPath; 
    proc.StartInfo.UseShellExecute = false; 
    proc.StartInfo.RedirectStandardOutput = true; 
    proc.StartInfo.RedirectStandardError = true; 
    proc.StartInfo.CreateNoWindow = true; 

    proc.Start(); 
    proc.WaitForExit(); 
    string response = proc.StandardOutput.ReadToEnd(); 
    response += proc.StandardError.ReadToEnd(); 
    return response; 
} 
+0

вы пробовали это? http://stackoverflow.com/questions/5519328/executing-batch-file-in-c-sharp – MaxOvrdrv

+0

Извините, я только что заметил что-то ... см. мой ответ ниже. – MaxOvrdrv

+0

Да, я посмотрел на эти примеры сегодня утром. Единственное функциональное отличие, которое я вижу между верхним ответом и моим примером выше, это то, что они вызывают WaitForExit перед чтением StandardOutput и StandardError, тогда как я вызывал WaitForExit после. я просто попытался сделать это изменение в моем примере и испытать - не радость! – grumpyhoser

ответ

1

Запуск командного файла или какой-либо процесса за Say со страницы ASPX бесполезно, как IIS не работает под истинным пользователем Windows Context. Из-за этого, независимо от того, сколько настроек и прав вы предоставляете пользователю, используемое AppPool под любым типом изменений конфигурации, вы просто не сможете работать. Некоторое время назад я столкнулся с той же проблемой, и в принципе это невозможно.

Смотрите мои предыдущие вопросы (и комментарии), наряду с общепринятым ответом на возможные «концептуальные» решения для решения текущей проблемы, здесь:

Process.Start won't work

+0

Dang. Я также попытался запустить тест с помощью cscript.exe, передав ему файл сценария js, и он ничего не сделает с этим, так что это не exe.cmd. Мне интересно, что «некоторые» вещи, кажется, успешно работают в этом контексте: - мой оригинальный вариант 1 работает с cmd.exe. Я также могу предоставить файл cmd непосредственно в качестве имени файла с помощью UseShellExecute = true, как упоминает @Derek, и это тоже работает, хотя я не могу получить ответ, делающий это таким образом. Я полагаю, что я мог бы запустить его путь Дерека, чтобы cmd написал ответ на файл, а затем прочитал файл в C#, но это просто уродливо! – grumpyhoser

+1

Да, я знаю ... были некоторые странные вещи, которые работали и не работали для меня тоже! Это действительно уродливо ... Я должен был сделать некоторые довольно забавные вещи, чтобы заставить мой процесс работать ... Я должен был написать что-то в текстовый файл и запустить Windows-службу в фоновом режиме (что файл был изменен), а затем запустить приложение из службы Windows вместо моей учетной записи и разбудить компьютер и всевозможные странные вещи, чтобы убрать мой процесс с веб-страницы ... он сосать. – MaxOvrdrv

+0

Спасибо за помощь - ваш вход привел меня к решению! Обновлен мой исходный вопрос с помощью решения. – grumpyhoser

0

Что о не используя "ЦМД"?

Process proc = new Process(); 
proc.StartInfo.FileName = @"c:\mypath\myfile.cmd"; 
+0

Это работает, если UseShellExecute имеет значение true, но мне нужно UseShellExecute = false, чтобы получить ответ из cmd-файла. – grumpyhoser

Смежные вопросы