Is it true that a service written in C# is unable to give visual feedback to the desktop?
I understand that services start up before user logon and at that point ther is no desktop available. My question then, apart from logging events in the system event log which is not a very efficient way of communicating to the user, what are my alternatives for showing a message box from a service?
Only two options come to mind:
MessageBox.Show - Looking around it seems this is not going to be an option.
Show a custom form
I've not given the reasons for why this messagebox needs to be shown.
Please assume that it needs to be shown as I don't want responses on "good practice". Not at this point at least.
A windows service should not perform interactions with a user. Instead you should create a seperate control or configuration application - often put into the system tray - that communicates with the service an can present information to the user or gather inputs.
See this Knowledge Base article and this MSDN article if you really want to do this. They contain some hints how to achiev this an you will probably need to use P/Invoke from C#.
Here are some ways that you can make interactive services. But, those have gone away with Vista.
One way you can have a user get information from a service is to build a separate UI for the purpose. The service could have a WCF endpoint for example and push messages out that the GUI would show. That way, you only show a message when there is a user logged in and it's not a security risk by popping up a window from the LocalSystem account. You could easily make this GUI run from the tray and pop-up toast so it is non-intrusive and begins when the user logs in. Much much better than trying to interact directly with the desktop.
I've never used it, and I include all of the disclaimers about not doing this.
However, you may want to check out the MessageBoxOptions.ServiceNotification enum.
Here's a good blog post detailing its use.
Related
I need help. I made a WPF application. Its functionality is that it launches the application when it is launched. But if it is pinned to the taskbar, then a JumpList appears. From which you can also call other applications. I ran into this problem: I do not know how to make the program automatically pinned to the taskbar after the first launch. Please help someone. I read on microsoft's website, but it's not suitable for wpf. Please help with this.
Maybe there is some kind of library? Maybe there is a way with the registry?
Don't ask for support for pinning, here is why.
Microsoft goes in great length to prevent applications altering user preferences. Why? Because otherwise, every application would do it. Giving access to user preferences via API means developers start exploiting it. It means applications fighting for screen space. You install compnay A product and it unpins company B product.
If such API existed, that is malware.
And an API for only the calling executable is not viable, it would mean that somewhere deep in the operating system the function call to do it for any executable exists. And then somebody finds it and calls it directly. Besides, it has been a big trouble for Microsoft to decouple the shell as it is.
Instead, explorer handles it.
Further reading Why is there no programmatic access to the Start menu pin list?.
Some application do manage to pin.
Regardless of what, it is a bad practice.
It is not guaranteed to work, much less in the next Windows update.
One way is to mimic user input. It is hard to consider all cases (what if the taskbar is hidden, what if it is not in the usual place, what if explorer is not running, etc.), but you can imagine setting the pointer position and sending keys.
Another way would be to write directly to the list. You might have found out that the pinned items are at:
%AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar
And they are regular, good old, shortcuts. And you could add your own. And it would not work.
Thus, the answer is "Please don't do it".
For a more detailed explanation, you can try to refer here.
I am developing a C# application. I am looking for a way to monitor different events in 3rd party applications.
Example 1: Calculator is running, and I want to know when the user has clicked on "=" button.
Example 2: Skype is running and I want to monitor when the user hits the "Call" button.
Example 3: Word is running and I want to monitor when the user opens the "Font" drop down list.
I am not looking for simple Mouse or Keyboard events.
Take a look at EventSpy, Both of those seams to do what you need.
http://www.codeproject.com/Articles/11918/EventSpy
http://eventspy.codeplex.com/
You basically need to tap into the "Windows Messaging" loop. In order to properly filter the GAZILLION messages that come flying through you'll also need to be able to periodically scan through all of the active windows to see which ones (if any) are relevant to you.
Be aware that this whole subsystem of windows is a GIANT security hole. (I have not worked with it much since NT4 / W95/W98 days so they might have tried attempts to "secure" it since then so it might be even harder to get to than it used to be.
You're going to need a good ide / 3rd party tools to help you get started on your way to have some idea of what you're looking for.
In a "previous" life we used this basic technique to get ~4,000 workstations to install their own software, updates, patches, etc through monitoring for existence of certain windows, controls, etc and "injecting" messages into the Windows Messaging loop to control Application Setup Programs, configuration changes that were not stored in the registry, etc, etc...
I'm developing a commercial Windows 7 desktop application (somewhat shrink wrap, but not quite). The application has both Windows Service and a WPF User Interface components. In the event that our application fails at a customer site we want to be able to capture information about the runtime environmnent, including a crash dump of our processes to a dump location. That information could then be forwared to our support personnel upon request for further investigation. We also want to turn off any Windows Error Reporting and Send To Microsoft dialogs that might popup as a result of the failure.
The important thing is that we only want this to affect our application processes. We don't want to affect some global setting that will change the way all other applications on the customers desktop report fatal errors.
I'm looking for some suggestions and best practices for doing this sort of thing in a shrink wrap application.
The best way I know how to do this is by subscribing to the AppDomain.CurrentDomain.UnhandledException event. There you will be able to use the Win32 API function MiniDumpWriteDump to create your own minidump file. Check out this blog post to see a good example. Also, there is the ClrDump library.
Before you exit from your UnhandledException handler, call Environment.Exit() and you shouldn't see any more Windows error dialogs.
I have not actually used these minidump libraries myself yet, but I will soon. Hopefully this answer will at least give you a few keywords that you can plug into Google.
This is in regards to applications that run in the taskbar but should be applicable to standard apps, Winforms, WPF, etc.
Question: I am after some method (preferably via managed code) to be notified when a user either has their screen "locked" while my app is running and/or know when they log back in.
GMail Notifier does this sort of thing for example, if my PC is locked for a while when I log in again it shows a list of emails that arrived since locking the PC. I'm looking to replicate that kind of functionality.
Does anyone have any ideas on how to accomplish this?
You want to hook into the System Event Notification Service and subscribe to the ISensLogon DisplayLock/DisplayUnlock events.
The question mentioned by Mike Daniels has answers:
Checking for workstation lock/unlock change with c#
The one I prefer is using is SessionSwitchReason:
http://msdn.microsoft.com/en-us/library/microsoft.win32.sessionswitchreason.aspx
I know something about MACROS. I don't mean the ASSEMBLY language kind. I am talking about those programs that you can use perform repetitions actions on another program. I am talking about those programs that you can use to record a series of events on your computer, like, mouse movements and button clicks and then you can play them back. Some of them are elaborate enough to run only on a paricular app that you designate.
I wrote one of sorts once. It was a program that launched an Excel sessions and then used the dynamic data exchage pipe of some kind to feed the excell session script commands. It worked.
But something on the level of the operating system, I imagine, is a whole different story.
How does someone go about writing a "macro" in C#?
I think the approach I will take is to use the spy routine that comes with the development environment to get a list of the proper messages and parameters (wm_lbuttondown for example) and then use dynamic data exchange to send those messages to the app.
So I have three questions.
Is this the best way to do this?
How do I get a handle to an app that is already running?
How do I send user-like messages to an app that is already running?
There are different answers based on many following factors:
is it 3rd party or your own
application?
does it have automation interface
GUI toolkit used in app
If it is a 3rd party app then you need to work on Windows API level via PInvoke - subclassing WinMain proc, capturing and sending input messages, etc. There are 3rd party library for that task. C# obviously is not a right choice for such task.
In case application has automation model (like Excel) it's a pretty straight forward to write program that will be interact with this app.
If it's your own application you want to enhance with macros functionality then you should take this into account on design state. If you use Command pattern from the beginning then it's not hard to program macro recording.
You should provide more details to get a better answer.
Oh, I almost forgot to answer those three questions
Is this the best way to do this?
Depends on concrete scenario
How do I get a handle to an app that is already running?
Depends on application. If it's a native Win app you can easily get process Id and window's handle via WinApi.
How do I send user-like messages to an app that is already running?
Once again it depends on application type. For native win apps you can easily send WM_XXX messages via WinAPI
Unless its something you need to add in your own program you can just download a keyboard/mouse macro program and use it to perform these repeatable actions.
On the other hand to perform macro's in your own program you would want to find a way to record the buttons clicked and write them to a temporary list that can be saved and then run the list by clicking the buttons (programmically).