I've created a custom C#/WPF application that can send toast notifications that has an activator that can handle activation. I'm using WiX to deploy the solution and create a shortcut with ShortcutProperty elements for System.AppUserModel.ID and System.AppUserModel.ToastActivatorCLSID.
Everything works perfectly as expected but I wonder one thing. Is it possible to register the ToastActivator without creating a shortcut? This program is going to be used on an internal enterprise network and I don't intend for it to have any UI. It'll be launched by the Task Scheduler, check a web service and send toast messages to the user when they apply.
If I must have a shortcut, the best UX I can think of is to just diplay an about dialog and exit.
Based on the Application Model Microsoft has, any UWP feature like notification center, toasts etc can only be done by a registered application.
An application is "registered" when its added to the start menu with a link.
There has to be a valid shortcut with a System.AppUserModel.Id otherwise all the new win10 features do not work.
https://learn.microsoft.com/en-us/windows/win32/shell/quickstart-sending-desktop-toast
Related
I am new to .NET and seeking help for the Windows Service Updates Notifications.
I have a use case that is somewhat similar to "https://stackoverflow.com/questions/41232170/c-sharp-show-notification-prompting-a-update".
The application is developed in C#.NET and is deployed and running as Windows Service.
However, the application is not using any MSI installer to install it. I am using a batch script that configures the Windows Service application.
Now, I want to show the notifications about the updates about the Windows Service to the user, when the system gets restarted.
I came across about the usage of WCF or by using the Task Scheduler, but not sure which one would be the better solution.
Please advice.
Ok, there are (were, because MS disabled the first one that I'm going to explain) two ways to notify your user about updates from a service.
First, the bad, ugly (and non-working in recent versions) way: interactive services.
You can configure a service as interactive, if you add the SERVICE_INTERACTIVE_PROCESS flag the service will be able to create a GUI that will be attached to Display_0. This presents a ton of problems (trying to show a GUI when there's no user session, if you have two sessions open only the first one will show the GUI and so on) but it's a cheap dirty way to show data to the user. Avoid it.
Second, the right way: a standalone GUI program.
In this case you create a secondary program that will show the data to the user, you can start it with the user session or let the user decide if he wants to receive info by opening manually this application. This program needs to receive the updates from the service in some way, which is better is up to you but I would use UDP for this, in this way your service doesn't needs to care if any GUI app is connected or not, you broadcast an UDP message and everyone listening will receive it, you don't need to mantain a server that handles connections, you don't need to have an storage in order to maintain the event data and it will support any number of instances of the GUI (if more than one user has started a session in the machine all of them will get notified).
But as I said, that would be my preference, you can do it as fancy as you want, you can use Pipes, use a file that contains the event and use a FileSystemWatcher to get notified when changes happen in it, you can even host an ASP .net web app which implements a SignalR hub and then you can create your GUI in html. It's up to you decide which mechanism is the best for your scenario.
I have Win32 desktop bridge application that uses background task to receive push notifications from WNS. I use UWP background task APIs over C++-WinRT
I'd like to be able to receive push notifications even when OS is in sleep so that it wakes up and the app handles push notification. By default OS does not wake up. It did only after manually changing settings value in System->Battery->See which apps are affecting your battery life->Click my app ->Uncheck Let Windows decide option (by default it is always checked) and check Allow the app to run background taks. Now I'd like to do this is manual work on code for better user experience.
RequestAccessKindAsync API allows to let user to change above setting value by showing popup notification to the user and I could do it without any problem in UWP C# sample app. But same code does not show pop notification from my desktop bridge over C++-WinRT. It simply returns false value for below code
auto result = co_await BackgroundExecutionManager::RequestAccessKindAsync(BackgroundAccessRequestKind::AlwaysAllowed,
L"App needs to use background to catch push notifications while device is in sleep");
Can anyone confirm that RequestAccessKindAsync API works from desktop bridge? If not then how I can make sure OS and the app will always be able to wake up from sleep when it receives push notification?
UPD: Raised request to enable this API from desktop brige here
This is a missing feature. When we designed this API a couple of releases ago we didn't consider desktop bridge apps would be calling it - but clearly there is a use case for supporting this. I have notified the team about this gap, but I'd also encourage you to log a feature request here: https://wpdev.uservoice.com/
Two possible workarounds:
(1) you could add a dummy/empty UWP foreground app to your desktop bridge app. You can then launch this on startup and request the background access from there. This will be a bit ugly, but you could make it look like a splash screen :-)
(2) you can instruct the user to go into the Settings app to set your app to always allowed. You can help them do that with a deep link to the battery save settings, but they will still need to manually flip the switch.
How can I load a 'login form' in OnStart event of windows Service?! I know windows service is incompatible with UI. but I need to do this without using windows startup..
Is it possible? and how?
Thanks a lot.
How can I load a 'login form' in OnStart event of windows Service?
You cannot do this, because Windows services cannot display a user interface.
I know windows service is incompatible with UI.
Oh. You already knew that. Good.
but I need to do this without using windows startup..
This does not change the fact that it is not supported and will not work.
Is it possible? and how?
No, because:
windows service is incompatible with UI.
So what do I do!?!
The real answer here is that your design is wrong.
If you need someone to log in to your application, you should not be creating a service.
Just make a standard Windows application (e.g., using Windows Forms or WPF) and set it to start automatically when any user logs on to the computer. This can be accomplished easily by adding a shortcut to it to the All Users "Startup" folder.
Then, when your app runs, you can display whatever UI you need to, without the limitations of a service.
If you need to combine UI interaction with a service, you ought to write two programs - the service, which exposes some kind of API, and a client program that interacts with that API (using whatever IPC mechanism you want to choose)
Just remember that multiple users can log onto the same machine, so you ought to write everything to cope with multiple instances of the client program running at the same time.
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 have a c# application that runs as a windows service controlling socket connections and other things.
Also, there is another windows forms application to control and configure this service (systray with start, stop, show form with configuration parameters).
I'm using .net remoting to do the IPC and that was fine, but now I want to show some real traffic and other reports and remoting will not meet my performance requirements. So I want to combine both applications in one.
Here is the problem:
When I started the form from the windows service, nothing happened. Googling around I've found that I have to right click the service, go to Log on and check the "Allow service to interact with desktop" option. Since I don't want to ask my users to do that, I got some code googling again to set this option in the user's regedit during installation time. The problem is that even setting this option, it doesn't work. I have to open the Log On options of the service (it is checked), uncheck and check again.
So, how to solve that? How is the best way to have a windows service with a systray control in the same process, available to any user logging in?
UPDATE: Thanks for the comments so far, guys. I agree it is better to use IPC and I know that it is bad to mix windows services and user interfaces. Even though, I want to know how to do that.
Two separate processes that communicate using your technology of choice. Services with UI is a bad idea. Don't go down this road - you'll regret it.
I've had very good results having service communication through a simple socket connection - document your service protocol well, keep it as simple as possible, and it'll be easier than you think.
In practice you should not couple your service with the management UI.
I agree with Greg. Perhaps you could examine a different IPC mechanism. Perhaps use sockets and your own protocol. Or, if your service control app can only control the service on the local machine, you can use named pipes (even faster).
Here is a way mixing up Services and Forms
http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx
I figured out how to do this from this article (click on the "Change" link in the Methods table).
string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
object[] parameters = new object[11];
parameters[5] = true; // Enable desktop interaction
service.InvokeMethod("Change", parameters);
}
I have the solution in a few steps, this is the plan
we are not going to create a service project with a a windows form, instead we are going to create a visual studio solution that contains a windows service project, a windows form project and a setup project.
The idea is to have a database or a file or anything you are comfortable with storing data in which you would store the parameters your windows service will always use to run. So your windows service and your windows form application should be able to modify and retrieve data from it.
To the Main Form Of Your Windows Application drag and drop a NotifyIcon on the form, in the properties tab, browse and select an .ico image(You can sreate one in visual studio but that is another topic you can get on google or contact me) That it will display in the system tray when you run the application and the main form is active or shown, try it, run the application.
Add both of them as outputs in the setup project of the solution. To Add a project to a setup project they must be in the same solution. Right click the setup project in the solution explorer, highlight add and then select project output, add the windows service and the windows form outputs and you will see them in the solution explorer under the setup project.
adding a windows service goes further than this but that also is another topic google it
Creating shortcut for the windows application and adding it to the startup folder is also another topic google or contact me.
NOTE Program your form in such a way that the close button doesn't show and the form goes Me.visible = false and double clicking the icon in the system tray is the only way to set me.visible=true.that way anytime the computer starts up, your windows form application is also started and visible is immediately set to false but since it has a notifyicon with an icon image, it will show in the system tray and double clicking it makes the form visible to edit the settings that you are storing for the service, the service also starts automatically since you would have set it in setting up the service in the setup project.
my mail is iamjavademon#gmail.com for a better illustration using screen shots And explain in full
It is very simply - your need to create one thread for perform application events.
Like this( source code for C++ with CLR, but your can make this in C#):
ref class RunWindow{
public:
static void MakeWindow(Object^ data)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew TMainForm());
};
};
And create thread in main
int main(array<System::String ^> ^args)
{
bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");
if (bService)
{
System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
thread->Start();
ServiceBase::Run(gcnew simpleWinService());
Application::Exit();
}
else
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew TMainForm());
}
return 0;
}
The main problems with interactive services are:
Security - other process could send it messages through its message pump, thereby gaining access to a SYSTEM/LOCAL process.
Incompleteness - an interactive service never sees shell messages, hence it can't interact with Notification Area icons.
We regularly use TCP and UDP connections to pass info from services to other exes, and, in some cases, MSMQ.