]> git.lyx.org Git - features.git/commitdiff
Update development/Win32/hidecmd.c, from Enrico Forestieri
authorBo Peng <bpeng@lyx.org>
Thu, 27 Jul 2006 16:39:27 +0000 (16:39 +0000)
committerBo Peng <bpeng@lyx.org>
Thu, 27 Jul 2006 16:39:27 +0000 (16:39 +0000)
The usage of hidecmd.c is now 'lyx.exe [var=val] [other lyx options]'
The realy console lyx.exe should be renamed to lyxc.exe.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14502 a592a061-630c-0410-9148-cb99ea01b6c8

development/Win32/hidecmd.c

index ad9710ad47b291da5e340b546f46f6dd73db06a6..19fcbafbf19f85a072b8067c939f8a47cbe793f1 100644 (file)
  */
 
 /**
- *  This utility function is used to start lyx under windows, but
- *  hide the console window. It is adapted from program hidec at
+ *  This is a wrapper program to start lyx under windows hiding its
+ *  console window. It is adapted from program hidec at
  *  http://www.msfn.org/board/index.php?showtopic=49184&mode=threaded
  *
+ *  This wrapper should be named lyx.exe and placed in the same directory
+ *  as the real lyx executable which _must_ be renamed as lyxc.exe
+ *
  *  Usage: 
- *     hidecmd [/w] [/VAR=val] <filename> [<params>]
- *  where: /w           wait for program termination
- *             /VAR=val        set VAR=val
- *             <filename>  executable program
- *             <params>        program parameters
+ *      hidecmd [VAR=val ...] [<params>]
+ *  where:
+ *         VAR=val    set VAR=val (multiple settings may be specified)
+ *         <params>   parameters for the real lyx executable
  *
- *  How to built this program:
- *  msvc:
- *     cl.exe hidecmd.c /GA /O1 /link /subsystem:windows \
- *        kernel32.lib advapi32.lib user32.lib libcmt.lib
- *  mingw/gcc:
- *     gcc -mno-cygwin -mwindows hidecmd.c -o hidecmd
+ *  How to build this program:
+ *    msvc:
+ *         cl.exe hidecmd.c /GA /O1 /Felyx.exe /link /subsystem:windows \
+ *                kernel32.lib advapi32.lib user32.lib libcmt.lib
+ *    mingw/gcc:
+ *     gcc -mwindows hidecmd.c -o lyx.exe
  *
  */
 
 #include <process.h>
 #include <windows.h>
 
-
-char * usage = "hidecmd [/w] [/VAR=val] <filename> [<params>]\n"
-       "  where: /w             wait for program termination\n"
-       "               /VAR=val        set VAR=val\n"
-       "               <filename>  executable program\n"
-       "               <params>        program parameters\n";
-
 #ifdef _MSC_VER
 //
-// Using msvc, the following progma can reduce executable size from
+// Using msvc, the following pragmas can reduce executable size from
 // 44k to 6k. I am not sure if mingw/gcc can take advantage of them
 // though.
 //
