How to have 1 notifyIcon over multiple instances of an application? - c#

I have created a notifyIcon in my C# application and I am happy with it. Basically, my application is a wrapper for other applications (notepad, firefox, etc). So right now, when I run my app ("MyApp firefox.exe") it loads firefox and when I mouse over the icon in the task bar it says "firefox.exe" ... pretty simple.
If I run 2 instances of my application (with different parameters) I get 2 icons, one mouse over is 'firefox.exe', the other 'notepad.exe'.
What I would really like is there to be 1 icon, where I can create a ContextMenuStrip that adds all the application names as MenuItems, so when I right click, there are 2 selectable items.
Is there any way to do this without wrapping my application in yet another application wrapper? Any ideas?

Sorry if this is a horrible answer...
Create a mutex in the same way that you to create only a single instance of an application when the first app starts...
Instead of preventing your application starting set a flag as follows
Mutex firstAppToStart = new System.Threading.Mutex(false, "Mutex...");
if (firstAppToStart.WaitOne(0, false)) {
// set flag to allow notifyicon to be loaded
CreateNotificationIcon();
} else {
// The mutex is not ours, therefore we do not create a notify icon
}
// Subsequent messages will be posted to the first application to use
// the notify icon on the first application
Now use windows messages to post between applications so now you have a single notifyicon - the other apps use windows messages to post messages to it
This does mean when the first app goes the notifyicon will also go, but you can work around this, by preventing the first app closing if it is the first app, holding a list of apps, and then posting a windows message when each closes, when they've all gone the first app can close itself...

Related

Way to tell if my winforms app has become a Background Process

I have a winforms app that is capable of showing forms, and even upon closing the last visible form will continue to run in the background - and I make use of a notify tray (system tray) icon to show that it is running.
I have code in place to prevent right click\Exit on this icon if any forms are visible. I check that
System.Windows.Forms.Application.OpenForms > 0
and while this seems to work for the most part, it may not be reliably (testing this application on other machines seems to yield unexpected results). Is there a way to check if a winforms app is running as a background process (as opposed to counting the number of open forms)?

How to get handle for menu items of an application running in the back ground from an application in C#

I am working on a application, which would be the face of lot of other tools running in background. I am facing an issue. During the launch of a background application ,it needs to load a specific file(file-->load--> file name).
Let the front end application be Fapp and the background application be Bapp. Is it possible for Fapp to get the handle of Bapp's menu item and trigger the load function. I am able to get the handle for buttons but not able to do the same for menu items.
Now we are achieving this using AutoIt, I am trying to achieve this in C# itself.
After you have obtained the handle of the window that you want to invoke its menus, then you may use
HMENU GetMenu(HWND) windows api to get menu
HMENU GetSubMenu(HMENU, int) to get to the file menu and again to open menu.
BOOL GetMenuItemInfo( ... ) to get info about menu
and you can use PostMessage((IntPtr)hWnd, WM_COMMAND, 0, ID_MENU_ITEM); (related post) to perform a click on that item.
all these apis are what AutoIt calls (I think). This solution works if your Bapp is a normal windows application with a normal windows menu, not a fancy WPF app, or a ribbon. If this is the case, then what you see as menu probably is not a menu (technically anyway)
Are you sure this is the right way to get two applications talking to each other?
If you don't have source code for BApp, and it also doesn't have an API that you can use, then pretending to be an interactive user could be the only way to interact with it. Just be aware that it is fraught with issues, consider what will happen when
BApp isn't already running
BApp has a modal dialog open
BApp is in the middle of an operation (or hanging) and its menu is disabled
BApp is updated to a new version and its UI changes
An interactive user changes focus, in the middle of an operation.
An alternative to this would be to do the same thing that you do when you are unit testing an application with a UI. This is because you are doing the same thing, automating an application by making calls that execute its functions, in this case to test the results are as expected. Since this is a WPF post lets assume that you are writing an application with MVVM, and the best way (to avoid brittleness when we are change the UI) is to ignore the UI (View) and call the layer that sits underneath i.e. the VM (ViewModel).
In fact its quite easy just to add a self-hosted WCF connection inside your BApp application so that it can be called externally.
this._host = new ServiceHost(service);
this._host.AddServiceEndpoint(typeof(IContract), new NetTcpBinding(), address);
this._host.Open();
This would then enable you to get the two talking totally independently.
If your Bapp is able to somehow invoke Win32 API - then this can be achieved by sending a custom WM_USER message to your Fapp - using SendMessage(). In your Fapp you handle this message and take appropriate action.
I don't think getting handle to a control and invoking its handler is the right way.

Why is this WinMobile (Compact Framework) app hanging after photo taken?

I am having a very difficult time trying to debug/fix an application.
Briefly:
- I created a "wizard" type app that starts with the user taking a photograph (using the common dialog for photos)
If the user tries to use the text input window (SIP) (the little keyboard input window) after a photo is taken the event loop seems to hang - the event is not processed or is delayed for a while.
If the user does not take a picture the SIP keyboard works great.
This only happens on some of my devices. Specifically it is not a problem on an MC65 but is a problem on an ES400.
It appears that the app's event loop gets screwed up with the way I am displaying forms and taking photos.
If created a simple test app with single form containing a button (Event handler takes a photo) and a text box that accepts input. That works fine. But it is only a single form app that does nothing else.
When I combine the photo taking with my form displaying (making a "wizard" ) things go badly.
I wonder what kind of event loop should I be running?
Essentially the user takes a photo then goes through some forms (I hide one form and show another when they click the "next" button.)
The Form.Show is called from the main form after a picture is taken and then I have something like:
while(UserNotFinished)
{
Application.DoEvents()
}
Where UserNotFinished is a flag set from my wizard/forms after the "submit" button is pressed.
I will be happy to provide more code but not sure what would be useful.
I am new to C# and CF development (lots of years of C++/Win32)
The real confusing part is that this works on one device but not on another. In fact, the device hangs completely. It ends the activesync connection and sometimes I have to hard reset by removing the battery.
I think your problem stems from the while(true) { DoEvents(); } and perhaps how you are trying to go between forms. The only time I've used the DoEvents() method is when I'm already in the scope of a windows event and I need to be sure something in the message queue is processed so screen updates are correct. I'd suggest making a controller class to manage the screen flow for your wizard. You can control the screen flow by either using ShowDialog() and execute the flow control directly in the scope of a single call, or you'll have to use Show() and an asynchronous mechanism such as subscribing to and handling specific form and control events in the controller class. Also saw the comment about introducing another thread, beware that Forms belong to the thread they were created in and you must Invoke(...) all Form members in the context of the creating thread.
Hmm. Very strange
I started a new thread and basically call Application.DoEvents() in in as well and it seems to fix the problem...
I don't know why the
while(true)
{
DoEvents()
}
in the main thread doesn't work.

