4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
9 * \author Enrico Forestieri
11 * Full author contact details are available in file CREDITS.
15 * This is a wrapper program to start lyx under windows hiding its
16 * console window. It is adapted from program hidec at
17 * http://www.msfn.org/board/index.php?showtopic=49184&mode=threaded
19 * This wrapper should be named lyx.exe and placed in the same directory
20 * as the real lyx executable which _must_ be renamed as lyxc.exe
23 * hidecmd [VAR=val ...] [<params>]
25 * VAR=val set VAR=val (multiple settings may be specified)
26 * <params> parameters for the real lyx executable
28 * How to build this program:
30 * cl.exe hidecmd.c /GA /O1 /Felyx.exe /link /subsystem:windows \
31 * kernel32.lib advapi32.lib user32.lib libcmt.lib
33 * gcc -mwindows hidecmd.c -o lyx.exe
42 // Using msvc, the following pragmas can reduce executable size from
43 // 44k to 6k. I am not sure if mingw/gcc can take advantage of them
46 // do not link to default libraries
47 #pragma comment(linker,"/NODEFAULTLIB")
48 // unite code and data section (make the program smaller)
49 #pragma comment(linker,"/MERGE:.rdata=.text")
50 // open code section for writing
51 #pragma comment(linker,"/SECTION:.text,EWR")
52 // redefine an entry point of the executable
53 // Must be used, if entry point 'void NewWinMain(void)' is used,
54 // instead of the standart 'int WINAPI WinMain(HINSTANCE hInst, ...)'
55 #pragma comment(linker,"/ENTRY:NewWinMain")
58 #else // mingw/gcc uses this entry point
59 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszCmd, int nCmd)
63 PROCESS_INFORMATION pi;
68 // two " are needed here: the first one quotes the entire
69 // command, the second one the executable name
70 char cmd[1024] = "cmd /c \"\"";
76 char * cmdLine = GetCommandLine();
77 // the name of the executable to be launched
78 // (must be in the same directory)
79 char * lyxc = "lyxc.exe";
81 // When using GetCommandLine(), command name is included
82 // but the full path may be missing, so skip it.
83 if (*cmdLine == '\"') {
88 while (*cmdLine != delim && *cmdLine != 0)
91 if (*cmdLine == delim)
94 // skip over ' ' or '\t'
95 while (*cmdLine != 0 && (*cmdLine == ' ' || *cmdLine == '\t'))
98 // Use GetModuleFileName() to get the path to lyxc.exe
99 GetModuleFileName(0, cmd + i0, sizeof(cmd) / 2);
101 // substitute executable name
102 for (i = i0; cmd[i] != 0; ++i);
104 for (--i; i >= i0 && cmd[i] != '\\' && cmd[i] != '/'; --i);
106 for (++i; *lyxc && i < sizeof(cmd); )
109 // check whether lyxc.exe is there
112 if (GetFileAttributesA(lyxc) == 0xFFFFFFFF) {
113 exitcode = GetLastError();
114 MessageBox(0, lyxc, "Error: cannot find the real LyX executable below", 0);
115 ExitProcess(exitcode);
118 // it's there, so finish quoting filename
121 // parse remainder of command line
122 while (*cmdLine != 0 && !err) {
128 if ((*cmdLine >= 'A' && *cmdLine <= 'Z') ||
129 (*cmdLine >= 'a' && *cmdLine <= 'z'))
136 while (!err && ((*cmdLine != 0 && *cmdLine != ' ' &&
137 *cmdLine != '\t') || inquote))
139 if (*cmdLine == '\"')
140 inquote = 1 - inquote;
142 if (var && *cmdLine == '=' && !inquote)
153 if (var && val && !err) {
154 *val++ = '\0'; // mark end of var
155 if (*val == '\"') { // account for quoted val
159 cmd[i] = '\0'; // mark end of val
160 i = var - cmd - 1; // reset pointer
161 SetEnvironmentVariable(var, val);
162 // MessageBox(0, val, var, 0);
166 while (*cmdLine != 0 && (*cmdLine == ' ' || *cmdLine == '\t'))
170 if (i < sizeof(cmd) - 1) {
171 // finish quoting the entire command
178 MessageBox(0, "Please, use a shorter command line.",
179 "Error: command line is too long", 0);
183 // create process with new console
184 // memset(&si, 0, sizeof(si));
186 for (i = 0; i < sizeof(si); ++i)
189 si.dwFlags = STARTF_USESHOWWINDOW;
190 si.wShowWindow = SW_HIDE;
191 if (CreateProcess(NULL, cmd,
192 NULL, NULL, FALSE, CREATE_NEW_CONSOLE,
193 NULL, NULL, &si, &pi))
195 CloseHandle( pi.hProcess );
196 CloseHandle( pi.hThread );
199 exitcode = GetLastError();
202 ExitProcess(exitcode);