|
I want to add tray icon to every session desktop of terminal services. How to achieve this? The dialog of this service is created in console desktop only, so it can't receive TaskbarCreated message when a remote user logins.
|
|
|
|
|
LPSTR lpszDescription = "Example Icon Service";
ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &lpszDescription);
Napalm
|
|
|
|
|
Great Program, but I can't get the service to be installed with a "started" status. I always have to go into the service manager to start it. Any way to make this happen automatically?
|
|
|
|
|
hello
First of all, thanks for this great application. It is very useful for me. Now I dont want any arg's, that is argv to be passed to this app, I want to just execute the app directly without giving any arg. I tried commenting args part. But service is not starting. Can you please tell me how to solve
it.
THanks
|
|
|
|
|
after installing the service
and starting it
I want to run my routine
Where should I insert my code below?
int result = spawnl(P_WAIT, "c:\\save\\sample.exe",
"c:\\save\\sample.exe", NULL, NULL);
Purpose: archiving files as a service
Thanks
Patrick
|
|
|
|
|
In the callback function DialogProc, I added the handle of the click a menuItem of the popup menu, I want to change to another icon when click the menuItem, but it doesn't work! Why?
BOOL CALLBACK DialogProc( HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
.......
break;
case WM_ICON_NOTIFY:
.......
break;
case WM_COMMAND:
if (LOWORD(wParam) == ID_POPUP_CLOSE) {
ServiceStop();
} else if (LOWORD(wParam) == ID_POPUP_FUNC_START) {
NOTIFYICONDATA ndata;
ndata.cbSize=sizeof(NOTIFYICONDATA);
ndata.hWnd=hwndDlg;
ndata.uID=2000;
ndata.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
ndata.uCallbackMessage=WM_ICON_NOTIFY;
strcpy(ndata.szTip,"Another Tips"); ndata.hIcon=::LoadIcon(NULL, MAKEINTRESOURCE(IDI_WINLOGO));
Shell_NotifyIcon(NIM_MODIFY,&ndata);
}
break;
}
return false;
}
|
|
|
|
|
That's my fault. I found it!
When I want to modify the icon, I reset the NOTIFYICONDATA.uID to a value other than the original one I set when adding the icon.
I realized that only the NOTIFYICONDATA.hWnd and NOTIFYICONDATA.uID identify the icon in the systemtray. You can't locate the icon when you changed either of the two fields.
|
|
|
|
|
I don't think a service itself must expose user interface facilities.
What I think: a service should remain what is - a console program having absolutely no user interface.
The "subclass" of services interacting with desktop can use UI features - as system tray icons.
However, I don't think this is a good idea.
Arguments/my ideas against GUI in services (and other things).
A service package must be composed from at least 3 files (assuming there is only one file per functionality):
1. [no GUI] the service(s)
No GUI, just exports 1 or more services, implements init/startup, terminate/shutdown, dispatcher + control codes.
The "core" functionality.
If the executable is large, it may be useful to split it into core executable to do the minimum required and implement the functionalities in dlls (as you can in Windows NT, there is no big csrss.exe or lsass.exe, but rather small starters csrss.exe/lsass.exe and the servers implemented as csrsrv.dll and lsasrv.dll).
This may go on in other such "splits" - if you need MAPI services, implement them in xxmapisrv.dll, if you need Internet, use xxinetsrv.dll etc.
Try to keep the executable itself as small as possible, and do not load all at startup unless are you sure is does not take much time. I think is a good practice to finish the service initialization (and expecially the termination...) as soon as possible.
2. [GUI] the service controller (if more than start/stop/pause/continue is needed)
This can be a Control Panel, a .mmc application, or a separate executable. This applet/application will be executed on demand (usually as a post-installation task), and can configure the service (grant rights, set paths, command line parameters etc).
3. [GUI] the service notification application
This can be a light modified version of service controller - perform the basic operations start/stop/pause/continue/restart), maybe set some simple parameters (or expose an option to launch the controller for finetune), but the central point here is that: it is executed on user logon and displays the tray icon. This won't be a service, but rather an application executed on startup.
These 3+ components can share the same source code tree, using macros to get the binaries. It is not pleasant to have 3 or more projects, each one with Win32 Debug, Win32 Release and ANSI/MBCS/Unicode configurations (a small calculation gives me 18 configurations by now ) - but I think it's ok.
Optional (but highly recommended):
4. documentation and help file(s) + internationalization (separate resource dlls)
5. error reporting utility
6. an event log application "filter" to display only the events reported from the service(s).
7. other utilities, varying from service to service: files/databases consistence/corruption checkers (example: Exchange's eseutil.exe), user/user rights checkings (deleted/invalid users etc.) - use your imagination...
7. anything else one may consider useful.
Of course, this may vary from project to project.
It may depend also on other factors:
- using of device drivers (this probably open another discussion even larger that this...)
- platform(s) supported: if you plan all from Win95 to 2003, then ...
- additional components required for various reasons (provided by you or needed for certain features to work): system-wide hooks, custom GINAs, need to programatically install networking (I think one may qoute at least 50% of MSDN here...)
And, finally, about language/libraries - not a flame war, folks :
C
Of course, there are, C, C++, VB, Java, Python, Perl ... your choice.
Personally, I didn't see any source code of a good service written in anything else than C.
And I don't mean the quality of code, but rather the limitation of languages.
A perfect service written in Python or VB can suffer severe impacts because language is interpreted, so another executable - usually a medium/large one - should be executed; this executable needs another references, dlls, maybe runtime components installed etc.
(still with me? )
Another thing that I must admit I'm totally against: use of MFC or VB - at least for user interface.
To load the VB runtime or MFC library - both libraries having more than 1 Mb - just to display a dialog with 2-3 buttons and several controls seems too much for me. After all, MFC and VB are for productivity - applications with hundreds of forms and thousand of classes, with more developers working on. But for something that can be done in a single .c file, with almost no resources, calling up to 5 registry functions and SCM calls? I think to implement a callback window/dialog procedure and several small functions pays the price.
|
|
|
|
|
It seems like Sardaukar is making a point on the "3 files" suggestion. The notification application seems like an interesting alternative.
However, will it be much more complicated in that way? How does the notification application interact with the service? Interprocess communication? I hope someone can explain or provide some tutorial on this kind of GUI-service interaction thing. It would be very much appreciated.
Thanks
|
|
|
|
|
long dd=m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));
does not work in services.
it gives an error msg "Class not Registered"
If i run this statement from an application in nt then it works.
|
|
|
|
|
Hi Sukanta ,
I am facing a similar problem as this .
Were you able to resolve this?Can you give some idea?
|
|
|
|
|
If i want do create the service with a privileged domain user account,
it can't interact with the desktop.
how can we solve this ?
|
|
|
|
|
My service is based on MFC Dialog. I can show a system tray icon when I login. But I find a strange problem. When I logoff then re-login. The service works great. But if I logoff again, win2000 will not logoff? The problem comes from my interactive service. Because if I close it, win2000 works normaly.
Any NT service expert help me ?
|
|
|
|
|
Hey buddy, when the win2k logs off, it sends WM_QUERYEND to all the applications running. If ur application has to allow the OS to logoff successfully then it has to return 1 in the queryendmessage message handler, u can check more on this on MSDN with a key search WM_QUERYEND.
Hope that helps!!!
|
|
|
|
|
See Page "Logoff Events" under "Window Stations and Desktops" in the MSDN Library.
|
|
|
|
|
|
when I install iconservice Nothing happen!!!!!!!
|
|
|
|
|
Me either..what am i doing wrong?!
|
|
|
|
|
I would like to execute a ".jar" file in Start Service, i used CreateProcess Method but it didn't executed..but if i'm giving a ".exe" file instead of ".jar" file then the command is executed properly and window is displayed..Please advice
|
|
|
|
|
You need to use ShellExecute() with "open" for the verd in order to open a non-exe file with its associated program.
|
|
|
|
|
I think, you just need to create process like this:
program: "java"
parameters: "your/path/and/the.jar"
|
|
|
|
|
He folks!
Thanks a lot for that article!
I developed a service, which should have a system tray icon, after the user logged in. Now i know what i have to do, in order to achieve it.
I will register the windows message "TaskbarCreated" and then add my icon.
I know that i have to call "Shell_NotifyIcon(NIM_DELETE, &tnid);", when the user stopps/deletes the service.
BUT what do i have to do, to unregister my icon, when the user logs out again??
|
|
|
|
|
You do not have to remove the icon when the user logs off; however, you need to re-create it when the user loggs back on. You can detect that by handling the registered window message "TaskbarCreated". This message is broadcasted when the taskbar is created.
|
|
|
|
|
A very useful addition to this example would be to add the functionality for the service icon to be added to the window on startup. You can find an example in the MSDN Library about "Taskbar Creation Notification". This would be ideal for any type of service with an icon in the taskbar area. Here is the excerpt from the library
.
.
.
Taskbar Creation Notification
-----------------------------
With Microsoft® Internet Explorer 4.0 and later, the Shell notifies applications that the taskbar has been created. When the taskbar is created, it registers a message with the TaskbarCreated string and then broadcasts this message to all top-level windows. When your taskbar application receives this message, it should assume that any taskbar icons it added have been removed and add them again. This feature generally applies only to services that are already running when the Shell begins execution. The following example shows a very simplified method for handling this case.
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
static UINT s_uTaskbarRestart;
switch(uMessage)
{
case WM_CREATE:
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
break;
default:
if(uMessage == s_uTaskbarRestart)
AddTaskbarIcons();
break;
}
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
.
.
.
Hope this is useful. I am using it in the projects that I am working on to allow the user to interact with the service (based on their user privileges)
Derius
|
|
|
|
|
I tried this out but I wasn't able to trap WM_CREATE. In the end I got it working with a trap on WM_INITDIALOG.
See below for my current implementation...
Cheers,
Paul.
BOOL CALLBACK DialogProc( HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
static UINT s_uTaskbarRestart;
switch (uMsg)
{
case WM_INITDIALOG:
{
// Defines a new window message; we use this to catch Taskbar creation.
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
// Add the taskbar icon.
AddTaskbarIcons(hwndDlg);
break;
}
case WM_ICON_NOTIFY:
{
if (lParam == WM_RBUTTONDOWN)
{
Beep(200,200);
CMenu menu;
menu.LoadMenu(IDR_POPUP);
CMenu* popup=menu.GetSubMenu(0);
CPoint pt;
GetCursorPos(&pt);
SetForegroundWindow(hwndDlg); // Fix to hide popup.
popup->TrackPopupMenu(TPM_LEFTALIGN,pt.x,pt.y,CWnd::FromHandle(hwndDlg),CRect(0,0,0,0));
}
break;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == ID_POPUP_CLOSE)
ServiceStop();
break;
}
default:
{
// Trap for Taskbar creation.
if (uMsg == s_uTaskbarRestart)
{
// Add the taskbar icon.
AddTaskbarIcons(hwndDlg);
}
break;
}
}
return FALSE;
}
VOID AddTaskbarIcons(HWND hwndDlg)
{
NOTIFYICONDATA ndata;
ndata.cbSize=sizeof(NOTIFYICONDATA);
ndata.hWnd=hwndDlg;
ndata.uID=2000;
ndata.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
ndata.uCallbackMessage=WM_ICON_NOTIFY;
ndata.hIcon = (HICON) ::LoadImage(GetModuleHandle("FepApp.exe"),
MAKEINTRESOURCE(IDI_STANDBY), IMAGE_ICON, 16, 16, LR_SHARED);
strcpy(ndata.szTip,"Halogen FEP v1.0");
Shell_NotifyIcon(NIM_ADD,&ndata);
SetWindowPos(hwndDlg,NULL,-10,-10,0,0,SWP_NOZORDER|SWP_NOMOVE);
hwnd=hwndDlg;
}
|
|
|
|
|