I trying to make a visible tray-icon of my program in windows startup, with the NotifyIcon component.
The program itself works great and the tray-icon showing up.
But, when i placing my program in computer startup, the tray icon not always showing up, while the program itself is running without any problems, and its main window is visible.
There is no custom code involved here, all code is auto-generated.
Running on Windows 7 Ultimate.
What can i do to make the tray icon to showing up in windows startup always?
in windows startup
If you mean you are running a OS boot time (e.g. by adding an entry to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run or with a service) then the process is running in a different session and has no access to the UI.
If you want a process to be run on OS startup and to be interactive you will need two applications: one to run on startup and expose some form of inter-0process communications (IPC), and two a UI application that uses the first applications IPC to communicate with it.
You also (depending on your target users) may need to consider cases where (1) no-one logs on to the system (e.g. a headless server), and (2) where multiple users login (e.g. remote desktop connections to a shared system).
In the past services could be configured to add items to the console user's UI, but this was blocked in Vista (as it opened up security holes).
You'll probably find it back in the hidden icons. On Win7 click the "Show hidden icons" arrow, click on Customize and override the behavior.
Related
For the record, I want to point out two things:
I know how to create a Windows Service, I know how to create Tray applications and how to communicate with my Windows Service
I have read countless articles on this subject, almost all of them suggest hacks, putting applications in the Startup menu, (old) interactive desktop services, startup scripts etc. I also found very resources for the subject dated after 2010 (aka light years in the world of technology)
What I'm looking for is the proper way to make sure that when my service is installed, every user gets a nice icon in his tray whenever he/she logs on to his/her computer. This is slightly more complex than it seems, and most of the hackish solutions won't work anyway (not that I'd want to use them anyway).
What I want to achieve is twofold. I want to know how to:
Start the Tray application WITHOUT modifying any user settings. This means not adding anything to the user startup, not modifying the registry, no startup-scripts or whatever. My company doesn't have fixed seats in almost all of its departments. Any user can log on to nearly every workstation at every time. Ideally the Tray application would be launched from the service detecting a user logging on or the shell being started, and then spawning an instance of the tray application for that user.
I'm also looking for a way to handle the startup of the service. For example, when I start up the service and multiple users are logged on to a single machine (which is entirely possible), the service should spawn a tray application instance for each of the users with an interactive logon. This is especially important should the service need to recover. The same goes for when the service is stopped or restarted.
Just to give you an idea, the application I'm writing consists out of a Windows Service, a Tray application that gives feedback to users via notifications and allows them to start op a configuration program that also contains additional information for them, and finally said configuration program that communicates with the service via named pipes. It's all very simple.
TL;DR: I have a service, a gui, and a tray icon. I want to know how to get the tray icon to run on user login/start-up and be able to stop the service and start the gui
Some Background Info:
I have a windows service I've made that uses a xml file to collect
files from other computers on my network and store them on the local
pc (running the service). the xml has some structures called
'profiles' which have info like FileDestination, LocationToTakeFrom,
FileTypeToTake, and IsProfileActive...
The service basically takes all the active profiles and every hour
scans the location for files created within a 1hr window of the
current date/time on local PC.
My GUI allows the user to make profiles / modify profiles, as
well as determine which profile(s) should be active for collection. I
dont want this gui running at all times, so I plan to have a
systemTrayIcon to allow this GUI to be opened and shutdown.
I'm using Visual Studio 2010 .NET 4.0 everything is in C#, I have 1 solution with separate projects(gui and service)
I'm wondering about the following things as far as the System Tray Icon goes:
1) how do I have the icon start on user login (note that this will be distributed via an installer, not just my personal use. so It has to be done via code)
2) Stop a service via sysTrayIcon
3) where to place the SysTrayIcon... do I make a 3rd project? add it in the GUI project? not quite sure here.
4) if SysTrayIcon IS in a seperate project how can I have it create instances of the GUI?
ie how can I start the GUI application from code in a different project
the project requirements are:
-upon installation the GUI must start, after that the Gui should only be accessed through the tray icon.
-user should be able to stop the service any time via system tray icon
Start the client
There are plenty of ways to start an application on Login under Windows. Just grab SysInternals AutoRuns to get an idea. The obvious ones are (a) the good ol' Startup group and (b) one of the
\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*
keys under HKCU and/or HKLM. That's the typical task of an setup utility, which makes sense since you have to install the service anyway. To do it in code:
Registry: Open the reg key, add the entry, close the reg key.
Startup: determine the value of CSIDL_STARTUP or CSIDL_COMMON_STARTUP using SHGetFolderPath, then create a Shell Link in that folder.
Service communication & control
The GUI part implements the TrayIcon and communicates through some channnel with your service. Again, there are plenty of possibilities how to do this, like disk files or memory mapped files, named pipes, even sockets. It would be too broad to list all the ways here, so I'd suggest to decide for one way and ask again if you have specific questions on that one.
To stop your service from code, use the ControlService() function and pass SERVICE_CONTROL_STOP as the dwControl parameter. To start a service, there's another function named (big surprise) StartService() to achieve that. Note that you may need to start an elevated copy of your app to control services. A quick & dirty way is to simply launch net start/stop MyService elevated with the necessary args.
I've created a service that runs as the Local System user. This service launches and monitors a Silverlight Out-of-browser application using native interop and the CreateProcessAsUser() method (to run it as the currently logged-in user, rather than Local System). I'm able to get a handle on the spawned Process and do things like Kill() it, however, I've become aware that the service is unable to get a handle to the main window of the child application because the child application is running as a different user. I'm running on Windows 7.
My end goal is to respond properly to when the Process stops responding (i.e. Process.Responding == false) so that I can kill the application and restart it. However, Process.Responding requires a handle to the main window of the process (Process.MainWindowHandle, to be exact), however, in this scenario, Process.MainWindowHandle always returns 0.
I'm stumped here. Is there any way for one user to get a window handle to a process running as another user in Win 7?
Thanks in advance for any and all help.
No, that's not possible. Windows Services are completely isolated from user-mode applications for security reasons. If you could get the handle to a window, you could manipulate and otherwise interact with that window, leaving open a huge security vulnerability.
More information is available here:
How can a Windows Service start a process when a Timer event is raised?
How can I run an EXE program from a Windows Service using C#?
windows service (allow service to interact with desktop)
Need suggestion on replacing Windows Service by invisible WinForm Application
Strictly speaking, what you're using the Windows Service for in the first place is bad design. It shouldn't be creating or launching any user-mode processes, or interacting with the user in any way. Remember that services run even when there is no user logged in! Thus, they shouldn't be starting applications.
A better solution is a simple background application, set to launch automatically when the user logs in. This background application could then launch the Silverlight application, monitor its state, and interact with it as necessary, because both would be running under the context of the same local user account. The effect is similar to a service, but without any of the drawbacks of isolation. The easiest way to do this in Visual Studio is to create a WinForms application (or possibly a WPF application, I have less experience in that area) that simply doesn't show any forms/windows.
I wonder is it possible to run my application before login on windows.? Its actually a WinForm application(Preferably other than Windows service).
I mean my application must be running even before log in and it should sit on System Tray from which I can "show" or open Interface for user.
To have:
Something happen between system startup and user login
An icon in the notification area for users to interact with
You must break your application up into two separate components. One of these will be a WinForms/WPF application which provides the notification area icon and allows the user to interact with it. The other will be a Windows Service, or possibly a scheduled task.
Once you've done this, the windows service can focus on doing whatever needs to be done prior to logon and the notification area application can assume responsibility for showing the results, or whatever else to the end user.
To answer the question you posed in comments regarding reading data from the Event Log, yes this is possible. There are other questions on here which will give you that particular answer:
read the windows event log by particular Source
Read event log in C#
This MS article might help but it is a bit old:
http://support.microsoft.com/kb/142905
Hopefully it'll put you on the right tracks though.
I think, it doesn't make sense, to acquire user input before a user has logged into the system. So, if the application needs input from a user, why start it before the use has logged in? If the application just starts some background work, than you should use a windows service, as this is the prefered way in windows.
Type in run gpedit.msc, for Group Policy,
There you can set start up script.
Application will launch before Windows Login,
Step to produce :-
Start --> Run --> gpedit.msc --> Local Computer Policy --> Windows Settings --> Script (Startup/ShutDown),
Add you .exe
It will launch Before login.
Do not try more in Group Policy, it may happen harmful for System
By Programmatic logic,
Try with registry key
this value is updating in registry,
by our program we can update directly registry then we can call application
You can schedule any application to be run when computer is powered on using Windows Task Scheduler. There is a corresponding option there.
But why would you need this? You should use a service for this.
I want to make a application that runs with no form interaction with user and only specific person can run a form and change config setting. The application is desktop reminder which runs every 4 months and shows up a notification.
I don't have any idea how to start it. Please guide me with some good suggestions.
If you have an application that needs to notify the user once every 4 months, its a bit overhead to have it running all the time.
Use the Task Scheduler in Windows, to schedule this command to run (once per day, or every week) check if the condition is met. If not silently exit.
You can effectively create a windows Service and then configure it to allow it interact with the desktop through the Services administration console.
However, for security reasons in W2008 Server (and I assume that more or less it will be the same with W7 or even Vista, you'll have to try it) this behaves differently, and services that interact with the desktop are not allowed. Actually, I remember that when I created and showed a Window I got a notification and when clicking on it the desktop switched to another one with my window. Still, no issue with XP, I've done it.