3 extern const TCHAR *hook_event_strings[];
\r
4 extern const TCHAR *hook_action_strings[];
\r
6 static enum { NSSM_TAB_APPLICATION, NSSM_TAB_DETAILS, NSSM_TAB_LOGON, NSSM_TAB_DEPENDENCIES, NSSM_TAB_PROCESS, NSSM_TAB_SHUTDOWN, NSSM_TAB_EXIT, NSSM_TAB_IO, NSSM_TAB_ROTATION, NSSM_TAB_ENVIRONMENT, NSSM_TAB_HOOKS, NSSM_NUM_TABS } nssm_tabs;
\r
7 static HWND tablist[NSSM_NUM_TABS];
\r
8 static int selected_tab;
\r
10 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function, LPARAM l) {
\r
11 /* The caller will deal with GetLastError()... */
\r
12 HRSRC resource = FindResourceEx(0, RT_DIALOG, templ, GetUserDefaultLangID());
\r
14 if (GetLastError() != ERROR_RESOURCE_LANG_NOT_FOUND) return 0;
\r
15 resource = FindResourceEx(0, RT_DIALOG, templ, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
\r
16 if (! resource) return 0;
\r
19 HGLOBAL ret = LoadResource(0, resource);
\r
20 if (! ret) return 0;
\r
22 return CreateDialogIndirectParam(0, (DLGTEMPLATE *) ret, parent, function, l);
\r
25 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function) {
\r
26 return dialog(templ, parent, function, 0);
\r
29 static inline void set_logon_enabled(unsigned char interact_enabled, unsigned char credentials_enabled) {
\r
30 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), interact_enabled);
\r
31 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), credentials_enabled);
\r
32 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), credentials_enabled);
\r
33 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), credentials_enabled);
\r
36 int nssm_gui(int resource, nssm_service_t *service) {
\r
38 HWND dlg = dialog(MAKEINTRESOURCE(resource), 0, nssm_dlg, (LPARAM) service);
\r
40 popup_message(0, MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));
\r
44 /* Load the icon. */
\r
45 HANDLE icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
\r
46 if (icon) SendMessage(dlg, WM_SETICON, ICON_SMALL, (LPARAM) icon);
\r
47 icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
\r
48 if (icon) SendMessage(dlg, WM_SETICON, ICON_BIG, (LPARAM) icon);
\r
50 /* Remember what the window is for. */
\r
51 SetWindowLongPtr(dlg, GWLP_USERDATA, (LONG_PTR) resource);
\r
53 /* Display the window */
\r
55 ShowWindow(dlg, SW_SHOW);
\r
57 /* Set service name if given */
\r
58 if (service->name[0]) {
\r
59 SetDlgItemText(dlg, IDC_NAME, service->name);
\r
60 /* No point making user click remove if the name is already entered */
\r
61 if (resource == IDD_REMOVE) {
\r
62 HWND button = GetDlgItem(dlg, IDC_REMOVE);
\r
64 SendMessage(button, WM_LBUTTONDOWN, 0, 0);
\r
65 SendMessage(button, WM_LBUTTONUP, 0, 0);
\r
70 if (resource == IDD_EDIT) {
\r
71 /* We'll need the service handle later. */
\r
72 SetWindowLongPtr(dlg, DWLP_USER, (LONG_PTR) service);
\r
74 /* Service name can't be edited. */
\r
75 EnableWindow(GetDlgItem(dlg, IDC_NAME), 0);
\r
76 SetFocus(GetDlgItem(dlg, IDOK));
\r
78 /* Set existing details. */
\r
82 /* Application tab. */
\r
83 if (service->native) SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->image);
\r
84 else SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe);
\r
85 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir);
\r
86 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags);
\r
89 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname);
\r
90 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description);
\r
91 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
92 SendMessage(combo, CB_SETCURSEL, service->startup, 0);
\r
95 if (service->username) {
\r
96 if (is_virtual_account(service->name, service->username)) {
\r
97 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_VIRTUAL_SERVICE, IDC_VIRTUAL_SERVICE);
\r
98 set_logon_enabled(0, 0);
\r
101 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_VIRTUAL_SERVICE, IDC_ACCOUNT);
\r
102 SetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username);
\r
103 set_logon_enabled(0, 1);
\r
107 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_VIRTUAL_SERVICE, IDC_LOCALSYSTEM);
\r
108 if (service->type & SERVICE_INTERACTIVE_PROCESS) SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_SETCHECK, BST_CHECKED, 0);
\r
111 /* Dependencies tab. */
\r
112 if (service->dependencieslen) {
\r
114 unsigned long newlen;
\r
115 if (format_double_null(service->dependencies, service->dependencieslen, &formatted, &newlen)) {
\r
116 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("nssm_dlg()"));
\r
119 SetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, formatted);
\r
120 HeapFree(GetProcessHeap(), 0, formatted);
\r
125 if (service->priority) {
\r
126 int priority = priority_constant_to_index(service->priority);
\r
127 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
128 SendMessage(combo, CB_SETCURSEL, priority, 0);
\r
131 if (service->affinity) {
\r
132 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
133 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
\r
134 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), 1);
\r
136 DWORD_PTR affinity, system_affinity;
\r
137 if (GetProcessAffinityMask(GetCurrentProcess(), &affinity, &system_affinity)) {
\r
138 if ((service->affinity & (__int64) system_affinity) != service->affinity) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_AFFINITY);
\r
141 for (int i = 0; i < num_cpus(); i++) {
\r
142 if (! (service->affinity & (1LL << (__int64) i))) SendMessage(list, LB_SETSEL, 0, i);
\r
146 if (service->no_console) {
\r
147 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
150 /* Shutdown tab. */
\r
151 if (! (service->stop_method & NSSM_STOP_METHOD_CONSOLE)) {
\r
152 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
153 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE), 0);
\r
155 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, service->kill_console_delay, 0);
\r
156 if (! (service->stop_method & NSSM_STOP_METHOD_WINDOW)) {
\r
157 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_UNCHECKED, 0);
\r
158 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW), 0);
\r
160 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, service->kill_window_delay, 0);
\r
161 if (! (service->stop_method & NSSM_STOP_METHOD_THREADS)) {
\r
162 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_UNCHECKED, 0);
\r
163 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS), 0);
\r
165 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, service->kill_threads_delay, 0);
\r
166 if (! (service->stop_method & NSSM_STOP_METHOD_TERMINATE)) {
\r
167 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
169 if (! service->kill_process_tree) {
\r
170 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
174 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, service->throttle_delay, 0);
\r
175 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
176 SendMessage(combo, CB_SETCURSEL, service->default_exit_action, 0);
\r
177 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, service->restart_delay, 0);
\r
180 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDIN, service->stdin_path);
\r
181 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDOUT, service->stdout_path);
\r
182 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDERR, service->stderr_path);
\r
184 /* Rotation tab. */
\r
185 if (service->stdout_disposition == CREATE_ALWAYS) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_SETCHECK, BST_CHECKED, 0);
\r
186 if (service->rotate_files) {
\r
187 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_SETCHECK, BST_CHECKED, 0);
\r
188 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), 1);
\r
189 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), 1);
\r
190 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), 1);
\r
192 if (service->rotate_stdout_online || service->rotate_stderr_online) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_CHECKED, 0);
\r
193 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);
\r
194 if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);
\r
197 if (service->hook_share_output_handles) SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_CHECKED, 0);
\r
199 /* Check if advanced settings are in use. */
\r
200 if (service->stdout_disposition != service->stderr_disposition || (service->stdout_disposition && service->stdout_disposition != NSSM_STDOUT_DISPOSITION && service->stdout_disposition != CREATE_ALWAYS) || (service->stderr_disposition && service->stderr_disposition != NSSM_STDERR_DISPOSITION && service->stderr_disposition != CREATE_ALWAYS)) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_STDIO);
\r
201 if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);
\r
203 /* Environment tab. */
\r
205 unsigned long envlen;
\r
206 if (service->env_extralen) {
\r
207 env = service->env_extra;
\r
208 envlen = service->env_extralen;
\r
211 env = service->env;
\r
212 envlen = service->envlen;
\r
213 if (envlen) SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_SETCHECK, BST_CHECKED, 0);
\r
218 unsigned long newlen;
\r
219 if (format_double_null(env, envlen, &formatted, &newlen)) {
\r
220 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()"));
\r
223 SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted);
\r
224 HeapFree(GetProcessHeap(), 0, formatted);
\r
227 if (service->envlen && service->env_extralen) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT);
\r
232 while (GetMessage(&message, 0, 0, 0)) {
\r
233 if (IsDialogMessage(dlg, &message)) continue;
\r
234 TranslateMessage(&message);
\r
235 DispatchMessage(&message);
\r
238 return (int) message.wParam;
\r
241 void centre_window(HWND window) {
\r
243 RECT size, desktop_size;
\r
244 unsigned long x, y;
\r
246 if (! window) return;
\r
248 /* Find window size */
\r
249 if (! GetWindowRect(window, &size)) return;
\r
251 /* Find desktop window */
\r
252 desktop = GetDesktopWindow();
\r
253 if (! desktop) return;
\r
255 /* Find desktop window size */
\r
256 if (! GetWindowRect(desktop, &desktop_size)) return;
\r
258 /* Centre window */
\r
259 x = (desktop_size.right - size.right) / 2;
\r
260 y = (desktop_size.bottom - size.bottom) / 2;
\r
261 MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);
\r
264 static inline void check_stop_method(nssm_service_t *service, unsigned long method, unsigned long control) {
\r
265 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) return;
\r
266 service->stop_method &= ~method;
\r
269 static inline void check_number(HWND tab, unsigned long control, unsigned long *timeout) {
\r
271 unsigned long configured = GetDlgItemInt(tab, control, &translated, 0);
\r
272 if (translated) *timeout = configured;
\r
275 static inline void set_timeout_enabled(unsigned long control, unsigned long dependent) {
\r
276 unsigned char enabled = 0;
\r
277 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
278 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], dependent), enabled);
\r
281 static inline void set_affinity_enabled(unsigned char enabled) {
\r
282 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), enabled);
\r
285 static inline void set_rotation_enabled(unsigned char enabled) {
\r
286 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), enabled);
\r
287 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), enabled);
\r
288 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);
\r
291 static inline int hook_env(const TCHAR *hook_event, const TCHAR *hook_action, TCHAR *buffer, unsigned long buflen) {
\r
292 return _sntprintf_s(buffer, buflen, _TRUNCATE, _T("NSSM_HOOK_%s_%s"), hook_event, hook_action);
\r
295 static inline void set_hook_tab(int event_index, int action_index, bool changed) {
\r
296 int first_event = NSSM_GUI_HOOK_EVENT_START;
\r
298 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
299 SendMessage(combo, CB_SETCURSEL, event_index, 0);
\r
300 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_ACTION);
\r
301 SendMessage(combo, CB_RESETCONTENT, 0, 0);
\r
303 const TCHAR *hook_event = hook_event_strings[event_index];
\r
304 TCHAR *hook_action;
\r
306 switch (event_index + first_event) {
\r
307 case NSSM_GUI_HOOK_EVENT_ROTATE:
\r
309 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_PRE));
\r
310 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
311 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_POST));
\r
312 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
315 case NSSM_GUI_HOOK_EVENT_START:
\r
317 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_PRE));
\r
318 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
319 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_POST));
\r
320 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
323 case NSSM_GUI_HOOK_EVENT_STOP:
\r
325 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_STOP_PRE));
\r
326 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
329 case NSSM_GUI_HOOK_EVENT_EXIT:
\r
331 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_EXIT_POST));
\r
332 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
335 case NSSM_GUI_HOOK_EVENT_POWER:
\r
337 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_CHANGE));
\r
338 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_CHANGE;
\r
339 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_RESUME));
\r
340 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_RESUME;
\r
344 SendMessage(combo, CB_SETCURSEL, action_index, 0);
\r
346 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
347 hook_env(hook_event, hook_action, hook_name, _countof(hook_name));
\r
349 if (! *hook_name) return;
\r
351 TCHAR cmd[CMD_LENGTH];
\r
353 GetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd, _countof(cmd));
\r
354 SetEnvironmentVariable(hook_name, cmd);
\r
357 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
358 SetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd);
\r
362 static inline int update_hook(TCHAR *service_name, const TCHAR *hook_event, const TCHAR *hook_action) {
\r
363 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
364 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) return 1;
\r
365 TCHAR cmd[CMD_LENGTH];
\r
366 ZeroMemory(cmd, sizeof(cmd));
\r
367 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
368 if (set_hook(service_name, hook_event, hook_action, cmd)) return 2;
\r
372 static inline int update_hooks(TCHAR *service_name) {
\r
374 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE);
\r
375 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_POST);
\r
376 ret += update_hook(service_name, NSSM_HOOK_EVENT_STOP, NSSM_HOOK_ACTION_PRE);
\r
377 ret += update_hook(service_name, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_ACTION_POST);
\r
378 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_CHANGE);
\r
379 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_RESUME);
\r
380 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_PRE);
\r
381 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_POST);
\r
385 static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {
\r
386 if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;
\r
387 if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;
\r
388 popup_message(owner, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, name);
\r
389 ZeroMemory(buffer, len * sizeof(TCHAR));
\r
392 /* Set service parameters. */
\r
393 int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service) {
\r
394 if (! service) return 1;
\r
396 set_nssm_service_defaults(service);
\r
398 if (orig_service) {
\r
399 service->native = orig_service->native;
\r
400 service->handle = orig_service->handle;
\r
403 /* Get service name. */
\r
404 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
405 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
406 cleanup_nssm_service(service);
\r
410 /* Get executable name */
\r
411 if (! service->native) {
\r
412 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe, _countof(service->exe))) {
\r
413 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
\r
417 /* Get startup directory. */
\r
418 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir, _countof(service->dir))) {
\r
419 _sntprintf_s(service->dir, _countof(service->dir), _TRUNCATE, _T("%s"), service->exe);
\r
420 strip_basename(service->dir);
\r
424 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
\r
425 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags, _countof(service->flags))) {
\r
426 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
\r
433 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME), WM_GETTEXTLENGTH, 0, 0)) {
\r
434 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname, _countof(service->displayname))) {
\r
435 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DISPLAYNAME);
\r
440 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION), WM_GETTEXTLENGTH, 0, 0)) {
\r
441 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description, _countof(service->description))) {
\r
442 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DESCRIPTION);
\r
447 HWND combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
448 service->startup = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
449 if (service->startup == CB_ERR) service->startup = 0;
\r
451 /* Get logon stuff. */
\r
452 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
453 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
454 service->type |= SERVICE_INTERACTIVE_PROCESS;
\r
456 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
457 service->username = 0;
\r
458 service->usernamelen = 0;
\r
459 if (service->password) {
\r
460 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
461 HeapFree(GetProcessHeap(), 0, service->password);
\r
463 service->password = 0;
\r
464 service->passwordlen = 0;
\r
466 else if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_VIRTUAL_SERVICE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
467 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
468 service->username = virtual_account(service->name);
\r
469 if (! service->username) {
\r
470 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
473 service->usernamelen = _tcslen(service->username) + 1;
\r
474 service->password = 0;
\r
475 service->passwordlen = 0;
\r
479 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
480 if (! service->usernamelen) {
\r
481 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
484 service->usernamelen++;
\r
486 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
487 if (! service->username) {
\r
488 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
491 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
492 HeapFree(GetProcessHeap(), 0, service->username);
\r
493 service->username = 0;
\r
494 service->usernamelen = 0;
\r
495 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
500 Special case for well-known accounts.
\r
501 Ignore the password if we're editing and the username hasn't changed.
\r
503 const TCHAR *well_known = well_known_username(service->username);
\r
505 if (str_equiv(well_known, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
506 HeapFree(GetProcessHeap(), 0, service->username);
\r
507 service->username = 0;
\r
508 service->usernamelen = 0;
\r
511 service->usernamelen = _tcslen(well_known) + 1;
\r
512 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
513 if (! service->username) {
\r
514 print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("install()"));
\r
517 memmove(service->username, well_known, service->usernamelen * sizeof(TCHAR));
\r
522 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
523 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
525 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
526 if (! service->passwordlen) {
\r
527 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
530 if (passwordlen != service->passwordlen) {
\r
531 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
534 service->passwordlen++;
\r
536 /* Temporary buffer for password validation. */
\r
537 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
539 HeapFree(GetProcessHeap(), 0, service->username);
\r
540 service->username = 0;
\r
541 service->usernamelen = 0;
\r
542 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
546 /* Actual password buffer. */
\r
547 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
548 if (! service->password) {
\r
549 HeapFree(GetProcessHeap(), 0, password);
\r
550 HeapFree(GetProcessHeap(), 0, service->username);
\r
551 service->username = 0;
\r
552 service->usernamelen = 0;
\r
553 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
557 /* Get first password. */
\r
558 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
559 HeapFree(GetProcessHeap(), 0, password);
\r
560 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
561 HeapFree(GetProcessHeap(), 0, service->password);
\r
562 service->password = 0;
\r
563 service->passwordlen = 0;
\r
564 HeapFree(GetProcessHeap(), 0, service->username);
\r
565 service->username = 0;
\r
566 service->usernamelen = 0;
\r
567 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
571 /* Get confirmation. */
\r
572 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
573 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
574 HeapFree(GetProcessHeap(), 0, password);
\r
575 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
576 HeapFree(GetProcessHeap(), 0, service->password);
\r
577 service->password = 0;
\r
578 service->passwordlen = 0;
\r
579 HeapFree(GetProcessHeap(), 0, service->username);
\r
580 service->username = 0;
\r
581 service->usernamelen = 0;
\r
582 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
587 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
588 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
589 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
590 HeapFree(GetProcessHeap(), 0, password);
\r
591 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
592 HeapFree(GetProcessHeap(), 0, service->password);
\r
593 service->password = 0;
\r
594 service->passwordlen = 0;
\r
595 HeapFree(GetProcessHeap(), 0, service->username);
\r
596 service->username = 0;
\r
597 service->usernamelen = 0;
\r
604 /* Get dependencies. */
\r
605 unsigned long dependencieslen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES), WM_GETTEXTLENGTH, 0, 0);
\r
606 if (dependencieslen) {
\r
607 TCHAR *dependencies = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (dependencieslen + 2) * sizeof(TCHAR));
\r
608 if (! dependencies) {
\r
609 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
610 cleanup_nssm_service(service);
\r
614 if (! GetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, dependencies, dependencieslen + 1)) {
\r
615 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DEPENDENCIES);
\r
616 HeapFree(GetProcessHeap(), 0, dependencies);
\r
617 cleanup_nssm_service(service);
\r
621 if (unformat_double_null(dependencies, dependencieslen, &service->dependencies, &service->dependencieslen)) {
\r
622 HeapFree(GetProcessHeap(), 0, dependencies);
\r
623 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
624 cleanup_nssm_service(service);
\r
628 HeapFree(GetProcessHeap(), 0, dependencies);
\r
631 /* Remaining tabs are only for services we manage. */
\r
632 if (service->native) return 0;
\r
634 /* Get process stuff. */
\r
635 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
636 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
638 service->affinity = 0LL;
\r
639 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
640 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
641 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
642 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
644 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
647 else if (selected < count) {
\r
648 for (int i = 0; i < count; i++) {
\r
649 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
654 if (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->no_console = 0;
\r
655 else service->no_console = 1;
\r
657 /* Get stop method stuff. */
\r
658 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
659 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
660 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
661 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
662 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
663 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
664 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
665 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->kill_process_tree = 1;
\r
666 else service->kill_process_tree = 0;
\r
668 /* Get exit action stuff. */
\r
669 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
670 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
671 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
672 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
673 check_number(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, &service->restart_delay);
\r
675 /* Get I/O stuff. */
\r
676 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
677 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
678 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
680 /* Override stdout and/or stderr. */
\r
681 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
682 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
683 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
686 /* Get rotation stuff. */
\r
687 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
688 service->rotate_files = true;
\r
689 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->rotate_stdout_online = service->rotate_stderr_online = NSSM_ROTATE_ONLINE;
\r
690 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
691 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
694 /* Get hook stuff. */
\r
695 if (SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_GETCHECK, 0, 0) & BST_CHECKED) service->hook_share_output_handles = true;
\r
697 /* Get environment. */
\r
698 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
700 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
702 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
703 cleanup_nssm_service(service);
\r
707 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
708 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
709 HeapFree(GetProcessHeap(), 0, env);
\r
710 cleanup_nssm_service(service);
\r
715 unsigned long newlen;
\r
716 if (unformat_double_null(env, envlen, &newenv, &newlen)) {
\r
717 HeapFree(GetProcessHeap(), 0, env);
\r
718 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
719 cleanup_nssm_service(service);
\r
723 HeapFree(GetProcessHeap(), 0, env);
\r
727 /* Test the environment is valid. */
\r
728 if (test_environment(env)) {
\r
729 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
730 HeapFree(GetProcessHeap(), 0, env);
\r
731 cleanup_nssm_service(service);
\r
735 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
736 service->env = env;
\r
737 service->envlen = envlen;
\r
740 service->env_extra = env;
\r
741 service->env_extralen = envlen;
\r
748 /* Install the service. */
\r
749 int install(HWND window) {
\r
750 if (! window) return 1;
\r
752 nssm_service_t *service = alloc_nssm_service();
\r
754 int ret = configure(window, service, 0);
\r
755 if (ret) return ret;
\r
758 /* See if it works. */
\r
759 switch (install_service(service)) {
\r
761 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
762 cleanup_nssm_service(service);
\r
766 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
767 cleanup_nssm_service(service);
\r
771 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
772 cleanup_nssm_service(service);
\r
776 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
777 cleanup_nssm_service(service);
\r
781 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
782 cleanup_nssm_service(service);
\r
786 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
787 cleanup_nssm_service(service);
\r
791 update_hooks(service->name);
\r
793 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
794 cleanup_nssm_service(service);
\r
798 /* Remove the service */
\r
799 int remove(HWND window) {
\r
800 if (! window) return 1;
\r
802 /* See if it works */
\r
803 nssm_service_t *service = alloc_nssm_service();
\r
805 /* Get service name */
\r
806 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
807 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
808 cleanup_nssm_service(service);
\r
813 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
814 cleanup_nssm_service(service);
\r
819 switch (remove_service(service)) {
\r
821 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
822 cleanup_nssm_service(service);
\r
826 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
827 cleanup_nssm_service(service);
\r
831 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
832 cleanup_nssm_service(service);
\r
836 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
837 cleanup_nssm_service(service);
\r
841 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
842 cleanup_nssm_service(service);
\r
846 int edit(HWND window, nssm_service_t *orig_service) {
\r
847 if (! window) return 1;
\r
849 nssm_service_t *service = alloc_nssm_service();
\r
851 int ret = configure(window, service, orig_service);
\r
852 if (ret) return ret;
\r
855 switch (edit_service(service, true)) {
\r
857 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
858 cleanup_nssm_service(service);
\r
862 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
863 cleanup_nssm_service(service);
\r
867 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
868 cleanup_nssm_service(service);
\r
873 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
874 cleanup_nssm_service(service);
\r
878 update_hooks(service->name);
\r
880 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
881 cleanup_nssm_service(service);
\r
885 static TCHAR *browse_filter(int message) {
\r
887 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
888 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
889 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
890 default: return _T("*.*");
\r
894 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
896 case WM_INITDIALOG:
\r
903 /* Browse for application */
\r
904 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
905 if (! window) return;
\r
908 size_t bufsize = 256;
\r
909 size_t len = bufsize;
\r
913 ZeroMemory(&ofn, sizeof(ofn));
\r
914 ofn.lStructSize = sizeof(ofn);
\r
915 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
916 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
917 if (ofn.lpstrFilter) {
\r
918 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
920 /* "Applications" + NULL + "*.exe" + NULL */
\r
921 va_start(arg, flags);
\r
922 while (i = va_arg(arg, int)) {
\r
923 TCHAR *localised = message_string(i);
\r
924 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
925 len += _tcslen(localised) + 1;
\r
926 LocalFree(localised);
\r
927 TCHAR *filter = browse_filter(i);
\r
928 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
929 len += _tcslen(filter) + 1;
\r
932 /* Remainder of the buffer is already zeroed */
\r
934 ofn.lpstrFile = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, PATH_LENGTH * sizeof(TCHAR));
\r
935 if (ofn.lpstrFile) {
\r
936 if (flags & OFN_NOVALIDATE) {
\r
937 /* Directory hack. */
\r
938 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
939 ofn.nMaxFile = DIR_LENGTH;
\r
942 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T("%s"), current);
\r
943 ofn.nMaxFile = PATH_LENGTH;
\r
946 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
947 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
949 if (GetOpenFileName(&ofn)) {
\r
950 /* Directory hack. */
\r
951 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
952 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
954 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
955 if (ofn.lpstrFile) HeapFree(GetProcessHeap(), 0, ofn.lpstrFile);
\r
958 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
960 case WM_INITDIALOG:
\r
963 /* Button was pressed or control was controlled. */
\r
966 TCHAR buffer[PATH_LENGTH];
\r
967 unsigned char enabled;
\r
969 switch (LOWORD(w)) {
\r
970 /* Browse for application. */
\r
972 dlg = GetDlgItem(tab, IDC_PATH);
\r
973 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
974 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
975 /* Fill in startup directory if it wasn't already specified. */
\r
976 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
978 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
979 strip_basename(buffer);
\r
980 SetDlgItemText(tab, IDC_DIR, buffer);
\r
984 /* Browse for startup directory. */
\r
985 case IDC_BROWSE_DIR:
\r
986 dlg = GetDlgItem(tab, IDC_DIR);
\r
987 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
988 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
992 case IDC_LOCALSYSTEM:
\r
993 set_logon_enabled(1, 0);
\r
996 case IDC_VIRTUAL_SERVICE:
\r
997 set_logon_enabled(0, 0);
\r
1001 set_logon_enabled(0, 1);
\r
1005 case IDC_AFFINITY_ALL:
\r
1006 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
1008 set_affinity_enabled(enabled);
\r
1011 /* Shutdown methods. */
\r
1012 case IDC_METHOD_CONSOLE:
\r
1013 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
1016 case IDC_METHOD_WINDOW:
\r
1017 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
1020 case IDC_METHOD_THREADS:
\r
1021 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
1024 /* Browse for stdin. */
\r
1025 case IDC_BROWSE_STDIN:
\r
1026 dlg = GetDlgItem(tab, IDC_STDIN);
\r
1027 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
1028 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1031 /* Browse for stdout. */
\r
1032 case IDC_BROWSE_STDOUT:
\r
1033 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
1034 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1035 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1036 /* Fill in stderr if it wasn't already specified. */
\r
1037 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1038 if (! buffer[0]) {
\r
1039 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1040 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
1044 /* Browse for stderr. */
\r
1045 case IDC_BROWSE_STDERR:
\r
1046 dlg = GetDlgItem(tab, IDC_STDERR);
\r
1047 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1048 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1053 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
1055 set_rotation_enabled(enabled);
\r
1059 case IDC_HOOK_EVENT:
\r
1060 if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), 0, false);
\r
1063 /* Hook action. */
\r
1064 case IDC_HOOK_ACTION:
\r
1065 if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), (int) SendMessage(GetDlgItem(tab, IDC_HOOK_ACTION), CB_GETCURSEL, 0, 0), false);
\r
1068 /* Browse for hook. */
\r
1069 case IDC_BROWSE_HOOK:
\r
1070 dlg = GetDlgItem(tab, IDC_HOOK);
\r
1071 GetDlgItemText(tab, IDC_HOOK, buffer, _countof(buffer));
\r
1072 browse(dlg, _T(""), OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1077 set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), (int) SendMessage(GetDlgItem(tab, IDC_HOOK_ACTION), CB_GETCURSEL, 0, 0), true);
\r
1086 /* Install/remove dialogue callback */
\r
1087 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
1088 nssm_service_t *service;
\r
1090 switch (message) {
\r
1091 /* Creating the dialogue */
\r
1092 case WM_INITDIALOG:
\r
1093 service = (nssm_service_t *) l;
\r
1095 SetFocus(GetDlgItem(window, IDC_NAME));
\r
1101 tabs = GetDlgItem(window, IDC_TAB1);
\r
1102 if (! tabs) return 0;
\r
1104 /* Set up tabs. */
\r
1106 ZeroMemory(&tab, sizeof(tab));
\r
1107 tab.mask = TCIF_TEXT;
\r
1111 /* Application tab. */
\r
1112 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
1113 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
1114 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1115 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
1116 if (service->native) {
\r
1117 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
1118 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
1119 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
1121 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
1122 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
1124 /* Details tab. */
\r
1125 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
1126 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1127 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
1128 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
1129 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
1131 /* Set defaults. */
\r
1132 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
1133 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
1134 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
1135 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
1136 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
1137 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
1140 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
1141 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1142 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
1143 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
1144 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
1146 /* Set defaults. */
\r
1147 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
1148 set_logon_enabled(1, 0);
\r
1150 /* Dependencies tab. */
\r
1151 tab.pszText = message_string(NSSM_GUI_TAB_DEPENDENCIES);
\r
1152 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1153 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DEPENDENCIES, (LPARAM) &tab);
\r
1154 tablist[NSSM_TAB_DEPENDENCIES] = dialog(MAKEINTRESOURCE(IDD_DEPENDENCIES), window, tab_dlg);
\r
1155 ShowWindow(tablist[NSSM_TAB_DEPENDENCIES], SW_HIDE);
\r
1157 /* Remaining tabs are only for services we manage. */
\r
1158 if (service->native) return 1;
\r
1160 /* Process tab. */
\r
1161 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
1162 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1163 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
1164 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
1165 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
1167 /* Set defaults. */
\r
1168 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
1169 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
1170 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
1171 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
1172 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
1173 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
1174 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
1175 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
1177 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1179 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
1181 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
1182 for (i = 0; i < n; i++) {
\r
1184 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
1185 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
1190 The box is high enough for four rows. It is wide enough for eight
\r
1191 columns without scrolling. With scrollbars it shrinks to two rows.
\r
1192 Note that the above only holds if we set the column width BEFORE
\r
1193 adding the strings.
\r
1196 int columns = (n - 1) / 4;
\r
1198 GetWindowRect(list, &rect);
\r
1199 int width = rect.right - rect.left;
\r
1200 width -= (7 - columns) * 16;
\r
1201 int height = rect.bottom - rect.top;
\r
1202 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
\r
1203 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
1205 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
1207 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
1208 set_affinity_enabled(0);
\r
1210 /* Shutdown tab. */
\r
1211 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
1212 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1213 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
1214 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
1215 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
1217 /* Set defaults. */
\r
1218 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1219 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
1220 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
1221 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
1222 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
1223 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1224 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1225 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_CHECKED, 1);
\r
1227 /* Restart tab. */
\r
1228 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1229 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1230 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1231 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1232 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1234 /* Set defaults. */
\r
1235 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1236 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1237 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1238 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1239 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1240 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1241 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1242 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1245 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1246 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1247 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1248 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1249 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1251 /* Rotation tab. */
\r
1252 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1253 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1254 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1255 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1256 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1258 /* Set defaults. */
\r
1259 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1260 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1261 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1262 set_rotation_enabled(0);
\r
1264 /* Environment tab. */
\r
1265 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1266 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1267 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1268 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1269 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1272 tab.pszText = message_string(NSSM_GUI_TAB_HOOKS);
\r
1273 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1274 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_HOOKS, (LPARAM) &tab);
\r
1275 tablist[NSSM_TAB_HOOKS] = dialog(MAKEINTRESOURCE(IDD_HOOKS), window, tab_dlg);
\r
1276 ShowWindow(tablist[NSSM_TAB_HOOKS], SW_HIDE);
\r
1278 /* Set defaults. */
\r
1279 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
1280 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_START));
\r
1281 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_STOP));
\r
1282 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_EXIT));
\r
1283 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_POWER));
\r
1284 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_ROTATE));
\r
1285 SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1286 if (_tcslen(service->name)) {
\r
1287 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
1288 TCHAR cmd[CMD_LENGTH];
\r
1289 for (i = 0; hook_event_strings[i]; i++) {
\r
1290 const TCHAR *hook_event = hook_event_strings[i];
\r
1292 for (j = 0; hook_action_strings[j]; j++) {
\r
1293 const TCHAR *hook_action = hook_action_strings[j];
\r
1294 if (! valid_hook_name(hook_event, hook_action, true)) continue;
\r
1295 if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) continue;
\r
1296 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) continue;
\r
1297 SetEnvironmentVariable(hook_name, cmd);
\r
1301 set_hook_tab(0, 0, false);
\r
1307 NMHDR *notification;
\r
1309 notification = (NMHDR *) l;
\r
1310 switch (notification->code) {
\r
1311 case TCN_SELCHANGE:
\r
1315 tabs = GetDlgItem(window, IDC_TAB1);
\r
1316 if (! tabs) return 0;
\r
1318 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1319 if (selection != selected_tab) {
\r
1320 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1321 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1322 SetFocus(GetDlgItem(window, IDOK));
\r
1323 selected_tab = selection;
\r
1330 /* Button was pressed or control was controlled */
\r
1332 switch (LOWORD(w)) {
\r
1335 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1336 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1338 else if (! install(window)) PostQuitMessage(0);
\r
1341 /* Cancel button */
\r
1343 DestroyWindow(window);
\r
1346 /* Remove button */
\r
1348 if (! remove(window)) PostQuitMessage(0);
\r
1353 /* Window closing */
\r
1355 DestroyWindow(window);
\r
1358 PostQuitMessage(0);
\r