views:

526

answers:

8

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.

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?

+1  A: 

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.

Robert Williams
yea thats what is an option but it would require it to run in the background
Crash893
When you say you "...simple program that i drop files onto..." do you mean a GUI window that you're dropping the files on?You could manually start the application when needed, or set up a new Task within the Task Scheduler to run your application on a periodic basis.
Robert Williams
@Robert: No, I think he means dragging and dropping the files onto the .exe through windows explorer.
Mark
correct - Drop the files onto the exe icon on the desktop for example
Crash893
@Crash893: Please see my edited answer to see if it is a viable option for you.
Robert Williams
+1  A: 

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.

chibacity
Drag and droping the files is for conveniences. I don't think that adding the names to a text file would be more convenient
Crash893
Ah I see you have provided clarification to some of the other answerers, I thought you were dropping onto a GUI app you had written where you could just handle the drop data. I did not realize you were going through the shell.
chibacity
+1  A: 

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.

Gweebz
not as bad as running it in the background but not as stream lined as selecting a few files and dropping it on. the downside is that it could still not fix the problem depending on the length of the path of the folder. +1 for the idea
Crash893
I was under the impression that you were reaching the limit of allowed command line arguments, NOT the limit of the command itself. I guess I misunderstood. Do you (or anyone else) know what the limit actually is?
Gweebz
+11  A: 

If you want to drop files with respect of Windows Explorer, than you can implement your own Drop Handlers as a Shell Extension Handlers (see http://msdn.microsoft.com/en-us/library/cc144165(VS.85).aspx and http://msdn.microsoft.com/en-us/library/bb776797.aspx). On http://www.codeproject.com/kb/shell/shellextguideindex.aspx you will find a good introduction how to write such extensions. The part VI (see http://www.codeproject.com/kb/shell/ShellExtGuide6.aspx) gives an example of Drop Handler (for a little other use case, but it dose not matter).

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.

Oleg
sorry i spaced out on this question thanks ill try it out. Since i don't have time to test it right now and you have the most votes you get the bounty
Crash893
+1  A: 

Hello,

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 http://stackoverflow.com/questions/2450604/how-do-i-get-the-security-details-for-a-long-path

Biff MaGriff
+1  A: 

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.

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

Jason
+6  A: 

From [0]:

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

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

[0] http://blogs.msdn.com/b/oldnewthing/archive/2003/12/10/56028.aspx

gnp
+2  A: 

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