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

(见解决方案)

我不认为这会很难。 我有一个命令文件,d:\ a.cmd,其中包含:

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

但是这些C#行不会执行它:

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

抛出Win32Exception:“%1不是有效的Win32应用程序。”

Process.Start打开.pdf文件…为什么不执行命令文件?

如果我在cmd窗口中输入它,这是有效的:

 cmd /cd:\a.cmd 

Windows XP,MS Visual Studio 2008。

吉姆,提前谢谢

解决方案我只是轻微尴尬:(有一个名为cmd.exe的文件,在我的应用程序的目录中大小为零。我不知道它是如何到达那里但它现在是吐司,上面的两个C#语句现在都有效。我我找了一本哈利波特的书,这样我就可以从多比那里得到一些自我惩罚的想法……

我有四件事你可以试试:

(1)尝试提供cmd.exe的完整路径(例如,在我的机器上: C:\WINDOWS\SYSTEM32\CMD.EXE )。


(2)尝试添加对要执行的命令的call

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

(3)除此之外,我只能猜测Win32Exception %1的来源。 也许您的文件关联设置不正确。

如果在命令行上键入以下内容:

 > 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值可能会引起一些兴趣。 我认为它对应于cmd.exe/d命令行开关,它控制cmd.exe是否尝试使用自定义扩展启动文件。 通常,这是启用的。 也许,在你的机器上,它不是?

或者您可以执行.bat文件 ,然后通过System.Diagnostics.Process.Start()调用此文件。 它不会将输出重定向到控制台应用程序,但它肯定会执行内部命令。

您需要指定进程全名(cmd.exe)。
你应该试试

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

因此,即使cmd.exe位于应用程序目录中,也可以确保执行正确的文件。

你的电脑看起来有点不对劲。 尝试在另一台机器上运行它。 这应该工作。 Process.Start(string)使用ShellExecuteEx来启动文件,因此它与在Explorer中双击文件几乎完全相同,就像你想象的那样。

一个简单的测试对我有用。

B:\ foo.cmd:

来自foo.cmd的@echo你好!
 @暂停

Program.cs中:

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

这按预期工作。

您的错误消息是可疑的,“%1不是有效的Win32应用程序。” 我的注册表在HKCR \ cmdfile \ shell \ open \命令中的值是

"%1" %*

%1被文件名替换,这里可以忽略%* (它表示应该传递任何进一步的命令行参数,但我们现在不关心它)。

启动文件本身以处理此类文件的事实表明Windows本身知道如何启动此类型的文件。 在正常安装Windows时,应以类似方式设置以下扩展:

  • .exe Windows和DOS可执行文件
  • .com DOS“命令”文件
  • .bat Windows和DOS批处理文件
  • .cmd Windows NT批处理文件
  • .pif Windows可执行文件的快捷方式

如果你去HKCR\.xxx (其中xxx是上述任何一个),“(默认)”值应该是xxxfile 。 如果您转到HKCR\xxxfile\shell\open\command ,则“(默认)”值应为"%1" %* 。 此外, HKCR\xxxfile\shell的“(默认)”值应该不设置或open

如果您在这些值中有任何其他值,则某些程序会尝试将自身插入执行过程。 病毒有时会这样做(例如Sircam )。

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

嗯尝试:

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

您是否在目录中测试了批处理文件,它将运行的上下文? %1的错误消息看起来可能在那里?