2010-05-26 168 views
17

我一直在研究一个小而简单的程序,将文件拖放到基于certian规则的文件上,并将它们移动到不同的地方。如何解决命令行长度限制?

该程序工作正常,除非我删除超过几个文件,然后它踢回一个错误(这似乎是比任何其他更多的Windows)启动命令“C:\ myapp.exe \文件\文件\文件“太长。我知道我可以设置一个后台进程,但是我真的更喜欢这个程序不在后台运行(大部分时间它都会处于空闲状态)。

有没有办法解决这个限制?

回答

14

如果您希望删除Windows资源管理器的文件,则可以将自己的Drop Handler作为Shell Extension Handlers(请参阅http://msdn.microsoft.com/en-us/library/cc144165(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/bb776797.aspx)。在http://www.codeproject.com/kb/shell/shellextguideindex.aspx你会发现一个很好的介绍如何编写这样的扩展。第六部分(见http://www.codeproject.com/kb/shell/ShellExtGuide6.aspx)给出了一个Drop Handler的例子(对于其他一些用例,但没有关系)。

就Drop Shell Extension Handler而言,您的程序将收到有关所有丢弃文件的完整信息,您无需启动一个包含所有文件的子程序,就像参数一样。

+0

对不起,我在这个问题上感谢你,谢谢你试用它。由于我现在没有时间对其进行测试,并且获得了最多的选票,因此您可以获得奖励 – Crash893 2010-07-01 21:57:09

+0

我们应该使用什么样的cl子? – SepehrM 2015-01-18 13:27:23

+1

@SepehrM:如果我正确理解你的话,你只需要生成一个新的唯一GUID并将其用作你的Shell扩展处理程序的clsid。只需在Visual Studio中选择“工具”/“创建GUID”菜单即可启动该实用程序,这有助于生成新的唯一GUID。 – Oleg 2015-01-18 18:46:10

1

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

UPDATE:

如果要求是能够项目拖到通过Windows资源管理器的.exe马克提到的,那么你可以把你所有的文件到一个文件夹拖放到启动应用程序整个.exe文件夹。

+0

啊那是什么是一个选项,但它需要它在后台 – Crash893 2010-05-26 21:18:59

+1

当你说你” ......简单的程序,我将文件拖放至运行.. 。“你的意思是一个你放置文件的GUI窗口? 您可以在需要时手动启动应用程序,或者在任务计划程序中设置一个新任务以定期运行应用程序。 – 2010-05-26 21:26:02

+0

不,我想他是指通过Windows资源管理器将文件拖放到.exe上。 – mpen 2010-05-26 21:35:58

1

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

+2

拖放文件是为了方便。我不认为将这些名称添加到文本文件会更方便 – Crash893 2010-05-27 02:43:45

+0

啊我看到您已经向其他一些答复者提供了说明,我认为您已经放入了一个您已经编写的GUI应用程序,您可以在其中处理丢弃数据。我没有意识到你正在经历壳。 – 2010-05-29 22:22:50

1

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

+0

并不像在后台运行它那么糟糕,但并不像选择几个文件并将其丢弃一样流。缺点是它依然可能无法解决问题,这取决于文件夹路径的长度。+1的想法 – Crash893 2010-06-02 18:32:44

+0

我的印象是你已经达到了允许的命令行参数的限制,而不是命令本身的限制。我想我误解了。你(或其他人)知道实际上的限制是什么吗? – 2010-06-02 19:14:34

1

Unix命令通常有一个或两个参数,可以是无限的长度。其中几个命令添加了可以从文件或标准输入来源参数的参数。因此,您有一个命令可以查看参数列表,并将它们传输到临时文件,或者将它们传输到标准输出。

另请参见xargs,它可以获取参数列表并以所有参数或分批方式调用您的命令。

14

this blog

  • 为CreateProcess函数的最大命令行长度是32767个字符。这个限制来自UNICODE_STRING结构。
  • 如果您使用的是CMD.EXE命令处理器,那么您还受CMD.EXE施加的8192字符命令行长度限制的限制。
  • 如果使用ShellExecute/Ex函数,那么您将受到ShellExecute/Ex函数施加的INTERNET_MAX_URL_LENGTH(大约2048)命令行长度限制的约束。
  • 您的环境的最大尺寸为32767个字符。环境的大小包括所有变量名称和所有值。

所以,你将不得不解决一些上述解决方法(另外,还有另一个解决方法,我链接的msdn博客)。

2

我认为拖放处理程序可能是一种可行的方式,但它看起来很重。

另一种解决方案是使用资源管理器上下文菜单处理程序。完成此操作后,您将选择所有文件,但不是拖动它们,请右键单击,然后选择新的菜单项“发送到”。

当选择菜单项时,它会将命令列表传递给您的程序。有一对夫妇的这样做的方法:

  1. 启动程序,和饲料的文件列表,以标准输入
  2. 文件列表写入到一个临时文件,并只用一个命令启动程序参数 - 列出要处理的文件的临时文件。列表文件通常在命令行上以“@”作为前缀,以区别于普通文件名。
1

如何避开命令行长度限制?将整个命令写入批处理文件,例如到“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);