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

发布于 2024-09-05 12:52:42 字数 630 浏览 4 评论 0原文

(解决方案见结尾)

我认为这不会很难。我有一个命令文件 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 的文件,大小为零。我不知道它是如何到达那里的,但它现在是 toast 并且上述两个 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:

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

But these lines of C# won't execute it:

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

Throws Win32Exception: "%1 is not a valid Win32 application."

Process.Start opens .pdf files...why not execute command files?

This works if I type it in a cmd window:

cmd /c d:\a.cmd

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

大海や 2024-09-12 12:52:42

我为您提供了四件事供您尝试:

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

I've got four things for you that you can try out:

(1) Try providing the full path for cmd.exe (e.g. on my machine: C:\WINDOWS\SYSTEM32\CMD.EXE).


(2) Try adding call to the command to be executed:

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. 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. 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.)


(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.

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:

//  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. 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. Usually, this is enabled. Maybe, on your machine, it isn't?

拥醉 2024-09-12 12:52:42

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

Or you can do a .bat file, then call this file through System.Diagnostics.Process.Start(). It won't redirect output to Console Application, but it would certainly execute the commands inside.

画中仙 2024-09-12 12:52:42

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

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

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

You need to specify the process full name (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.

北音执念 2024-09-12 12:52:42

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

如果您转到 HKCR\ .xxx(其中 xxx 是上述任意一项),“(默认)”值应为 xxxfile。如果您随后转到 HKCR\xxxfile\shell\open\command,“(默认)”值应为 “%1” %*。此外,HKCR\xxxfile\shell 的“(默认)”值应该不设置或打开

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

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.

A simple test worked for me.

B:\foo.cmd:

@echo Hello from foo.cmd!
@pause

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." The value in my registry at HKCR\cmdfile\shell\open\command is


"%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).

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. On a normal installation of Windows, the following extensions should be set up similarly:

  • .exe Windows and DOS executable files
  • .com DOS "command" files
  • .bat Windows and DOS batch files
  • .cmd Windows NT batch files
  • .pif Windows shortcuts to DOS executable files

If you go to HKCR\.xxx (where xxx is any of the above), the "(Default)" value should be xxxfile. If you then go to HKCR\xxxfile\shell\open\command, the "(Default)" value should be "%1" %*. Also the "(Default)" value of HKCR\xxxfile\shell should be either not set or 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).

瞳孔里扚悲伤 2024-09-12 12:52:42

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

Have you tried executing cmd.exe, and passing the .cmd file to it as an argument?

暖树树初阳… 2024-09-12 12:52:42

嗯尝试:

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

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");
三生路 2024-09-12 12:52:42

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

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文