@@ -64,19 +59,25 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszCmd, int nCmd)
 {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
-       int bWait = 0;
        DWORD exitcode = 0;
        char delim = ' ';
-       char var[128];
-       char val[128];
+       char * var;
+       char * val;
+       // two " are needed here: the first one quotes the entire
+       // command, the second one the executable name
+       char cmd[1024] = "cmd /c \"\"";
+       //  i0 = strlen(cmd);
+       int i0 = 9;
+       int i;
        int err = 0;
+       int inquote;
        char * cmdLine = GetCommandLine();
-       int i;
-       // start and end of variable/value
-       char * s;
-       char * e;
+       // the name of the executable to be launched
+       // (must be in the same directory)
+       char * lyxc = "lyxc.exe";
 
-       // use GetCommandLine(), command name is included. Skip it
+       // When using GetCommandLine(), command name is included
+       // but the full path may be missing, so skip it.
        if (*cmdLine == '\"') {
                delim = '\"';
                cmdLine++;
@@ -89,95 +90,106 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszCmd, int nCmd)
                cmdLine++;
 
        // skip over ' ' or '\t'
-       while ((*cmdLine != 0) && ((*cmdLine == ' ') || (*cmdLine == '\t')))
+       while (*cmdLine != 0 && (*cmdLine == ' ' || *cmdLine == '\t'))
                cmdLine++; 
 
-       while (*cmdLine == '/') {
-               // /w or /W option
-               if (((cmdLine[1] == 'w') || (cmdLine[1] == 'W')) &&
-                       (cmdLine[2] == ' '))
+       // Use GetModuleFileName() to get the path to lyxc.exe
+       GetModuleFileName(0, cmd + i0, sizeof(cmd) / 2);
+
+       // substitute executable name
+       for (i = i0; cmd[i] != 0; ++i);
+
+       for (--i; i >= i0 && cmd[i] != '\\' && cmd[i] != '/'; --i);
+
+       for (++i; *lyxc && i < sizeof(cmd); )
+               cmd[i++] = *lyxc++;
+
+       // check whether lyxc.exe is there
+       cmd[i] = '\0';
+       lyxc = cmd + i0;
+       if (GetFileAttributesA(lyxc) == 0xFFFFFFFF) {
+               exitcode = GetLastError();
+               MessageBox(0, lyxc, "Error: cannot find the real LyX executable below", 0);
+               ExitProcess(exitcode);
+       }
+
+       // it's there, so finish quoting filename
+       cmd[i++] = '\"';
+
+       // parse remainder of command line
+       while (*cmdLine != 0 && !err) {
+               if (i < sizeof(cmd))
+                       cmd[i++] = ' ';
+               else
+                       err = 1;
+
+               if ((*cmdLine >= 'A' && *cmdLine <= 'Z') ||
+                   (*cmdLine >= 'a' && *cmdLine <= 'z'))
+                       var = cmd + i;
+               else
+                       var = NULL;
+
+               val = NULL;
+               inquote = 0;
+               while (!err && ((*cmdLine != 0 && *cmdLine != ' ' &&
+                               *cmdLine != '\t') || inquote))
                {
-                       bWait = 1;
-                       cmdLine += 3;
-               // environment variable
-               } else {
-                       cmdLine++;
+                       if (*cmdLine == '\"')
+                               inquote = 1 - inquote;
 
-                       // get var
-                       s = var;
-                       e = s + sizeof(var) - 1;
-                       
-                       while (*cmdLine != 0 && *cmdLine != '=') {
-                               if (s < e) {
-                                       *s++ = *cmdLine++;
-                               } else {
-                                       cmdLine++;
-                                       err = 1;
-                               }
-                       }
+                       if (var && *cmdLine == '=' && !inquote)
+                               val = cmd + i;
 
-                       // get value
-                       *s = 0;
-                       if (*cmdLine == '=')
-                               cmdLine++;
+                       if (i < sizeof(cmd))
+                               cmd[i++] = *cmdLine;
+                       else
+                               err = 1;
 
-                       delim = ' ';
-                       
-                       if (*cmdLine == '\"') {
-                               delim = '\"';
-                               cmdLine++;
-                       }
+                       cmdLine++;
+               }
 
-                       s = val;
-                       e = s + sizeof(val) - 1;
-                       
-                       while (*cmdLine != delim && *cmdLine != 0) {
-                               if (s < e) {
-                                       *s++ = *cmdLine++;
-                               } else {
-                                       cmdLine++;
-                                       err = 1;
-                               }
+               if (var && val && !err) {
+                       *val++ = '\0';          // mark end of var
+                       if (*val == '\"') {     // account for quoted val
+                               ++val;
+                               --i;
                        }
-                       *s = 0;
-                       if (*cmdLine == delim)
-                               cmdLine++;
-
+                       cmd[i] = '\0';          // mark end of val
+                       i = var - cmd - 1;      // reset pointer
                        SetEnvironmentVariable(var, val);
                        // MessageBox(0, val, var, 0);
                }
 
                // skip spaces
-               while ((*cmdLine != 0) && ((*cmdLine == ' ') || (*cmdLine == '\t'))) 
+               while (*cmdLine != 0 && (*cmdLine == ' ' || *cmdLine == '\t')) 
                        cmdLine++;
        }
 
-       // report error if there is no parameter 
-       if (*cmdLine == 0)
-       {
-               MessageBox(0, usage, "Error: Incorrect usage", 0);
-               ExitProcess(0);
-       }
+       if (i < sizeof(cmd) - 1) {
+               // finish quoting the entire command
+               cmd[i++] = '\"';
+               cmd[i] = '\0';
+       } else
+               err = 1;
        
        if (err) {
-               MessageBox(0, "One of the specified environment variables or its value is too long.", "Error: Variable name or value too long", 0);
+               MessageBox(0, "Please, use a shorter command line.",
+                               "Error: command line is too long", 0);
                ExitProcess(0);
        }
 
        // create process with new console
        // memset(&si, 0, sizeof(si));
-       s = (char *) &si;
+       val = (char *) &si;
        for (i = 0; i < sizeof(si); ++i)
-               s[i] = 0x00;
+               val[i] = 0x00;
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;
-       if (CreateProcess(NULL, cmdLine,
+       if (CreateProcess(NULL, cmd,
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE,
                NULL, NULL, &si, &pi))
        {
-               if (bWait) 
-                       WaitForSingleObject(pi.hProcess, INFINITE);
                CloseHandle( pi.hProcess );
                CloseHandle( pi.hThread );
        }