On 6/27/2011 9:38 AM, Andrey Repin wrote: >> As you are apparently using the cmd "shell", the correct way to quote >> arguments in order to preserve spaces etc, is to use double quotes >> and escape all backslashes with an extra backslash. > > Ok, please explain, how could I escape backslashes in, say, Explorer? > It could only quote the string. > I can't even write my own conversion utility :/ > No amount of external conversion would help using diff or patch freely.
Well, here's the thing: on win32, GUI apps (those compiled for the GUI subsystem) have a different "entry point" than command line ones (those compiled for the CUI subsystem. The GUI ones actually use 'WinMain' as an entry point, while the CUI ones follow the tradition 'int main(int argc, char * argv[])' entry point (actually, thanks to a quirk of the C, it is int main(int argc, char * argv[], char * envp[]) but usually the third argument is null). Anyway, since the signature of WinMain is int CALLBACK WinMain( __in HINSTANCE hInstance, __in HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nCmdShow ); the "command line arguments" are passed in as one giant command line, and parsing it is up the program itself. Now, *cygwin* programs are usually CUI, but their actual entry point is mainCRTStartup, regardless of whether they are compiled for the CUI or GUI subsystem. This function is defined in cygwin1.dll; it does a lot of stuff, but eventually converts the "big cmd line string" to an argv[] array, and calls the user's main() function. This process of converting "the big cmd line string" is done according to *unix* quoting rules. There's also a 'stub' main() that does the opposite: if your app defines a WinMain but no main(), then the stub main gets the "big cmd line string" via GetCommandLine (e.g. it ignores whatever argv[] was passed in) and invokes your WinMain using that big string. See http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/how-startup-shutdown-works.txt?rev=1.1&content-type=text/x-cvsweb-markup&cvsroot=src for more info. So, what's the point? I think ONE way of solving your problem is to write a wrapper program, that will *ignore* argv[]. It should grab the full cmd line using GetCommandLine(), properly quote it using *win32* quoting rules -- and then invoke the cygwin program you want to run (*) using main(argc, argv). Then, cygwin's parsing routines will Do The Right Thing for you. Here's some code to get you started: http://sourceforge.net/projects/mingw/files/UserContributed/execwrap/Current%20Release_%20mingw-execwrap-1.0/ (*) In order to bypass the cygwin parsing rules, this wrapper program should be a native (that is, non cygwin) application. Now, why is this so hard? Well, you've got to realize, what you are trying to do is WAY outside the normal usage pattern for cygwin tools. In general, we try to make sure that cygwin tools work "in the unix way" -- and often, that means they need to be invoked via a unix style shell. Sometimes, invoking directly from the Win32 GUI point-n-click arena just doesn't work as expected -- as you have discovered. That's why so few cygwin apps install GUI-style shortcuts into the Start Menu. If you look, most of the one that do fall into three categories: (1) shells - like Cygwin.bat or bash (2) terminals, like rxvt or mintty (3) X apps that take no cmd line arguments. -- Chuck -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple