如何从C#执行批处理文件?
(解决方案见结尾) 我不认为这会很难。我有一个commmand文件,d:\a.cmd,其中包含:如何从C#执行批处理文件?,c#,process,batch-file,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"); 引发Win32异常:“%1不是有效的Win32应用程序。” Process.Start打开.pdf文件…为什么不执行
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");
引发Win32异常:“%1不是有效的Win32应用程序。”
Process.Start打开.pdf文件…为什么不执行命令文件
如果我在cmd窗口中键入它,则此选项有效:
cmd /c d:\a.cmd
WindowsXP,微软VisualStudio2008
提前感谢,,
吉姆
解决方案
我只是有点尴尬:(我的应用程序目录中有一个名为cmd.exe的文件,大小为零。我不知道它是如何到达那里的,但现在它是toast,上面的两个C#语句现在都起作用了。我要去找一本哈利波特的书,这样我可以从多比那里得到一些自我惩罚的想法…你有没有尝试执行
cmd.exe
,并将.cmd文件作为参数传递给它?或者,然后通过System.Diagnostics.Process.Start()
调用此文件。它不会将输出重定向到控制台应用程序,但肯定会执行其中的命令。我有四件事供您尝试:
(1)尝试提供cmd.exe
的完整路径(例如,在我的机器上:C:\WINDOWS\SYSTEM32\cmd.exe
)
(2)尝试将
调用添加到要执行的命令中:
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\U LOCAL\U machine\SOFTWARE\Microsoft\Command Processor
在我的Windows XP计算机上(以及您的进程.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
是否尝试启动具有自定义扩展名的文件。通常,这是启用的。也许,在您的计算机上,它不是?您需要指定过程ss全名(cmd.exe)。
你应该试试
Environment.GetFolderPath(Environment.SpecialFolder.System) + "cmd.exe"
因此,即使应用程序目录中有cmd.exe,也可以确保执行正确的文件。hmm请尝试:
System.Diagnostics.Process myproc = new System.Diagnostics.Process();
myproc.EnableRaisingEvents=false;
myproc.StartInfo.FileName="d:\\a.cmd";
myproc.Start();
MessageBox.Show("did the command");
您的计算机似乎有问题。请尝试在另一台计算机上运行此操作。这应该可以正常工作。Process.Start(string)
使用ShellExecuteEx
启动文件,因此这与您所设想的在资源管理器中双击文件几乎是一样的
一个简单的测试对我有效
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
DOS可执行文件的Windows快捷方式
如果您转到HKCR\.xxx
(其中xxx
是上述任何一项),“(默认)”值应为xxxfile
。如果您随后转到HKCR\xxxfile\shell\open\command
,则“(默认)”值应为%1”%*
。也是“(默认值)”HKCR\xxxfile\shell
的值不应设置或打开
如果这些值中有其他值,则某些程序试图将自身插入执行过程。病毒有时会这样做(例如).您是否在将要运行的目录上下文中测试了批处理文件?带有%1的错误消息看起来可能存在问题?是否关联了.cmd
文件?(双击它们是否运行?)还有,您只是在.bat
文件上使用了错误的扩展名,还是有什么不同?在Windows资源管理器中双击a.cmd确实会执行它,我认为Process.Start与该操作类似。您的代码很好。我以前用Process.Start(“my.cmd”);以这种方式运行过很多批处理。出于好奇,在批处理中运行命令时会发生什么情况?例如:Process.Start(“复制/b d:\7zS.sfx+d:\config.txt+d:\files.7z d:\setup.exe”);@fatcat1111:理论上,这不应该起作用,因为copy
是cmd.exe
的内置命令,因此不能在其外部调用。@fatcat1111:在这种情况下,您必须使用两个参数版本:Process.Start(“cmd.exe”,“copy/b…”)
ShellExecuteEx
不知道如何运行命令处理器的内置程序,如copy
、dir
、echo
,等等。是的,(请参阅我对Johannes Rossel的评论)。
@echo Hello from foo.cmd!
@pause
class Program{
static void Main(){
System.Diagnostics.Process.Start("B:\\foo.cmd");
}
}