*** empty log message ***
[emacs.git] / nt / runemacs.c
blobafa5340ef53803087fd801491ee3642d70be543f
1 /*
2 Simple program to start Emacs with its console window hidden.
4 This program is provided purely for convenience, since most users will
5 use Emacs in windowing (GUI) mode, and will not want to have an extra
6 console window lying around. */
8 /*
9 You may want to define this if you want to be able to install updated
10 emacs binaries even when other users are using the current version.
11 The problem with some file servers (notably Novell) is that an open
12 file cannot be overwritten, deleted, or even renamed. So if someone
13 is running emacs.exe already, you cannot install a newer version.
14 By defining CHOOSE_NEWEST_EXE, you can name your new emacs.exe
15 something else which matches "emacs*.exe", and runemacs will
16 automatically select the newest emacs executeable in the bin directory.
17 (So you'll probably be able to delete the old version some hours/days
18 later).
21 /* #define CHOOSE_NEWEST_EXE */
23 #include <windows.h>
24 #include <string.h>
25 #include <malloc.h>
27 int WINAPI
28 WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
30 STARTUPINFO start;
31 SECURITY_ATTRIBUTES sec_attrs;
32 SECURITY_DESCRIPTOR sec_desc;
33 PROCESS_INFORMATION child;
34 int wait_for_child = FALSE;
35 DWORD priority_class = NORMAL_PRIORITY_CLASS;
36 DWORD ret_code = 0;
37 char *new_cmdline;
38 char *p;
39 char modname[MAX_PATH];
41 if (!GetModuleFileName (NULL, modname, MAX_PATH))
42 goto error;
43 if ((p = strrchr (modname, '\\')) == NULL)
44 goto error;
45 *p = 0;
47 new_cmdline = alloca (MAX_PATH + strlen (cmdline) + 3);
48 /* Quote executable name in case of spaces in the path. */
49 *new_cmdline = '"';
50 strcpy (new_cmdline + 1, modname);
52 #ifdef CHOOSE_NEWEST_EXE
54 /* Silly hack to allow new versions to be installed on
55 server even when current version is in use. */
57 char * best_name = alloca (MAX_PATH + 1);
58 FILETIME best_time = {0,0};
59 WIN32_FIND_DATA wfd;
60 HANDLE fh;
61 p = new_cmdline + strlen (new_cmdline);
62 strcpy (p, "\\emacs*.exe\" ");
63 fh = FindFirstFile (new_cmdline, &wfd);
64 if (fh == INVALID_HANDLE_VALUE)
65 goto error;
68 if (wfd.ftLastWriteTime.dwHighDateTime > best_time.dwHighDateTime
69 || (wfd.ftLastWriteTime.dwHighDateTime == best_time.dwHighDateTime
70 && wfd.ftLastWriteTime.dwLowDateTime > best_time.dwLowDateTime))
72 best_time = wfd.ftLastWriteTime;
73 strcpy (best_name, wfd.cFileName);
76 while (FindNextFile (fh, &wfd));
77 FindClose (fh);
78 *p++ = '\\';
79 strcpy (p, best_name);
80 strcat (p, " ");
82 #else
83 strcat (new_cmdline, "\\emacs.exe\" ");
84 #endif
86 /* Append original arguments if any; first look for arguments we
87 recognise (-wait, -high, and -low), and apply them ourselves. */
88 while (cmdline[0] == '-' || cmdline[0] == '/')
90 if (strncmp (cmdline+1, "wait", 4) == 0)
92 wait_for_child = TRUE;
93 cmdline += 5;
95 else if (strncmp (cmdline+1, "high", 4) == 0)
97 priority_class = HIGH_PRIORITY_CLASS;
98 cmdline += 5;
100 else if (strncmp (cmdline+1, "low", 3) == 0)
102 priority_class = IDLE_PRIORITY_CLASS;
103 cmdline += 4;
105 else
106 break;
108 strcat (new_cmdline, cmdline);
110 /* Set emacs_dir variable if runemacs was in "%emacs_dir%\bin". */
111 if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
113 *p = 0;
114 for (p = modname; *p; p++)
115 if (*p == '\\') *p = '/';
116 SetEnvironmentVariable ("emacs_dir", modname);
119 memset (&start, 0, sizeof (start));
120 start.cb = sizeof (start);
121 start.dwFlags = STARTF_USESHOWWINDOW;
122 start.wShowWindow = SW_HIDE;
124 sec_attrs.nLength = sizeof (sec_attrs);
125 sec_attrs.lpSecurityDescriptor = NULL;
126 sec_attrs.bInheritHandle = FALSE;
128 if (CreateProcess (NULL, new_cmdline, &sec_attrs, NULL, TRUE, priority_class,
129 NULL, NULL, &start, &child))
131 if (wait_for_child)
133 WaitForSingleObject (child.hProcess, INFINITE);
134 GetExitCodeProcess (child.hProcess, &ret_code);
136 CloseHandle (child.hThread);
137 CloseHandle (child.hProcess);
139 else
140 goto error;
141 return (int) ret_code;
143 error:
144 MessageBox (NULL, "Could not start Emacs.", "Error", MB_ICONSTOP);
145 return 1;
148 /* arch-tag: 7e02df73-4df7-4aa0-baea-99c6d047a384
149 (do not change this comment) */