3 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
4 static HWND tablist[NSSM_NUM_TABS];
\r
5 static const TCHAR *hook_event_strings[] = { NSSM_HOOK_EVENT_START, NSSM_HOOK_EVENT_STOP, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_EVENT_ROTATE, NULL };
\r
6 static const TCHAR *hook_action_strings[] = { NSSM_HOOK_ACTION_PRE, NSSM_HOOK_ACTION_POST, NSSM_HOOK_ACTION_CHANGE, NSSM_HOOK_ACTION_RESUME, NULL };
\r
7 static int selected_tab;
\r
9 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function, LPARAM l) {
\r
10 /* The caller will deal with GetLastError()... */
\r
11 HRSRC resource = FindResourceEx(0, RT_DIALOG, templ, GetUserDefaultLangID());
\r
13 if (GetLastError() != ERROR_RESOURCE_LANG_NOT_FOUND) return 0;
\r
14 resource = FindResourceEx(0, RT_DIALOG, templ, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
\r
15 if (! resource) return 0;
\r
18 HGLOBAL ret = LoadResource(0, resource);
\r
19 if (! ret) return 0;
\r
21 return CreateDialogIndirectParam(0, (DLGTEMPLATE *) ret, parent, function, l);
\r
24 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function) {
\r
25 return dialog(templ, parent, function, 0);
\r
28 int nssm_gui(int resource, nssm_service_t *service) {
\r
30 HWND dlg = dialog(MAKEINTRESOURCE(resource), 0, nssm_dlg, (LPARAM) service);
\r
32 popup_message(0, MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));
\r
36 /* Load the icon. */
\r
37 HANDLE icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
\r
38 if (icon) SendMessage(dlg, WM_SETICON, ICON_SMALL, (LPARAM) icon);
\r
39 icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
\r
40 if (icon) SendMessage(dlg, WM_SETICON, ICON_BIG, (LPARAM) icon);
\r
42 /* Remember what the window is for. */
\r
43 SetWindowLongPtr(dlg, GWLP_USERDATA, (LONG_PTR) resource);
\r
45 /* Display the window */
\r
47 ShowWindow(dlg, SW_SHOW);
\r
49 /* Set service name if given */
\r
50 if (service->name[0]) {
\r
51 SetDlgItemText(dlg, IDC_NAME, service->name);
\r
52 /* No point making user click remove if the name is already entered */
\r
53 if (resource == IDD_REMOVE) {
\r
54 HWND button = GetDlgItem(dlg, IDC_REMOVE);
\r
56 SendMessage(button, WM_LBUTTONDOWN, 0, 0);
\r
57 SendMessage(button, WM_LBUTTONUP, 0, 0);
\r
62 if (resource == IDD_EDIT) {
\r
63 /* We'll need the service handle later. */
\r
64 SetWindowLongPtr(dlg, DWLP_USER, (LONG_PTR) service);
\r
66 /* Service name can't be edited. */
\r
67 EnableWindow(GetDlgItem(dlg, IDC_NAME), 0);
\r
68 SetFocus(GetDlgItem(dlg, IDOK));
\r
70 /* Set existing details. */
\r
74 /* Application tab. */
\r
75 if (service->native) SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->image);
\r
76 else SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe);
\r
77 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir);
\r
78 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags);
\r
81 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname);
\r
82 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description);
\r
83 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
84 SendMessage(combo, CB_SETCURSEL, service->startup, 0);
\r
87 if (service->username) {
\r
88 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_ACCOUNT);
\r
89 SetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username);
\r
90 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), 0);
\r
91 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), 1);
\r
92 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), 1);
\r
93 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), 1);
\r
96 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
97 if (service->type & SERVICE_INTERACTIVE_PROCESS) SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_SETCHECK, BST_CHECKED, 0);
\r
100 /* Dependencies tab. */
\r
101 if (service->dependencieslen) {
\r
103 unsigned long newlen;
\r
104 if (format_double_null(service->dependencies, service->dependencieslen, &formatted, &newlen)) {
\r
105 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("nssm_dlg()"));
\r
108 SetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, formatted);
\r
109 HeapFree(GetProcessHeap(), 0, formatted);
\r
114 if (service->priority) {
\r
115 int priority = priority_constant_to_index(service->priority);
\r
116 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
117 SendMessage(combo, CB_SETCURSEL, priority, 0);
\r
120 if (service->affinity) {
\r
121 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
122 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
\r
123 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), 1);
\r
125 DWORD_PTR affinity, system_affinity;
\r
126 if (GetProcessAffinityMask(GetCurrentProcess(), &affinity, &system_affinity)) {
\r
127 if ((service->affinity & (__int64) system_affinity) != service->affinity) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_AFFINITY);
\r
130 for (int i = 0; i < num_cpus(); i++) {
\r
131 if (! (service->affinity & (1LL << (__int64) i))) SendMessage(list, LB_SETSEL, 0, i);
\r
135 if (service->no_console) {
\r
136 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
139 /* Shutdown tab. */
\r
140 if (! (service->stop_method & NSSM_STOP_METHOD_CONSOLE)) {
\r
141 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
142 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE), 0);
\r
144 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, service->kill_console_delay, 0);
\r
145 if (! (service->stop_method & NSSM_STOP_METHOD_WINDOW)) {
\r
146 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_UNCHECKED, 0);
\r
147 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW), 0);
\r
149 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, service->kill_window_delay, 0);
\r
150 if (! (service->stop_method & NSSM_STOP_METHOD_THREADS)) {
\r
151 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_UNCHECKED, 0);
\r
152 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS), 0);
\r
154 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, service->kill_threads_delay, 0);
\r
155 if (! (service->stop_method & NSSM_STOP_METHOD_TERMINATE)) {
\r
156 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
158 if (! service->kill_process_tree) {
\r
159 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
163 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, service->throttle_delay, 0);
\r
164 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
165 SendMessage(combo, CB_SETCURSEL, service->default_exit_action, 0);
\r
166 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, service->restart_delay, 0);
\r
169 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDIN, service->stdin_path);
\r
170 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDOUT, service->stdout_path);
\r
171 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDERR, service->stderr_path);
\r
173 /* Rotation tab. */
\r
174 if (service->stdout_disposition == CREATE_ALWAYS) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_SETCHECK, BST_CHECKED, 0);
\r
175 if (service->rotate_files) {
\r
176 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_SETCHECK, BST_CHECKED, 0);
\r
177 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), 1);
\r
178 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), 1);
\r
179 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), 1);
\r
181 if (service->rotate_stdout_online || service->rotate_stderr_online) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_CHECKED, 0);
\r
182 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);
\r
183 if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);
\r
185 /* Check if advanced settings are in use. */
\r
186 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
187 if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);
\r
189 /* Environment tab. */
\r
191 unsigned long envlen;
\r
192 if (service->env_extralen) {
\r
193 env = service->env_extra;
\r
194 envlen = service->env_extralen;
\r
197 env = service->env;
\r
198 envlen = service->envlen;
\r
199 if (envlen) SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_SETCHECK, BST_CHECKED, 0);
\r
204 unsigned long newlen;
\r
205 if (format_double_null(env, envlen, &formatted, &newlen)) {
\r
206 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()"));
\r
209 SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted);
\r
210 HeapFree(GetProcessHeap(), 0, formatted);
\r
213 if (service->envlen && service->env_extralen) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT);
\r
218 while (GetMessage(&message, 0, 0, 0)) {
\r
219 if (IsDialogMessage(dlg, &message)) continue;
\r
220 TranslateMessage(&message);
\r
221 DispatchMessage(&message);
\r
224 return (int) message.wParam;
\r
227 void centre_window(HWND window) {
\r
229 RECT size, desktop_size;
\r
230 unsigned long x, y;
\r
232 if (! window) return;
\r
234 /* Find window size */
\r
235 if (! GetWindowRect(window, &size)) return;
\r
237 /* Find desktop window */
\r
238 desktop = GetDesktopWindow();
\r
239 if (! desktop) return;
\r
241 /* Find desktop window size */
\r
242 if (! GetWindowRect(desktop, &desktop_size)) return;
\r
244 /* Centre window */
\r
245 x = (desktop_size.right - size.right) / 2;
\r
246 y = (desktop_size.bottom - size.bottom) / 2;
\r
247 MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);
\r
250 static inline void check_stop_method(nssm_service_t *service, unsigned long method, unsigned long control) {
\r
251 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) return;
\r
252 service->stop_method &= ~method;
\r
255 static inline void check_number(HWND tab, unsigned long control, unsigned long *timeout) {
\r
257 unsigned long configured = GetDlgItemInt(tab, control, &translated, 0);
\r
258 if (translated) *timeout = configured;
\r
261 static inline void set_timeout_enabled(unsigned long control, unsigned long dependent) {
\r
262 unsigned char enabled = 0;
\r
263 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
264 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], dependent), enabled);
\r
267 static inline void set_logon_enabled(unsigned char enabled) {
\r
268 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), ! enabled);
\r
269 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), enabled);
\r
270 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), enabled);
\r
271 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), enabled);
\r
274 static inline void set_affinity_enabled(unsigned char enabled) {
\r
275 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), enabled);
\r
278 static inline void set_rotation_enabled(unsigned char enabled) {
\r
279 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), enabled);
\r
280 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), enabled);
\r
281 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);
\r
284 static inline int hook_env(const TCHAR *hook_event, const TCHAR *hook_action, TCHAR *buffer, unsigned long buflen) {
\r
285 return _sntprintf_s(buffer, buflen, _TRUNCATE, _T("NSSM_HOOK_%s_%s"), hook_event, hook_action);
\r
288 static inline void set_hook_tab(int event_index, int action_index, bool changed) {
\r
289 int first_event = NSSM_GUI_HOOK_EVENT_START;
\r
291 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
292 SendMessage(combo, CB_SETCURSEL, event_index, 0);
\r
293 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_ACTION);
\r
294 SendMessage(combo, CB_RESETCONTENT, 0, 0);
\r
296 const TCHAR *hook_event = hook_event_strings[event_index];
\r
297 TCHAR *hook_action;
\r
299 switch (event_index + first_event) {
\r
300 case NSSM_GUI_HOOK_EVENT_ROTATE:
\r
302 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_PRE));
\r
303 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
304 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_POST));
\r
305 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
308 case NSSM_GUI_HOOK_EVENT_START:
\r
310 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_PRE));
\r
311 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
312 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_POST));
\r
313 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
316 case NSSM_GUI_HOOK_EVENT_STOP:
\r
318 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_STOP_PRE));
\r
319 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
322 case NSSM_GUI_HOOK_EVENT_EXIT:
\r
324 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_EXIT_POST));
\r
325 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
328 case NSSM_GUI_HOOK_EVENT_POWER:
\r
330 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_CHANGE));
\r
331 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_CHANGE;
\r
332 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_RESUME));
\r
333 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_RESUME;
\r
337 SendMessage(combo, CB_SETCURSEL, action_index, 0);
\r
339 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
340 hook_env(hook_event, hook_action, hook_name, _countof(hook_name));
\r
342 if (! *hook_name) return;
\r
344 TCHAR cmd[CMD_LENGTH];
\r
346 GetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd, _countof(cmd));
\r
347 SetEnvironmentVariable(hook_name, cmd);
\r
350 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
351 SetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd);
\r
355 static inline int update_hook(TCHAR *service_name, const TCHAR *hook_event, const TCHAR *hook_action) {
\r
356 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
357 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) return 1;
\r
358 TCHAR cmd[CMD_LENGTH];
\r
359 ZeroMemory(cmd, sizeof(cmd));
\r
360 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
361 if (set_hook(service_name, hook_event, hook_action, cmd)) return 2;
\r
365 static inline int update_hooks(TCHAR *service_name) {
\r
367 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE);
\r
368 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_POST);
\r
369 ret += update_hook(service_name, NSSM_HOOK_EVENT_STOP, NSSM_HOOK_ACTION_PRE);
\r
370 ret += update_hook(service_name, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_ACTION_POST);
\r
371 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_CHANGE);
\r
372 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_RESUME);
\r
373 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_PRE);
\r
374 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_POST);
\r
378 static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {
\r
379 if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;
\r
380 if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;
\r
381 popup_message(owner, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, name);
\r
382 ZeroMemory(buffer, len * sizeof(TCHAR));
\r
385 /* Set service parameters. */
\r
386 int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service) {
\r
387 if (! service) return 1;
\r
389 set_nssm_service_defaults(service);
\r
391 if (orig_service) {
\r
392 service->native = orig_service->native;
\r
393 service->handle = orig_service->handle;
\r
396 /* Get service name. */
\r
397 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
398 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
399 cleanup_nssm_service(service);
\r
403 /* Get executable name */
\r
404 if (! service->native) {
\r
405 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe, _countof(service->exe))) {
\r
406 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
\r
410 /* Get startup directory. */
\r
411 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir, _countof(service->dir))) {
\r
412 _sntprintf_s(service->dir, _countof(service->dir), _TRUNCATE, _T("%s"), service->exe);
\r
413 strip_basename(service->dir);
\r
417 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
\r
418 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags, _countof(service->flags))) {
\r
419 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
\r
426 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME), WM_GETTEXTLENGTH, 0, 0)) {
\r
427 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname, _countof(service->displayname))) {
\r
428 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DISPLAYNAME);
\r
433 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION), WM_GETTEXTLENGTH, 0, 0)) {
\r
434 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description, _countof(service->description))) {
\r
435 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DESCRIPTION);
\r
440 HWND combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
441 service->startup = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
442 if (service->startup == CB_ERR) service->startup = 0;
\r
444 /* Get logon stuff. */
\r
445 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
446 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
447 service->type |= SERVICE_INTERACTIVE_PROCESS;
\r
449 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
450 service->username = 0;
\r
451 service->usernamelen = 0;
\r
452 if (service->password) {
\r
453 SecureZeroMemory(service->password, service->passwordlen);
\r
454 HeapFree(GetProcessHeap(), 0, service->password);
\r
456 service->password = 0;
\r
457 service->passwordlen = 0;
\r
461 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
462 if (! service->usernamelen) {
\r
463 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
466 service->usernamelen++;
\r
468 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\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 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
474 HeapFree(GetProcessHeap(), 0, service->username);
\r
475 service->username = 0;
\r
476 service->usernamelen = 0;
\r
477 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
482 Special case for well-known accounts.
\r
483 Ignore the password if we're editing and the username hasn't changed.
\r
485 const TCHAR *well_known = well_known_username(service->username);
\r
487 if (str_equiv(well_known, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
488 HeapFree(GetProcessHeap(), 0, service->username);
\r
489 service->username = 0;
\r
490 service->usernamelen = 0;
\r
493 service->usernamelen = _tcslen(well_known) + 1;
\r
494 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
495 if (! service->username) {
\r
496 print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("install()"));
\r
499 memmove(service->username, well_known, service->usernamelen * sizeof(TCHAR));
\r
504 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
505 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
507 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
508 if (! service->passwordlen) {
\r
509 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
512 if (passwordlen != service->passwordlen) {
\r
513 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
516 service->passwordlen++;
\r
518 /* Temporary buffer for password validation. */
\r
519 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
521 HeapFree(GetProcessHeap(), 0, service->username);
\r
522 service->username = 0;
\r
523 service->usernamelen = 0;
\r
524 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
528 /* Actual password buffer. */
\r
529 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
530 if (! service->password) {
\r
531 HeapFree(GetProcessHeap(), 0, password);
\r
532 HeapFree(GetProcessHeap(), 0, service->username);
\r
533 service->username = 0;
\r
534 service->usernamelen = 0;
\r
535 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
539 /* Get first password. */
\r
540 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
541 HeapFree(GetProcessHeap(), 0, password);
\r
542 SecureZeroMemory(service->password, service->passwordlen);
\r
543 HeapFree(GetProcessHeap(), 0, service->password);
\r
544 service->password = 0;
\r
545 service->passwordlen = 0;
\r
546 HeapFree(GetProcessHeap(), 0, service->username);
\r
547 service->username = 0;
\r
548 service->usernamelen = 0;
\r
549 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
553 /* Get confirmation. */
\r
554 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
555 SecureZeroMemory(password, service->passwordlen);
\r
556 HeapFree(GetProcessHeap(), 0, password);
\r
557 SecureZeroMemory(service->password, service->passwordlen);
\r
558 HeapFree(GetProcessHeap(), 0, service->password);
\r
559 service->password = 0;
\r
560 service->passwordlen = 0;
\r
561 HeapFree(GetProcessHeap(), 0, service->username);
\r
562 service->username = 0;
\r
563 service->usernamelen = 0;
\r
564 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
569 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
570 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
571 SecureZeroMemory(password, service->passwordlen);
\r
572 HeapFree(GetProcessHeap(), 0, password);
\r
573 SecureZeroMemory(service->password, service->passwordlen);
\r
574 HeapFree(GetProcessHeap(), 0, service->password);
\r
575 service->password = 0;
\r
576 service->passwordlen = 0;
\r
577 HeapFree(GetProcessHeap(), 0, service->username);
\r
578 service->username = 0;
\r
579 service->usernamelen = 0;
\r
586 /* Get dependencies. */
\r
587 unsigned long dependencieslen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES), WM_GETTEXTLENGTH, 0, 0);
\r
588 if (dependencieslen) {
\r
589 TCHAR *dependencies = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (dependencieslen + 2) * sizeof(TCHAR));
\r
590 if (! dependencies) {
\r
591 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
592 cleanup_nssm_service(service);
\r
596 if (! GetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, dependencies, dependencieslen + 1)) {
\r
597 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DEPENDENCIES);
\r
598 HeapFree(GetProcessHeap(), 0, dependencies);
\r
599 cleanup_nssm_service(service);
\r
603 if (unformat_double_null(dependencies, dependencieslen, &service->dependencies, &service->dependencieslen)) {
\r
604 HeapFree(GetProcessHeap(), 0, dependencies);
\r
605 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
606 cleanup_nssm_service(service);
\r
610 HeapFree(GetProcessHeap(), 0, dependencies);
\r
613 /* Remaining tabs are only for services we manage. */
\r
614 if (service->native) return 0;
\r
616 /* Get process stuff. */
\r
617 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
618 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
620 service->affinity = 0LL;
\r
621 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
622 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
623 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
624 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
626 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
629 else if (selected < count) {
\r
630 for (int i = 0; i < count; i++) {
\r
631 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
636 if (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->no_console = 0;
\r
637 else service->no_console = 1;
\r
639 /* Get stop method stuff. */
\r
640 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
641 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
642 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
643 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
644 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
645 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
646 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
647 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->kill_process_tree = 1;
\r
648 else service->kill_process_tree = 0;
\r
650 /* Get exit action stuff. */
\r
651 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
652 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
653 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
654 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
655 check_number(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, &service->restart_delay);
\r
657 /* Get I/O stuff. */
\r
658 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
659 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
660 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
662 /* Override stdout and/or stderr. */
\r
663 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
664 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
665 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
668 /* Get rotation stuff. */
\r
669 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
670 service->rotate_files = true;
\r
671 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
672 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
673 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
676 /* Get environment. */
\r
677 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
679 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
681 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
682 cleanup_nssm_service(service);
\r
686 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
687 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
688 HeapFree(GetProcessHeap(), 0, env);
\r
689 cleanup_nssm_service(service);
\r
694 unsigned long newlen;
\r
695 if (unformat_double_null(env, envlen, &newenv, &newlen)) {
\r
696 HeapFree(GetProcessHeap(), 0, env);
\r
697 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
698 cleanup_nssm_service(service);
\r
702 HeapFree(GetProcessHeap(), 0, env);
\r
706 /* Test the environment is valid. */
\r
707 if (test_environment(env)) {
\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
714 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
715 service->env = env;
\r
716 service->envlen = envlen;
\r
719 service->env_extra = env;
\r
720 service->env_extralen = envlen;
\r
727 /* Install the service. */
\r
728 int install(HWND window) {
\r
729 if (! window) return 1;
\r
731 nssm_service_t *service = alloc_nssm_service();
\r
733 int ret = configure(window, service, 0);
\r
734 if (ret) return ret;
\r
737 /* See if it works. */
\r
738 switch (install_service(service)) {
\r
740 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
741 cleanup_nssm_service(service);
\r
745 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
746 cleanup_nssm_service(service);
\r
750 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
751 cleanup_nssm_service(service);
\r
755 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
756 cleanup_nssm_service(service);
\r
760 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
761 cleanup_nssm_service(service);
\r
765 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
766 cleanup_nssm_service(service);
\r
770 update_hooks(service->name);
\r
772 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
773 cleanup_nssm_service(service);
\r
777 /* Remove the service */
\r
778 int remove(HWND window) {
\r
779 if (! window) return 1;
\r
781 /* See if it works */
\r
782 nssm_service_t *service = alloc_nssm_service();
\r
784 /* Get service name */
\r
785 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
786 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
787 cleanup_nssm_service(service);
\r
792 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
793 cleanup_nssm_service(service);
\r
798 switch (remove_service(service)) {
\r
800 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
801 cleanup_nssm_service(service);
\r
805 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
806 cleanup_nssm_service(service);
\r
810 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
811 cleanup_nssm_service(service);
\r
815 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
816 cleanup_nssm_service(service);
\r
820 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
821 cleanup_nssm_service(service);
\r
825 int edit(HWND window, nssm_service_t *orig_service) {
\r
826 if (! window) return 1;
\r
828 nssm_service_t *service = alloc_nssm_service();
\r
830 int ret = configure(window, service, orig_service);
\r
831 if (ret) return ret;
\r
834 switch (edit_service(service, true)) {
\r
836 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
837 cleanup_nssm_service(service);
\r
841 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
842 cleanup_nssm_service(service);
\r
846 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
847 cleanup_nssm_service(service);
\r
852 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
853 cleanup_nssm_service(service);
\r
857 update_hooks(service->name);
\r
859 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
860 cleanup_nssm_service(service);
\r
864 static TCHAR *browse_filter(int message) {
\r
866 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
867 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
868 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
869 default: return _T("*.*");
\r
873 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
875 case WM_INITDIALOG:
\r
882 /* Browse for application */
\r
883 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
884 if (! window) return;
\r
887 size_t bufsize = 256;
\r
888 size_t len = bufsize;
\r
892 ZeroMemory(&ofn, sizeof(ofn));
\r
893 ofn.lStructSize = sizeof(ofn);
\r
894 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
895 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
896 if (ofn.lpstrFilter) {
\r
897 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
899 /* "Applications" + NULL + "*.exe" + NULL */
\r
900 va_start(arg, flags);
\r
901 while (i = va_arg(arg, int)) {
\r
902 TCHAR *localised = message_string(i);
\r
903 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
904 len += _tcslen(localised) + 1;
\r
905 LocalFree(localised);
\r
906 TCHAR *filter = browse_filter(i);
\r
907 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
908 len += _tcslen(filter) + 1;
\r
911 /* Remainder of the buffer is already zeroed */
\r
913 ofn.lpstrFile = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, PATH_LENGTH * sizeof(TCHAR));
\r
914 if (ofn.lpstrFile) {
\r
915 if (flags & OFN_NOVALIDATE) {
\r
916 /* Directory hack. */
\r
917 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
918 ofn.nMaxFile = DIR_LENGTH;
\r
921 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T("%s"), current);
\r
922 ofn.nMaxFile = PATH_LENGTH;
\r
925 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
926 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
928 if (GetOpenFileName(&ofn)) {
\r
929 /* Directory hack. */
\r
930 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
931 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
933 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
934 if (ofn.lpstrFile) HeapFree(GetProcessHeap(), 0, ofn.lpstrFile);
\r
937 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
939 case WM_INITDIALOG:
\r
942 /* Button was pressed or control was controlled. */
\r
945 TCHAR buffer[PATH_LENGTH];
\r
946 unsigned char enabled;
\r
948 switch (LOWORD(w)) {
\r
949 /* Browse for application. */
\r
951 dlg = GetDlgItem(tab, IDC_PATH);
\r
952 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
953 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
954 /* Fill in startup directory if it wasn't already specified. */
\r
955 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
957 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
958 strip_basename(buffer);
\r
959 SetDlgItemText(tab, IDC_DIR, buffer);
\r
963 /* Browse for startup directory. */
\r
964 case IDC_BROWSE_DIR:
\r
965 dlg = GetDlgItem(tab, IDC_DIR);
\r
966 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
967 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
971 case IDC_LOCALSYSTEM:
\r
972 set_logon_enabled(0);
\r
976 set_logon_enabled(1);
\r
980 case IDC_AFFINITY_ALL:
\r
981 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
983 set_affinity_enabled(enabled);
\r
986 /* Shutdown methods. */
\r
987 case IDC_METHOD_CONSOLE:
\r
988 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
991 case IDC_METHOD_WINDOW:
\r
992 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
995 case IDC_METHOD_THREADS:
\r
996 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
999 /* Browse for stdin. */
\r
1000 case IDC_BROWSE_STDIN:
\r
1001 dlg = GetDlgItem(tab, IDC_STDIN);
\r
1002 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
1003 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1006 /* Browse for stdout. */
\r
1007 case IDC_BROWSE_STDOUT:
\r
1008 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
1009 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1010 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1011 /* Fill in stderr if it wasn't already specified. */
\r
1012 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1013 if (! buffer[0]) {
\r
1014 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1015 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
1019 /* Browse for stderr. */
\r
1020 case IDC_BROWSE_STDERR:
\r
1021 dlg = GetDlgItem(tab, IDC_STDERR);
\r
1022 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1023 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1028 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
1030 set_rotation_enabled(enabled);
\r
1034 case IDC_HOOK_EVENT:
\r
1035 if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), 0, false);
\r
1038 /* Hook action. */
\r
1039 case IDC_HOOK_ACTION:
\r
1040 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
1043 /* Browse for hook. */
\r
1044 case IDC_BROWSE_HOOK:
\r
1045 dlg = GetDlgItem(tab, IDC_HOOK);
\r
1046 GetDlgItemText(tab, IDC_HOOK, buffer, _countof(buffer));
\r
1047 browse(dlg, _T(""), OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1052 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
1061 /* Install/remove dialogue callback */
\r
1062 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
1063 nssm_service_t *service;
\r
1065 switch (message) {
\r
1066 /* Creating the dialogue */
\r
1067 case WM_INITDIALOG:
\r
1068 service = (nssm_service_t *) l;
\r
1070 SetFocus(GetDlgItem(window, IDC_NAME));
\r
1076 tabs = GetDlgItem(window, IDC_TAB1);
\r
1077 if (! tabs) return 0;
\r
1079 /* Set up tabs. */
\r
1081 ZeroMemory(&tab, sizeof(tab));
\r
1082 tab.mask = TCIF_TEXT;
\r
1086 /* Application tab. */
\r
1087 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
1088 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
1089 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1090 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
1091 if (service->native) {
\r
1092 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
1093 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
1094 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
1096 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
1097 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
1099 /* Details tab. */
\r
1100 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
1101 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1102 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
1103 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
1104 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
1106 /* Set defaults. */
\r
1107 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
1108 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
1109 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
1110 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
1111 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
1112 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
1115 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
1116 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1117 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
1118 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
1119 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
1121 /* Set defaults. */
\r
1122 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
1123 set_logon_enabled(0);
\r
1125 /* Dependencies tab. */
\r
1126 tab.pszText = message_string(NSSM_GUI_TAB_DEPENDENCIES);
\r
1127 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1128 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DEPENDENCIES, (LPARAM) &tab);
\r
1129 tablist[NSSM_TAB_DEPENDENCIES] = dialog(MAKEINTRESOURCE(IDD_DEPENDENCIES), window, tab_dlg);
\r
1130 ShowWindow(tablist[NSSM_TAB_DEPENDENCIES], SW_HIDE);
\r
1132 /* Remaining tabs are only for services we manage. */
\r
1133 if (service->native) return 1;
\r
1135 /* Process tab. */
\r
1136 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
1137 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1138 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
1139 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
1140 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
1142 /* Set defaults. */
\r
1143 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
1144 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
1145 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
1146 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
1147 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
1148 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
1149 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
1150 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
1152 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1154 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
1156 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
1157 for (i = 0; i < n; i++) {
\r
1159 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
1160 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
1165 The box is high enough for four rows. It is wide enough for eight
\r
1166 columns without scrolling. With scrollbars it shrinks to two rows.
\r
1167 Note that the above only holds if we set the column width BEFORE
\r
1168 adding the strings.
\r
1171 int columns = (n - 1) / 4;
\r
1173 GetWindowRect(list, &rect);
\r
1174 int width = rect.right - rect.left;
\r
1175 width -= (7 - columns) * 16;
\r
1176 int height = rect.bottom - rect.top;
\r
1177 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
\r
1178 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
1180 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
1182 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
1183 set_affinity_enabled(0);
\r
1185 /* Shutdown tab. */
\r
1186 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
1187 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1188 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
1189 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
1190 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
1192 /* Set defaults. */
\r
1193 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1194 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
1195 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
1196 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
1197 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
1198 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1199 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1200 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_CHECKED, 1);
\r
1202 /* Restart tab. */
\r
1203 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1204 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1205 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1206 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1207 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1209 /* Set defaults. */
\r
1210 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1211 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1212 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1213 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1214 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1215 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1216 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1217 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1220 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1221 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1222 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1223 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1224 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1226 /* Rotation tab. */
\r
1227 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1228 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1229 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1230 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1231 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1233 /* Set defaults. */
\r
1234 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1235 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1236 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1237 set_rotation_enabled(0);
\r
1239 /* Environment tab. */
\r
1240 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1241 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1242 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1243 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1244 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1247 tab.pszText = message_string(NSSM_GUI_TAB_HOOKS);
\r
1248 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1249 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_HOOKS, (LPARAM) &tab);
\r
1250 tablist[NSSM_TAB_HOOKS] = dialog(MAKEINTRESOURCE(IDD_HOOKS), window, tab_dlg);
\r
1251 ShowWindow(tablist[NSSM_TAB_HOOKS], SW_HIDE);
\r
1253 /* Set defaults. */
\r
1254 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
1255 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_START));
\r
1256 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_STOP));
\r
1257 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_EXIT));
\r
1258 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_POWER));
\r
1259 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_ROTATE));
\r
1260 if (_tcslen(service->name)) {
\r
1261 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
1262 TCHAR cmd[CMD_LENGTH];
\r
1263 for (i = 0; hook_event_strings[i]; i++) {
\r
1264 const TCHAR *hook_event = hook_event_strings[i];
\r
1266 for (j = 0; hook_action_strings[j]; j++) {
\r
1267 const TCHAR *hook_action = hook_action_strings[j];
\r
1268 if (! valid_hook_name(hook_event, hook_action, true)) continue;
\r
1269 if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) continue;
\r
1270 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) continue;
\r
1271 SetEnvironmentVariable(hook_name, cmd);
\r
1275 set_hook_tab(0, 0, false);
\r
1281 NMHDR *notification;
\r
1283 notification = (NMHDR *) l;
\r
1284 switch (notification->code) {
\r
1285 case TCN_SELCHANGE:
\r
1289 tabs = GetDlgItem(window, IDC_TAB1);
\r
1290 if (! tabs) return 0;
\r
1292 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1293 if (selection != selected_tab) {
\r
1294 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1295 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1296 SetFocus(GetDlgItem(window, IDOK));
\r
1297 selected_tab = selection;
\r
1304 /* Button was pressed or control was controlled */
\r
1306 switch (LOWORD(w)) {
\r
1309 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1310 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1312 else if (! install(window)) PostQuitMessage(0);
\r
1315 /* Cancel button */
\r
1317 DestroyWindow(window);
\r
1320 /* Remove button */
\r
1322 if (! remove(window)) PostQuitMessage(0);
\r
1327 /* Window closing */
\r
1329 DestroyWindow(window);
\r
1332 PostQuitMessage(0);
\r