windows 如何绕过命令行长度限制?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2916865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:32:11  来源:igfitidea点击:

How to get around the command line length limit?

c#windowscommand-line

提问by Crash893

I've been working on a small and simple program that I drop files onto and, based on certian rules, they are moved to diffrent places.

我一直在开发一个小而简单的程序,我将文件放到它上面,然后根据特定规则,将它们移动到不同的地方。

The program works fine unless I drop more than a few files, then it kicks back an error (that appears to be more Windows than anything) that the start up command "c:\myapp.exe \file \file \file" is too long.

除非我删除多个文件,否则该程序运行良好,然后它会返回一个错误(似乎比任何 Windows 都多)启动命令“c:\myapp.exe\file\file\file”也是错误的长。

I realize I could set up a background proccess, but I really would prefer that this program not run in the backround (where it would be idle most of the time).

我意识到我可以设置一个后台进程,但我真的希望这个程序不在后台运行(它大部分时间都处于空闲状态)。

Is there a way around this limitation?

有没有办法绕过这个限制?

采纳答案by Oleg

If you want to drop files with respect of Windows Explorer, then you can implement your own Drop Handlers as a Shell Extension Handlers see:

如果您想删除与 Windows 资源管理器相关的文件,那么您可以实现自己的删除处理程序作为 Shell 扩展处理程序,请参见:

On The Complete Idiot's Guide to Writing Shell Extensionsyou will find a good introduction how to write such extensions.

The Complete Idiot's Guide to Writing Shell Extensions你会找到一个很好的介绍如何编写这样的扩展。

The part VIgives an example of Drop Handler (for a little other use case, but it dose not matter).

VI 部分给出了 Drop Handler 的示例(对于其他一些用例,但无关紧要)。

With respect of Drop Shell Extension Handler your program will receive full information about all dropped files and you need not start a child program with all the files as command like parameters.

关于 Drop Shell 扩展处理程序,您的程序将收到有关所有已删除文件的完整信息,并且您无需使用所有文件作为命令(如参数)启动子程序。

回答by GnP

From this blog:

这个博客

  • The maximum command line length for the CreateProcess function is 32767 characters. This limitation comes from the UNICODE_STRING structure.
  • If you are using the CMD.EXE command processor, then you are also subject to the 8192 character command line length limit imposed by CMD.EXE.
  • If you are using the ShellExecute/Ex function, then you become subject to the INTERNET_MAX_URL_LENGTH (around 2048) command line length limit imposed by the ShellExecute/Ex functions.
  • The maximum size of your environment is 32767 characters. The size of the environment includes all the variable names plus all the values.
  • CreateProcess 函数的最大命令行长度为 32767 个字符。此限制来自 UNICODE_STRING 结构。
  • 如果您使用的是 CMD.EXE 命令处理器,那么您还受到 CMD.EXE 施加的 8192 字符命令行长度限制。
  • 如果您使用的是 ShellExecute/Ex 函数,那么您将受到 ShellExecute/Ex 函数施加的 INTERNET_MAX_URL_LENGTH(大约 2048 年)命令行长度限制的约束。
  • 您的环境的最大大小为 32767 个字符。环境的大小包括所有变量名和所有值。

So you're gonna have to settle with some of the mentioned workarounds (also, there's another workaround on the msdn blog I linked).

因此,您将不得不解决一些提到的解决方法(此外,我链接的 msdn 博客上还有另一种解决方法)。

回答by mdma

I think the drag and drop handler is possibly one way to go, but it seems quite heavy.

我认为拖放处理程序可能是一种方法,但它似乎很重。

An alternative solution is to use a Explorer Context Menu handler. With this in place, you would select all the files, but rather than dragging them, right click, and choose your new menu item "Send to ".

另一种解决方案是使用资源管理器上下文菜单处理程序。有了这个,您将选择所有文件,而不是拖动它们,右键单击并选择新菜单项“发送到”。

When the menu item is selected, it passes the list of commands to your program. There are a couple of ways of doing this:

