简体   繁体   English

如何从C#执行批处理文件?

[英]How to execute a batch file from C#?

(See end for solution) (请参阅结尾以获取解决方案)

I didn't think this was going to be hard. 我不认为这会很难。 I have a commmand file, d:\\a.cmd which contains: 我有一个命令文件d:\\ a.cmd,其中包含:

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

But these lines of C# won't execute it: 但是这些C#行不会执行它:

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

Throws Win32Exception: "%1 is not a valid Win32 application." 引发Win32Exception:“%1不是有效的Win32应用程序。”

Process.Start opens .pdf files...why not execute command files? Process.Start打开.pdf文件...为什么不执行命令文件?

This works if I type it in a cmd window: 如果我在cmd窗口中键入它,它将起作用:

cmd /c d:\a.cmd

Windows XP, MS Visual Studio 2008. Windows XP,MS Visual Studio 2008。

Thanks in advance, Jim 预先感谢,吉姆

SOLUTION I'm only SLIGHTLY embarrassed :( There was a file named cmd.exe, size zero in my app's dir. I have no idea how it got there but it is now toast and both of the above C# statements now work. I'm off to find a Harry Potter book so I can get some self-punishment ideas from Dobby... 解决方案:我只是有些尴尬:(在我的应用程序目录中有一个名为cmd.exe的文件,大小为零。我不知道它如何到达那里,但是现在是吐司了,上面的两个C#语句现在都可以使用。我去找一本《哈利·波特》书,所以我可以从多比那里得到一些自我惩罚的想法...

Or you can do a .bat file , then call this file through System.Diagnostics.Process.Start() . 或者, 您可以创建一个.bat文件 ,然后通过System.Diagnostics.Process.Start()调用此文件。 It won't redirect output to Console Application, but it would certainly execute the commands inside. 它不会将输出重定向到控制台应用程序,但是肯定会在其中执行命令。

I've got four things for you that you can try out: 我为您准备了四件事 ,您可以尝试:

(1) Try providing the full path for cmd.exe (eg on my machine: C:\\WINDOWS\\SYSTEM32\\CMD.EXE ). (1)尝试提供cmd.exe的完整路径(例如,在我的计算机上: C:\\WINDOWS\\SYSTEM32\\CMD.EXE )。


(2) Try adding call to the command to be executed: (2)尝试将call添加到要执行的命令:

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

(3) Besides that, I can only guess where the %1 in the Win32Exception is coming from. (3)除此之外,我只能猜测Win32Exception中的%1来自何处。 Maybe your file associations are set-up incorrectly. 也许您的文件关联设置不正确。

If you type the following on the command-line: 如果您在命令行上键入以下内容:

> assoc .cmd

You will likely get a mention of cmdfile . 您可能会提到cmdfile If you then look up this token with: 如果您随后使用以下命令查找此令牌:

> ftype cmdfile

You might get an answer along the lines of: 您可能会得到以下答案:

cmdfile="%1" %*

Those settings are stored in the registry, and this is how the command-line interpreter knows how to execute files with custom extensions. 这些设置存储在注册表中,这就是命令行解释器知道如何执行带有自定义扩展名的文件的方式。 (You can find out how a PDF document is started by executing the above two statements for the .pdf extension.) (您可以通过执行上述两个.pdf扩展名语句来了解如何启动PDF文档。)


(4) If you start to suspect that your machine might be mis-configured, start regedit (the registry editor) and locate the key HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Command Processor . (4)如果您开始怀疑计算机配置错误,请启动regedit (注册表编辑器)并找到键HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Command Processor

On my Windows XP machine (and your Process.Start example works on my machine, with different filenames though), I've got the following values stored in there: 在我的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)

Of those, the AutoRun value might be of some interest. 其中,“ AutoRun值可能会令人感兴趣。 I think it corresponds to the /d command-line switch of cmd.exe , which controls whether cmd.exe attempts to start files with custom extensions. 我认为它对应于cmd.exe/d命令行开关,该开关控制cmd.exe是否尝试启动具有自定义扩展名的文件。 Usually, this is enabled. 通常,启用此功能。 Maybe, on your machine, it isn't? 也许在您的机器上不是吗?

