Update development/Win32/hidecmd.c, from Enrico Forestieri

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
This commit is contained in:
Bo Peng 2006-07-27 16:39:27 +00:00
parent 3181082c31
commit 60fa713737

View File

@ -12,39 +12,34 @@
*/
/**
* 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
*
* Usage:
* hidecmd [/w] [/VAR=val] <filename> [<params>]
* where: /w wait for program termination
* /VAR=val set VAR=val
* <filename> executable program
* <params> program parameters
* 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
*
* 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
* Usage:
* hidecmd [VAR=val ...] [<params>]
* where:
* VAR=val set VAR=val (multiple settings may be specified)
* <params> parameters for the real lyx executable
*
* 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];
int err = 0;
char * cmdLine = GetCommandLine();
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;
// start and end of variable/value
char * s;
char * e;
int err = 0;
int inquote;
char * cmdLine = GetCommandLine();
// 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 {
if (*cmdLine == '\"')
inquote = 1 - inquote;
if (var && *cmdLine == '=' && !inquote)
val = cmd + i;
if (i < sizeof(cmd))
cmd[i++] = *cmdLine;
else
err = 1;
cmdLine++;
}
// get var
s = var;
e = s + sizeof(var) - 1;
while (*cmdLine != 0 && *cmdLine != '=') {
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;
}
// get value
*s = 0;
if (*cmdLine == '=')
cmdLine++;
delim = ' ';
if (*cmdLine == '\"') {
delim = '\"';
cmdLine++;
}
s = val;
e = s + sizeof(val) - 1;
while (*cmdLine != delim && *cmdLine != 0) {
if (s < e) {
*s++ = *cmdLine++;
} else {
cmdLine++;
err = 1;
}
}
*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 );
}