选择菜单项后,它会将命令列表传递给您的程序。有几种方法可以做到这一点:

  1. launch your program, and feed the list of files to standard input
  2. write the list of files to a temporary file, and launch your program with just one command argument - the temporary file listing the files to process. List files are usually prefixed with '@' on the command line to distinguish them from ordinary file names.
  1. 启动您的程序,并将文件列表提供给标准输入
  2. 将文件列表写入临时文件,然后仅使用一个命令参数启动程序 - 列出要处理的文件的临时文件。列表文件在命令行中通常以“@”为前缀,以区别于普通文件名。

回答by kurt

How to get around the command line length limit? Write your whole command to a batch file, e.g. to "C:\Users\Johnny\Documents\mybatch.bat". Write it as you would in the cmd (no need to escape anything). Then, in your code simply call that file:

如何绕过命令行长度限制?将整个命令写入批处理文件,例如“C:\Users\Johnny\Documents\mybatch.bat”。像在 cmd 中一样编写它(无需转义任何内容)。然后,在您的代码中只需调用该文件:

strCmdText = "C:\Users\Johnny\Documents\mybatch.bat";

ProcessStartInfo ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + strCmdText);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;

Process.Start(ProcessInfo);

回答by Biff MaGriff

I experienced a similar issue when I was trying to get security details on a long path. My solution was to map drives whenever the path length got too long. Check out my solution on How do I get the security details for a long path?

当我试图在很长的路径上获取安全详细信息时,我遇到了类似的问题。我的解决方案是在路径长度过长时映射驱动器。查看我的解决方案 如何获取长路径的安全详细信息?

回答by Jason

Unix commands frequently have one or two parameters that can be of unbounded length. Several of these commands have added parameters which can source those arguments from a file, or from standard input. So you have one command which gins up the list of arguments, and either pipes them to a temporary file, or pipes them to stdout.

Unix 命令经常有一个或两个可以无限长度的参数。其中一些命令添加了参数,这些参数可以从文件或标准输入中获取这些参数。因此,您有一个命令可以生成参数列表,并将它们通过管道传输到临时文件,或者通过管道传输到标准输出。

See also, xargs, which can take a list of arguments and either invoke your command with all of the parameters, or in batches.

另请参阅 xargs,它可以采用参数列表,并使用所有参数或批量调用您的命令。

回答by Robert Williams

I'd modify the application to pick up the files from a specific location (e.g. specific folder on a filesystem) rather than specifying each file on the command line.

我会修改应用程序以从特定位置(例如文件系统上的特定文件夹)获取文件,而不是在命令行上指定每个文件。

UPDATE:

更新:

If the requirement is to be able to drag an item onto an .exe via Windows Explorer to start the application as Mark mentioned then you could put all of your files into one folder and drop the entire folder on the .exe.

如果要求能够通过 Windows 资源管理器将项目拖到 .exe 上以启动 Mark 提到的应用程序,那么您可以将所有文件放入一个文件夹中,然后将整个文件夹放在 .exe 上。

回答by Tim Lloyd

When the files are drag&dropped onto your application write the list of files names out to a text file, then give the location of this file to your program. The target program can then read in this file and process it line-by-line. This way you only ever pass a single file name.

当文件被拖放到您的应用程序上时,将文件名列表写入文本文件,然后将该文件的位置提供给您的程序。然后目标程序可以读入这个文件并逐行处理它。这样你只需要传递一个文件名。

回答by Jesse Webb

I think the easiest solution is to modify your application to accept a directory as the parameter as opposed to a list of files. This would allow you to copy the multiple files into a single directory. You can then drag and drop the folder onto your executable. It would then run a command like "c:\myapp.exe \folder-with-files-in-it" which should not run into the command line parameter limitation that you are experiencing now.

我认为最简单的解决方案是修改您的应用程序以接受目录作为参数,而不是文件列表。这将允许您将多个文件复制到一个目录中。然后,您可以将该文件夹拖放到您的可执行文件上。然后它会运行像“c:\myapp.exe \folder-with-files-in-it”这样的命令,它不应该遇到你现在遇到的命令行参数限制。