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->usernamelen = _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN) + _tcslen(service->name) + 2;
\r
469 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
470 if (! service->username) {
\r
471 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
474 _sntprintf_s(service->username, service->usernamelen, _TRUNCATE, _T("%s\\%s"), NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, service->name);
\r
475 service->password = 0;
\r
476 service->passwordlen = 0;
\r
480 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
481 if (! service->usernamelen) {
\r
482 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
485 service->usernamelen++;
\r
487 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
488 if (! service->username) {
\r
489 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
492 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
493 HeapFree(GetProcessHeap(), 0, service->username);
\r
494 service->username = 0;
\r
495 service->usernamelen = 0;
\r
496 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
501 Special case for well-known accounts.
\r
502 Ignore the password if we're editing and the username hasn't changed.
\r
504 const TCHAR *well_known = well_known_username(service->username);
\r
506 if (str_equiv(well_known, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
507 HeapFree(GetProcessHeap(), 0, service->username);
\r
508 service->username = 0;
\r
509 service->usernamelen = 0;
\r
512 service->usernamelen = _tcslen(well_known) + 1;
\r
513 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
514 if (! service->username) {
\r
515 print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("install()"));
\r
518 memmove(service->username, well_known, service->usernamelen * sizeof(TCHAR));
\r
523 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
524 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
526 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
527 if (! service->passwordlen) {
\r
528 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
531 if (passwordlen != service->passwordlen) {
\r
532 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
535 service->passwordlen++;
\r
537 /* Temporary buffer for password validation. */
\r
538 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
540 HeapFree(GetProcessHeap(), 0, service->username);
\r
541 service->username = 0;
\r
542 service->usernamelen = 0;
\r
543 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
547 /* Actual password buffer. */
\r
548 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
549 if (! service->password) {
\r
550 HeapFree(GetProcessHeap(), 0, password);
\r
551 HeapFree(GetProcessHeap(), 0, service->username);
\r
552 service->username = 0;
\r
553 service->usernamelen = 0;
\r
554 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
558 /* Get first password. */
\r
559 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
560 HeapFree(GetProcessHeap(), 0, password);
\r
561 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
562 HeapFree(GetProcessHeap(), 0, service->password);
\r
563 service->password = 0;
\r
564 service->passwordlen = 0;
\r
565 HeapFree(GetProcessHeap(), 0, service->username);
\r
566 service->username = 0;
\r
567 service->usernamelen = 0;
\r
568 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
572 /* Get confirmation. */
\r
573 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
574 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
575 HeapFree(GetProcessHeap(), 0, password);
\r
576 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
577 HeapFree(GetProcessHeap(), 0, service->password);
\r
578 service->password = 0;
\r
579 service->passwordlen = 0;
\r
580 HeapFree(GetProcessHeap(), 0, service->username);
\r
581 service->username = 0;
\r
582 service->usernamelen = 0;
\r
583 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
588 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
589 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
590 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
591 HeapFree(GetProcessHeap(), 0, password);
\r
592 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
593 HeapFree(GetProcessHeap(), 0, service->password);
\r
594 service->password = 0;
\r
595 service->passwordlen = 0;
\r
596 HeapFree(GetProcessHeap(), 0, service->username);
\r
597 service->username = 0;
\r
598 service->usernamelen = 0;
\r
605 /* Get dependencies. */
\r
606 unsigned long dependencieslen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES), WM_GETTEXTLENGTH, 0, 0);
\r
607 if (dependencieslen) {
\r
608 TCHAR *dependencies = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (dependencieslen + 2) * sizeof(TCHAR));
\r
609 if (! dependencies) {
\r
610 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
611 cleanup_nssm_service(service);
\r
615 if (! GetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, dependencies, dependencieslen + 1)) {
\r
616 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DEPENDENCIES);
\r
617 HeapFree(GetProcessHeap(), 0, dependencies);
\r
618 cleanup_nssm_service(service);
\r
622 if (unformat_double_null(dependencies, dependencieslen, &service->dependencies, &service->dependencieslen)) {
\r
623 HeapFree(GetProcessHeap(), 0, dependencies);
\r
624 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
625 cleanup_nssm_service(service);
\r
629 HeapFree(GetProcessHeap(), 0, dependencies);
\r
632 /* Remaining tabs are only for services we manage. */
\r
633 if (service->native) return 0;
\r
635 /* Get process stuff. */
\r
636 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
637 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
639 service->affinity = 0LL;
\r
640 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
641 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
642 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
643 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
645 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
648 else if (selected < count) {
\r
649 for (int i = 0; i < count; i++) {
\r
650 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
655 if (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->no_console = 0;
\r
656 else service->no_console = 1;
\r
658 /* Get stop method stuff. */
\r
659 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
660 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
661 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
662 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
663 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
664 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
665 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
666 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->kill_process_tree = 1;
\r
667 else service->kill_process_tree = 0;
\r
669 /* Get exit action stuff. */
\r
670 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
671 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
672 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
673 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
674 check_number(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, &service->restart_delay);
\r
676 /* Get I/O stuff. */
\r
677 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
678 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
679 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
681 /* Override stdout and/or stderr. */
\r
682 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
683 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
684 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
687 /* Get rotation stuff. */
\r
688 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
689 service->rotate_files = true;
\r
690 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
691 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
692 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
695 /* Get hook stuff. */
\r
696 if (SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_GETCHECK, 0, 0) & BST_CHECKED) service->hook_share_output_handles = true;
\r
698 /* Get environment. */
\r
699 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
701 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
703 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
704 cleanup_nssm_service(service);
\r
708 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
709 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
710 HeapFree(GetProcessHeap(), 0, env);
\r
711 cleanup_nssm_service(service);
\r
716 unsigned long newlen;
\r
717 if (unformat_double_null(env, envlen, &newenv, &newlen)) {
\r
718 HeapFree(GetProcessHeap(), 0, env);
\r
719 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
720 cleanup_nssm_service(service);
\r
724 HeapFree(GetProcessHeap(), 0, env);
\r
728 /* Test the environment is valid. */
\r
729 if (test_environment(env)) {
\r
730 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
731 HeapFree(GetProcessHeap(), 0, env);
\r
732 cleanup_nssm_service(service);
\r
736 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
737 service->env = env;
\r
738 service->envlen = envlen;
\r
741 service->env_extra = env;
\r
742 service->env_extralen = envlen;
\r
749 /* Install the service. */
\r
750 int install(HWND window) {
\r
751 if (! window) return 1;
\r
753 nssm_service_t *service = alloc_nssm_service();
\r
755 int ret = configure(window, service, 0);
\r
756 if (ret) return ret;
\r
759 /* See if it works. */
\r
760 switch (install_service(service)) {
\r
762 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
763 cleanup_nssm_service(service);
\r
767 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
768 cleanup_nssm_service(service);
\r
772 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
773 cleanup_nssm_service(service);
\r
777 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
778 cleanup_nssm_service(service);
\r
782 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
783 cleanup_nssm_service(service);
\r
787 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
788 cleanup_nssm_service(service);
\r
792 update_hooks(service->name);
\r
794 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
795 cleanup_nssm_service(service);
\r
799 /* Remove the service */
\r
800 int remove(HWND window) {
\r
801 if (! window) return 1;
\r
803 /* See if it works */
\r
804 nssm_service_t *service = alloc_nssm_service();
\r
806 /* Get service name */
\r
807 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
808 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
809 cleanup_nssm_service(service);
\r
814 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
815 cleanup_nssm_service(service);
\r
820 switch (remove_service(service)) {
\r
822 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
823 cleanup_nssm_service(service);
\r
827 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
828 cleanup_nssm_service(service);
\r
832 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
833 cleanup_nssm_service(service);
\r
837 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
838 cleanup_nssm_service(service);
\r
842 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
843 cleanup_nssm_service(service);
\r
847 int edit(HWND window, nssm_service_t *orig_service) {
\r
848 if (! window) return 1;
\r
850 nssm_service_t *service = alloc_nssm_service();
\r
852 int ret = configure(window, service, orig_service);
\r
853 if (ret) return ret;
\r
856 switch (edit_service(service, true)) {
\r
858 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
859 cleanup_nssm_service(service);
\r
863 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
864 cleanup_nssm_service(service);
\r
868 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
869 cleanup_nssm_service(service);
\r
874 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
875 cleanup_nssm_service(service);
\r
879 update_hooks(service->name);
\r
881 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
882 cleanup_nssm_service(service);
\r
886 static TCHAR *browse_filter(int message) {
\r
888 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
889 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
890 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
891 default: return _T("*.*");
\r
895 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
897 case WM_INITDIALOG:
\r
904 /* Browse for application */
\r
905 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
906 if (! window) return;
\r
909 size_t bufsize = 256;
\r
910 size_t len = bufsize;
\r
914 ZeroMemory(&ofn, sizeof(ofn));
\r
915 ofn.lStructSize = sizeof(ofn);
\r
916 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
917 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
918 if (ofn.lpstrFilter) {
\r
919 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
921 /* "Applications" + NULL + "*.exe" + NULL */
\r
922 va_start(arg, flags);
\r
923 while (i = va_arg(arg, int)) {
\r
924 TCHAR *localised = message_string(i);
\r
925 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
926 len += _tcslen(localised) + 1;
\r
927 LocalFree(localised);
\r
928 TCHAR *filter = browse_filter(i);
\r
929 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
930 len += _tcslen(filter) + 1;
\r
933 /* Remainder of the buffer is already zeroed */
\r
935 ofn.lpstrFile = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, PATH_LENGTH * sizeof(TCHAR));
\r
936 if (ofn.lpstrFile) {
\r
937 if (flags & OFN_NOVALIDATE) {
\r
938 /* Directory hack. */
\r
939 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
940 ofn.nMaxFile = DIR_LENGTH;
\r
943 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T("%s"), current);
\r
944 ofn.nMaxFile = PATH_LENGTH;
\r
947 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
948 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
950 if (GetOpenFileName(&ofn)) {
\r
951 /* Directory hack. */
\r
952 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
953 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
955 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
956 if (ofn.lpstrFile) HeapFree(GetProcessHeap(), 0, ofn.lpstrFile);
\r
959 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
961 case WM_INITDIALOG:
\r
964 /* Button was pressed or control was controlled. */
\r
967 TCHAR buffer[PATH_LENGTH];
\r
968 unsigned char enabled;
\r
970 switch (LOWORD(w)) {
\r
971 /* Browse for application. */
\r
973 dlg = GetDlgItem(tab, IDC_PATH);
\r
974 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
975 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
976 /* Fill in startup directory if it wasn't already specified. */
\r
977 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
979 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
980 strip_basename(buffer);
\r
981 SetDlgItemText(tab, IDC_DIR, buffer);
\r
985 /* Browse for startup directory. */
\r
986 case IDC_BROWSE_DIR:
\r
987 dlg = GetDlgItem(tab, IDC_DIR);
\r
988 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
989 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
993 case IDC_LOCALSYSTEM:
\r
994 set_logon_enabled(1, 0);
\r
997 case IDC_VIRTUAL_SERVICE:
\r
998 set_logon_enabled(0, 0);
\r
1002 set_logon_enabled(0, 1);
\r
1006 case IDC_AFFINITY_ALL:
\r
1007 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
1009 set_affinity_enabled(enabled);
\r
1012 /* Shutdown methods. */
\r
1013 case IDC_METHOD_CONSOLE:
\r
1014 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
1017 case IDC_METHOD_WINDOW:
\r
1018 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
1021 case IDC_METHOD_THREADS:
\r
1022 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
1025 /* Browse for stdin. */
\r
1026 case IDC_BROWSE_STDIN:
\r
1027 dlg = GetDlgItem(tab, IDC_STDIN);
\r
1028 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
1029 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1032 /* Browse for stdout. */
\r
1033 case IDC_BROWSE_STDOUT:
\r
1034 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
1035 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1036 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1037 /* Fill in stderr if it wasn't already specified. */
\r
1038 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1039 if (! buffer[0]) {
\r
1040 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1041 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
1045 /* Browse for stderr. */
\r
1046 case IDC_BROWSE_STDERR:
\r
1047 dlg = GetDlgItem(tab, IDC_STDERR);
\r
1048 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1049 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1054 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
1056 set_rotation_enabled(enabled);
\r
1060 case IDC_HOOK_EVENT:
\r
1061 if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), 0, false);
\r
1064 /* Hook action. */
\r
1065 case IDC_HOOK_ACTION:
\r
1066 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
1069 /* Browse for hook. */
\r
1070 case IDC_BROWSE_HOOK:
\r
1071 dlg = GetDlgItem(tab, IDC_HOOK);
\r
1072 GetDlgItemText(tab, IDC_HOOK, buffer, _countof(buffer));
\r
1073 browse(dlg, _T(""), OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1078 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
1087 /* Install/remove dialogue callback */
\r
1088 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
1089 nssm_service_t *service;
\r
1091 switch (message) {
\r
1092 /* Creating the dialogue */
\r
1093 case WM_INITDIALOG:
\r
1094 service = (nssm_service_t *) l;
\r
1096 SetFocus(GetDlgItem(window, IDC_NAME));
\r
1102 tabs = GetDlgItem(window, IDC_TAB1);
\r
1103 if (! tabs) return 0;
\r
1105 /* Set up tabs. */
\r
1107 ZeroMemory(&tab, sizeof(tab));
\r
1108 tab.mask = TCIF_TEXT;
\r
1112 /* Application tab. */
\r
1113 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
1114 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
1115 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1116 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
1117 if (service->native) {
\r
1118 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
1119 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
1120 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
1122 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
1123 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
1125 /* Details tab. */
\r
1126 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
1127 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1128 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
1129 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
1130 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
1132 /* Set defaults. */
\r
1133 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
1134 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
1135 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
1136 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
1137 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
1138 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
1141 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
1142 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1143 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
1144 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
1145 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
1147 /* Set defaults. */
\r
1148 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
1149 set_logon_enabled(1, 0);
\r
1151 /* Dependencies tab. */
\r
1152 tab.pszText = message_string(NSSM_GUI_TAB_DEPENDENCIES);
\r
1153 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1154 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DEPENDENCIES, (LPARAM) &tab);
\r
1155 tablist[NSSM_TAB_DEPENDENCIES] = dialog(MAKEINTRESOURCE(IDD_DEPENDENCIES), window, tab_dlg);
\r
1156 ShowWindow(tablist[NSSM_TAB_DEPENDENCIES], SW_HIDE);
\r
1158 /* Remaining tabs are only for services we manage. */
\r
1159 if (service->native) return 1;
\r
1161 /* Process tab. */
\r
1162 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
1163 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1164 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
1165 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
1166 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
1168 /* Set defaults. */
\r
1169 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
1170 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
1171 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
1172 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
1173 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
1174 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
1175 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
1176 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
1178 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1180 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
1182 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
1183 for (i = 0; i < n; i++) {
\r
1185 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
1186 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
1191 The box is high enough for four rows. It is wide enough for eight
\r
1192 columns without scrolling. With scrollbars it shrinks to two rows.
\r
1193 Note that the above only holds if we set the column width BEFORE
\r
1194 adding the strings.
\r
1197 int columns = (n - 1) / 4;
\r
1199 GetWindowRect(list, &rect);
\r
1200 int width = rect.right - rect.left;
\r
1201 width -= (7 - columns) * 16;
\r
1202 int height = rect.bottom - rect.top;
\r
1203 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
\r
1204 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
1206 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
1208 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
1209 set_affinity_enabled(0);
\r
1211 /* Shutdown tab. */
\r
1212 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
1213 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1214 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
1215 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
1216 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
1218 /* Set defaults. */
\r
1219 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1220 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
1221 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
1222 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
1223 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
1224 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1225 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1226 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_CHECKED, 1);
\r
1228 /* Restart tab. */
\r
1229 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1230 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1231 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1232 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1233 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1235 /* Set defaults. */
\r
1236 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1237 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1238 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1239 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1240 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1241 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1242 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1243 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1246 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1247 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1248 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1249 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1250 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1252 /* Rotation tab. */
\r
1253 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1254 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1255 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1256 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1257 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1259 /* Set defaults. */
\r
1260 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1261 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1262 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1263 set_rotation_enabled(0);
\r
1265 /* Environment tab. */
\r
1266 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1267 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1268 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1269 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1270 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1273 tab.pszText = message_string(NSSM_GUI_TAB_HOOKS);
\r
1274 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1275 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_HOOKS, (LPARAM) &tab);
\r
1276 tablist[NSSM_TAB_HOOKS] = dialog(MAKEINTRESOURCE(IDD_HOOKS), window, tab_dlg);
\r
1277 ShowWindow(tablist[NSSM_TAB_HOOKS], SW_HIDE);
\r
1279 /* Set defaults. */
\r
1280 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
1281 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_START));
\r
1282 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_STOP));
\r
1283 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_EXIT));
\r
1284 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_POWER));
\r
1285 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_ROTATE));
\r
1286 SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1287 if (_tcslen(service->name)) {
\r
1288 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
1289 TCHAR cmd[CMD_LENGTH];
\r
1290 for (i = 0; hook_event_strings[i]; i++) {
\r
1291 const TCHAR *hook_event = hook_event_strings[i];
\r
1293 for (j = 0; hook_action_strings[j]; j++) {
\r
1294 const TCHAR *hook_action = hook_action_strings[j];
\r
1295 if (! valid_hook_name(hook_event, hook_action, true)) continue;
\r
1296 if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) continue;
\r
1297 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) continue;
\r
1298 SetEnvironmentVariable(hook_name, cmd);
\r
1302 set_hook_tab(0, 0, false);
\r
1308 NMHDR *notification;
\r
1310 notification = (NMHDR *) l;
\r
1311 switch (notification->code) {
\r
1312 case TCN_SELCHANGE:
\r
1316 tabs = GetDlgItem(window, IDC_TAB1);
\r
1317 if (! tabs) return 0;
\r
1319 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1320 if (selection != selected_tab) {
\r
1321 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1322 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1323 SetFocus(GetDlgItem(window, IDOK));
\r
1324 selected_tab = selection;
\r
1331 /* Button was pressed or control was controlled */
\r
1333 switch (LOWORD(w)) {
\r
1336 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1337 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1339 else if (! install(window)) PostQuitMessage(0);
\r
1342 /* Cancel button */
\r
1344 DestroyWindow(window);
\r
1347 /* Remove button */
\r
1349 if (! remove(window)) PostQuitMessage(0);
\r
1354 /* Window closing */
\r
1356 DestroyWindow(window);
\r
1359 PostQuitMessage(0);
\r