Programming a windows service

I have started prgramming a windows service. I have added a notify icon from the toolbox.
It has the small notify icon that appears in the systray as a member of those icons.
It works so far.
So far I have a blank form. I have used the DoubleClick for the notifyIcon to bring up
the form (I will use the form for something later).
Now I have a list of things I want to accomplish to make this work like a true windows
service.
First of all, if possible, I owuld like to remove the maximize and cancel button on the form.
Most windos service apps that I have seen offer the ability to close the app by right-mouse-button clicking on the notify icon which brings up a menu of options.
I see in the properties of the form under Misc there is an CancelButton. But I do not see how do deactivate it. In the Properties of the forum I see under Window Style there is a ControlBox option that, if I turn to false, all three buttons, (minimize, maximize and cancel) go away.
These are not what i am looking for. I would not like the option for them to resize,
maximize or close the form here. I suspect people will close the box intending to
make the box go away while still wanting the app to run.
Under the "Focus" caption in Properties, there id "Deactivate". I have created my own
event/method/function for this and in debug I noticed that when you click on the x-box in the upper right corner, this function is called. The problem is that after the function is
over, the app closes anyway. How do I over-ride this function?
Secondly, how do you catch the right button click event on the notify icon in the
systray?
I can see how to create events for "Click" and "MouseClick" etc. but how so I determine
which button was click?
Using the right buton click is how such programs know when to pull up a menu. So I would
like to know how to do this as well.
Windows services should not display notification icons, nor show forms. You'll find out very soon that post Vista they are explicitly forbid from doing so.
You need to split your application into a user program that may show an icon in the notification tray and shows forms, and the service. They need to be distinct processes and communicate via IPC (shared memory, named pipes, sockets etc).
As to how to react to a righ-click on the notification icon question, you simply need to assign something in your designer to the ContextMenu property:
The menu is shown when the user
right-clicks an icon in the
notification area of the taskbar.
Shortcut menus also are known as
pop-up menus.
Standard Windows services do not run with any user interface at all. Generally speaking, your Windows service project type in Visual Studio won't contain any UI components whatsoever.
The UIs you see when working with other services are secondary applications designed to manage those services. Those may run in the system notification area ("tray"), or may run as minimized windows, may be MMC snap-ins, or may be separate applications the administrator launches on an ad-hoc basis.
As an example, SQL Server runs as a service, whether or not Management Studio or any of the other ancillary UI apps are running.
In any event, the user interface "component" of a service needs to be an entirely separate application. This is particularly important in the post-Vista world, for reasons cited by Remus Rusanu. You'll create a separate WinForms project to do this, and have it send messages to the service to control. (This may include the basics such as start, stop and restart; it usually also includes other service-specific commands.)
You may want to consider reading the following other questions here on StackOverflow for some guidance on the standard Windows Service/UI helper application pattern:
What can Services do under Windows?
What is the difference between a windows service and a regular application?
Creating a user interface for monitoring and interacting with a running windows service
Running an exe from windows service that interacts the the user’s desktop
Why do forms fail in Windows Services

Automatically run programs on startup and stop applications from memory on PPC

I have to stop applications when the window is closed. The window stays in the memory when click the (x) button. How can i remove the app in memory? Also another question is that i want the application to be installed when hard restart the pocket pc, how can i do it?
Thanks
By default the form will just hide when you click the X in the top right. You need to set the "MinimizeBox" property of the form to "False" for the application to close instead.
Installing the application on hard restart (often referred to as cold boot) requires that you put a CAB file for the application on the flash (persistent) memory of the device. You will then normally have to write a script and place that somewhere to call the CAB. This can vary from device to device so you'll have to look that one up.
Setting the form's MinimizeBox property to False causes the OK button to appear.
The Ok button is for closing the application instead of minimalizing
To prevent to application from minimizing which is the default behavior for PocketPC applications, set the MinimizeBox option to false on the form.
As for your second option that might be trickier because it depends on the PDA. If it has persistent memory you could put it there, and find a way to run the CAB file during initialization.
[Update]
It would appear that there is a Startup Folder in the windows menu. Perhaps you could write a utility that checks if your application is installed and if not launches the CAB installer.
The default behavior is indeed minimizing the application. Using a custom task manager which replaces the [x] you can tune this behavior. Some vendors (for instance HTC) include a custom taskmanager exactly for this purpose.
A generic but good task manager is WkTASK, here is the relevant feature description:
X button
Using the X button, you can
use some actions as follows:
Tap: really close
Tap&Hold: show context menu
Drag: some gestures (To show a program launcher, drag toward down. To
show Today, drag toward left.)
WkTASK offers a lot more, but you can fine tune it to do only what you want.

Categories