2010-05-26 170 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);