You need to specify the process full name (cmd.exe). 您需要指定进程全名(cmd.exe)。
You should try 你应该试试

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

So you can be sure to execute the right file even if a cmd.exe is in your applications directory. 因此,即使cmd.exe在应用程序目录中,您也可以确保执行正确的文件。

It looks like something wrong with your computer. 您的计算机似乎出了点问题。 Try running this on another machine. 尝试在另一台机器上运行它。 This should work. 应该工作。 Process.Start(string) uses ShellExecuteEx to launch the file, so it's pretty much the same thing as double-clicking the file in Explorer, as you supposed. Process.Start(string)使用ShellExecuteEx启动文件,因此,就像您想的那样,它与在资源管理器中双击该文件几乎相同。

A simple test worked for me. 一个简单的测试对我有用。

B:\\foo.cmd: B:\\ foo.cmd:

@echo Hello from foo.cmd!
@pause

Program.cs: Program.cs中:

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

This works as expected. 这按预期工作。

Your error message is suspicious, "%1 is not a valid Win32 application." 您的错误消息是可疑的,“%1不是有效的Win32应用程序。” The value in my registry at HKCR\\cmdfile\\shell\\open\\command is 我在HKCR \\ cmdfile \\ shell \\ open \\ command中的注册表值是

"%1" %*

The %1 gets replaced by the file name, and the %* can be ignored here (it indicates that any further command-line arguments should be passed along, but we're not concerned with that right now). %1被文件名替换, %*在这里可以忽略(它表示应该传递任何其他命令行参数,但是我们现在不关心它)。

The fact that the file itself is launched to handle this type of file indicates that Windows itself knows how to launch this type of file. 启动文件本身以处理此类文件的事实表明Windows本身知道如何启动此类文件。 On a normal installation of Windows, the following extensions should be set up similarly: 在Windows的正常安装中,应类似地设置以下扩展名:

  • .exe Windows and DOS executable files .exe Windows和DOS可执行文件
  • .com DOS "command" files .com DOS“命令”文件
  • .bat Windows and DOS batch files .bat Windows和DOS批处理文件
  • .cmd Windows NT batch files .cmd Windows NT批处理文件
  • .pif Windows shortcuts to DOS executable files .pif Windows到DOS可执行文件的快捷方式

If you go to HKCR\\.xxx (where xxx is any of the above), the "(Default)" value should be xxxfile . 如果转到HKCR\\.xxx (其中xxx是上述任何一项),则“(默认)”值应为xxxfile If you then go to HKCR\\xxxfile\\shell\\open\\command , the "(Default)" value should be "%1" %* . 如果然后转到HKCR\\xxxfile\\shell\\open\\command ,则“((默认)”)值应为"%1" %* Also the "(Default)" value of HKCR\\xxxfile\\shell should be either not set or open . 此外, HKCR\\xxxfile\\shell的“(默认)”值应该未设置或未open

If you have anything else in any of these values, then some program has attempted to insert itself into the execution process. 如果这些值中还有其他任何内容,则说明某个程序已尝试将其自身插入执行过程中。 Viruses sometimes do this ( Sircam , for example). 病毒有时会这样做(例如Sircam )。

您是否尝试过执行cmd.exe并将.cmd文件作为参数传递给它?

hmm try: 嗯试试:

System.Diagnostics.Process myproc = new System.Diagnostics.Process();
myproc.EnableRaisingEvents=false;
myproc.StartInfo.FileName="d:\\a.cmd";
myproc.Start();
MessageBox.Show("did the command");

Have you tested your batch file in the directory, context it's going to run? 您是否已在目录中测试了批处理文件,并且该文件即将运行? The error message with %1 looks like the problem may be in there? 出现%1的错误消息似乎是问题所在?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM