Как выполнить командный файл из C #? - PullRequest
2 голосов
/ 12 июня 2010

(См. Конец для решения)

Я не думал, что это будет трудно.У меня есть файл комманд, d: \ a.cmd, который содержит:

copy /b d:\7zS.sfx + d:\config.txt + d:\files.7z d:\setup.exe

Но эти строки C # не будут его выполнять:

Process.Start("d:\\a.cmd");
Process.Start("cmd", "/c d:\\a.cmd");

Выдает Win32Exception: "% 1не является допустимым приложением Win32. "

Process.Start открывает файлы .pdf ... почему бы не выполнить командные файлы?

Это работает, если я набираю его в окне cmd:

cmd /c d:\a.cmd

Windows XP, MS Visual Studio 2008.

Заранее спасибо, Джим

РЕШЕНИЕ Я только НЕМНОГО смущен :( Был файл с именем cmd.exe, размерноль в директории моего приложения. Я понятия не имею, как оно туда попало, но теперь оно является тостом, и оба вышеперечисленных утверждения C # теперь работают. Я ухожу, чтобы найти книгу о Гарри Поттере, чтобы я мог получить некоторые идеи самонаказания от Добби...

Ответы [ 7 ]

2 голосов
/ 14 июня 2010

Необходимо указать полное имя процесса (cmd.exe).
Вы должны попробовать

Environment.GetFolderPath(Environment.SpecialFolder.System) + "cmd.exe"

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

2 голосов
/ 14 июня 2010

У меня есть четыре вещи , которые вы можете попробовать:

(1) Попробуйте указать полный путь для cmd.exe (например, на моем компьютере: C:\WINDOWS\SYSTEM32\CMD.EXE).


(2) Попробуйте добавить call к исполняемой команде:

Process.Start(@"C:\WINDOWS\SYSTEM32\CMD.EXE", @"/c call D:\a.cmd");

(3) Кроме того, я могу только догадываться, откуда исходит %1 в Win32Exception. Возможно, ваши файловые ассоциации установлены неправильно.

Если вы введете в командной строке следующее:

> assoc .cmd

Вы, вероятно, получите упоминание о cmdfile. Если вы затем посмотрите на этот токен с:

> ftype cmdfile

Вы можете получить ответ в следующем виде:

cmdfile="%1" %*

Эти настройки хранятся в реестре, и именно так интерпретатор командной строки знает, как выполнять файлы с пользовательскими расширениями. (Вы можете узнать, как запускается документ PDF, выполнив два вышеуказанных оператора для расширения .pdf.)


(4) Если вы начинаете подозревать, что ваш компьютер может быть неправильно настроен, запустите regedit (редактор реестра) и найдите ключ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor.

На моем компьютере с Windows XP (и ваш Process.Start пример работает на моем компьютере, хотя и с разными именами файлов), у меня там хранятся следующие значения:

//  Name                Type        Value
//  -----------------------------------------------
//  (standard)          REG_SZ      (not set)
//  AutoRun             REG_SZ
//  CompletionChar      REG_DWORD   0x00000040 (64)
//  DefaultColor        REG_DWORD   0x00000000 (0)
//  EnableExtensions    REG_DWORD   0x00000001 (1)
//  PathCompletionChar  REG_DWORD   0x00000040 (64)

Из них значение AutoRun может представлять некоторый интерес. Я думаю, что это соответствует ключу командной строки /d cmd.exe, который определяет, пытается ли cmd.exe запускать файлы с пользовательскими расширениями. Обычно это включено. Может быть, на вашей машине это не так?

2 голосов
/ 12 июня 2010

Или вы можете сделать .bat файл , а затем вызвать этот файл через System.Diagnostics.Process.Start().Он не будет перенаправлять вывод в консольное приложение, но, безусловно, будет выполнять команды внутри.

1 голос
/ 14 июня 2010

Похоже, что-то не так с вашим компьютером. Попробуйте запустить это на другой машине. Это должно работать. Process.Start(string) использует ShellExecuteEx для запуска файла, так что это почти то же самое, что и двойной щелчок файла в Проводнике, как вы и предполагали.

У меня сработал простой тест.

B: \ foo.cmd:

@echo Hello from foo.cmd!
@pause

Program.cs:

class Program{
    static void Main(){
        System.Diagnostics.Process.Start("B:\\foo.cmd");
    }
}

Это работает как ожидалось.

Ваше сообщение об ошибке подозрительно: «% 1 не является допустимым приложением Win32». Значение в моем реестре в HKCR \ cmdfile \ shell \ open \ command:

"%1" %*

%1 заменяется именем файла, и %* здесь можно игнорировать (это указывает на то, что любые дальнейшие аргументы командной строки должны передаваться, но мы сейчас не занимаемся этим).

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

  • .exe Исполняемые файлы Windows и DOS
  • .com DOS-файлы "команд"
  • .bat Пакетные файлы Windows и DOS
  • .cmd Пакетные файлы Windows NT
  • .pif Ярлыки Windows для исполняемых файлов DOS

Если перейти к HKCR\.xxx (где xxx - любой из вышеперечисленных), значение "(по умолчанию)" должно быть xxxfile. Если вы затем перейдете к HKCR\xxxfile\shell\open\command, значение «(по умолчанию)» должно быть "%1" %*. Также значение «(по умолчанию)» HKCR\xxxfile\shell должно быть либо не задано, либо open.

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

0 голосов
/ 14 июня 2010

Вы тестировали свой пакетный файл в каталоге, в каком контексте он будет работать? Сообщение об ошибке с% 1 выглядит так, как будто проблема может быть там?

0 голосов
/ 14 июня 2010

хмм попробуй:

System.Diagnostics.Process myproc = new System.Diagnostics.Process();
myproc.EnableRaisingEvents=false;
myproc.StartInfo.FileName="d:\\a.cmd";
myproc.Start();
MessageBox.Show("did the command");
0 голосов
/ 12 июня 2010

Вы пытались выполнить cmd.exe и передать ему файл .cmd в качестве аргумента?

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