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 // resolve record in section of code
51 #pragma comment(linker,"/SECTION:.text,EWR")
52 // the new entry point (the WinMain entry point is big)
53 #pragma comment(linker,"/ENTRY:NewWinMain")
56 #else // mingw/gcc uses this entry point
57 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszCmd, int nCmd)
61 PROCESS_INFORMATION pi;
66 // two " are needed here: the first one quotes the entire
67 // command, the second one the executable name
68 char cmd[1024] = "cmd /c \"\"";
74 char * cmdLine = GetCommandLine();
75 // the name of the executable to be launched
76 // (must be in the same directory)
77 char * lyxc = "lyxc.exe";
79 // When using GetCommandLine(), command name is included
80 // but the full path may be missing, so skip it.
81 if (*cmdLine == '\"') {
86 while (*cmdLine != delim && *cmdLine != 0)
89 if (*cmdLine == delim)
92 // skip over ' ' or '\t'
93 while (*cmdLine != 0 && (*cmdLine == ' ' || *cmdLine == '\t'))
96 // Use GetModuleFileName() to get the path to lyxc.exe
97 GetModuleFileName(0, cmd + i0, sizeof(cmd) / 2);
99 // substitute executable name
100 for (i = i0; cmd[i] != 0; ++i);
102 for (--i; i >= i0 && cmd[i] != '\\' && cmd[i] != '/'; --i);
104 for (++i; *lyxc && i < sizeof(cmd); )
107 // check whether lyxc.exe is there
110 if (GetFileAttributesA(lyxc) == 0xFFFFFFFF) {
111 exitcode = GetLastError();
112 MessageBox(0, lyxc, "Error: cannot find the real LyX executable below", 0);
113 ExitProcess(exitcode);
116 // it's there, so finish quoting filename
119 // parse remainder of command line
120 while (*cmdLine != 0 && !err) {
126 if ((*cmdLine >= 'A' && *cmdLine <= 'Z') ||
127 (*cmdLine >= 'a' && *cmdLine <= 'z'))
134 while (!err && ((*cmdLine != 0 && *cmdLine != ' ' &&
135 *cmdLine != '\t') || inquote))
137 if (*cmdLine == '\"')
138 inquote = 1 - inquote;
140 if (var && *cmdLine == '=' && !inquote)
151 if (var && val && !err) {
152 *val++ = '\0'; // mark end of var
153 if (*val == '\"') { // account for quoted val
157 cmd[i] = '\0'; // mark end of val
158 i = var - cmd - 1; // reset pointer
159 SetEnvironmentVariable(var, val);
160 // MessageBox(0, val, var, 0);
164 while (*cmdLine != 0 && (*cmdLine == ' ' || *cmdLine == '\t'))
168 if (i < sizeof(cmd) - 1) {
169 // finish quoting the entire command
176 MessageBox(0, "Please, use a shorter command line.",
177 "Error: command line is too long", 0);
181 // create process with new console
182 // memset(&si, 0, sizeof(si));
184 for (i = 0; i < sizeof(si); ++i)
187 si.dwFlags = STARTF_USESHOWWINDOW;
188 si.wShowWindow = SW_HIDE;
189 if (CreateProcess(NULL, cmd,
190 NULL, NULL, FALSE, CREATE_NEW_CONSOLE,
191 NULL, NULL, &si, &pi))
193 CloseHandle( pi.hProcess );
194 CloseHandle( pi.hThread );
197 exitcode = GetLastError();
200 ExitProcess(exitcode);