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

时间:2010-06-11 23:36:57

标签: c# process batch-file

(见解决方案的结尾)

我认为这不会很难。我有一个commmand文件,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 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

我已经为您准备了四件事

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


(2)尝试将call添加到要执行的命令中:

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

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

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

> 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的{​​{1}}命令行开关,它控制cmd.exe是否尝试启动具有自定义扩展名的文件。通常,这是启用的。也许,在你的机器上,它不是吗?

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

您的计算机看起来有问题。尝试在另一台机器上运行它。这个工作。 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可执行文件的快捷方式

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

嗯尝试:

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

答案 6 :(得分:0)

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