I have a Windows WPF application running in the background at all times. I have registered a URL protocol in with the application called WTL:. The protocol works when the application is closed, but how do I respond to it when the application is open or running in the background? I have clients that are using WinXP, so the new protocol handling in Win8 isn't sufficient.
I figured OnNavigated or OnActivated might work, but the protocol doesn't work with those. Should I run something that is always listening to the protocol? Help.
Thanks!
OK - i had to read over this two times but now i think i know what you mean. I have had a similar task, not with WPF but in WinForms... (almost the same in that case).
I don't know what "WTL" does exactly, because i registered my own protocol manually at the application startup.
You can view the current settings by opening the registry editor and goto HKEY_CLASSES_ROOT
Beneath you can find your "protocol" (dont know yours, so for example i take "callto://")
Browse to the command-subkey HKEY_CLASSES_ROOT\callto\shell\open\command - The default entry points to your application. The value must look like:
"path_to_your_application.exe" "%1" (including the double-quotes!)
Important is the "%1"
This value represents the argument for your application instance.
Reading commandline args isn't really a complicated task in .net.
But it's getting a little bit tricky, if you allow only one instance!
For me the best approach for a single-instance application & getting those
"second instance-commandline-args" can be found under:
Codeproject: WPF Single Instance Application
Long story short: A request to your application can look like:
"callto://008291478624599"
In which the number will be filled in the args for your 2nd application startup request (the %1)
Related
I'm new in programming with .Net and C# and, as said in the title, I have a WPF app which is accessible in a system tray icon and I want to run it a windows service.
Typically, I want an output like it was described in an answer provided in a discussion here.
If you want it in the system tray I think what you'll have to do is make it a Windows service. I've only written 1 Windows Service and that was years ago, but I believe that's what you'll have to do. If I'm correct about writing a Windows service, then what I would suggest you do is create a new Visual Studio solution and add two projects to it. One would be a DLL which would run as a Windows service. The second project would be a WPF project that will be your UI the user interacts with. Then you'll have to use some messaging system to communicate between the two. For the action messages that would mimic what Outlook does, I've used some WPF toast messages to accomplish that. If you Bing/Google "WPF toast popup" you'll get lots of results.
I have many searched in Internet and find some helpful answers like:
URL1
You can't, not directly, because the windows service will necessarily start when the machine does, not when a user logs in. The service will also be running in a different context, likely as a different user. What you can do is to write a separate system tray based "controller" that interacts with the service.
URL2
It needs some effort to achieve. Well, just two hints: 1) use static property System.Environment.UserInteractive to detect in which mode your application is running, see http://msdn.microsoft.com/en-us/library/system.environment.userinteractive.aspx; 2) get rid of app.xaml, because it will force starting WPF Application in all cases; instead, create and run and instance of System.Windows.Application (or better, a specially derived class) explicitly and only for interactive mode, see http://msdn.microsoft.com/en-us/library/system.windows.application.aspx.
And, I could not apply their instructions.
Thanks advance!
I have a WPF application, and i need to launch some actions (and receive return values) starting from another console application.
I encountered many problems so i don t know exactly how to proceed:
1- I tried to use command lines with arguments(it worked to launch the wpf application), but i couldn't receive return Values, because they are only returned on application shutdown. Also it doesn't fit my need since some actions must be called while the wpf app is still running.
2- I thought abt developping a small dll to communicate between Console and WPF application, but i don't know what technology would be light, efficient and fit my needs.
Has any one achieved similar task in the past? If so, how did you go about it?
Thanks,
What you are looking for is usually termed 'Inter-process communication'. Named pipes are a type of IPC and can be used in .net. This guide should get you started.
You could use WCF technology to achieve this. Define contract in you wpf application, where you should set your action logic - methods, by which you want to manage your application. If it is single sided, use netTcpBinding and create endpoint in your WPF application - it is a listener from the commands from outeside. Then in your your console application add proxy class of your wpf application, using svcutil. This will allow you to send your commands. If you do everything right - this should work. I suppose you have 1 wpf application and 1 console application.
You may launch your wpf app and then use:
Named Pipes - the simplest way but you must create a protocol of interaction between apps. You may transfer serialized objects for example. (example);
Shared files;
WCF - most powerfull and complex technology.
I have a systemtray application (C#, Windows Forms). Next to this executable I will have another x amount of executables (written in C#) that must somehow send a message (preferably in string format) to the system tray application.
I do NOT want to install an entire Windows service for this.
It is NOT client-server. It all happens on the same PC. Using a listener combined with sockets would be to troublesome and it might even be blocked by it's own firewall I think.
I'm looking for something similar to a console application that can handle parameters on it's main function. Only this time for an already running Windows Form application.
Is it possible to somehow make a global function/procedure in the system tray application that can be called by other executables? Like "global void PerformAction(params here){..}"? This would seem to be the best solution but I'm not sure if .NET 4 supports this.
Example: executable X1.exe sends message "perform action [A] param [B]" to the system tray application and then terminates itself. The system tray application will then read that string and then knows that it needs to call function A with parameter "B".
But how do I send/receive the message?
Thank you.
Without resorting to WCF - you can use a simple wrapper over Named Pipes - like this one I posted as an answer to another question.
Hope this helps!
For local communication you could try anonymous pipes.
Link: http://msdn.microsoft.com/en-us/library/bb546102.aspx
You can also check out the remote method invocation.
Here is an example:
http://www.codeproject.com/Articles/14791/NET-Remoting-with-an-easy-example
There is a very handy method available to native application, i.e. window messages. With some hack, you can also use it with your .net application.
I would suggest you to refer to
SendMessage and SendMessageA api functions. You might have to write some unsafe code though.
If you used self hosted Asp.Net Web API, then you could use simple http calls to that application to execute methods. This is nice because you can test it using fiddler or anything that can send an http request.
Here is a link for an example.
http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api
The easiest solution to me seemed to use a WCF service (inside the tray application) as Steve B mentioned.
I used this tutorial: http://www.switchonthecode.com/tutorials/wcf-tutorial-basic-interprocess-communication.
I haven't heard of piping before but I think that the above link uses a WCF Service with piping. It did solve my problem.
Thanks for the many solutions provided (and so fast).
I have a web-based picking/packing solution for delivering orders (asp.net/c#). Orders are marked as packed in the browser and then immediately the label information is added to our database, ready for the next part...
The label printing is done via a Windows application (written in C#) and was done this way because I couldn't find a way of getting the browser to print the label automatically (i.e. without the user having to click Print/OK, etc.)
The problem:
The Windows application polls every 10 seconds (subject to change) to see if there are any new labels for that picker/packer. Now, if I could get the browser to communicate with the label application then the polling would be unnecessary, since the picker/packer would have just clicked "Ready to Ship" and the label data would be created.
The data that is pulled down by the polling process isn't vast, but I'm concerned that as we add more picker/packer stations the polling process could have a knock on effect to the web server/database (since all stations would be polling). Also, pickers/packers don't want to wait around waiting for labels, so extending the polling time isn't possible (if anything I'd like it as quick as possible)
Solutions?
So, ideally, I'd like a way of communicating between the browser and the application (if possible). Or any method that removes the need for polling. Perhaps something akin to Comet, that allows the server to send a message to the application when a new label is added.
Ideally, a solution that wouldn't require a specific browser. But this may be asking too much.
A long-term solution would be to move the web-based picking-packing solution into the label application, but that would be a lot of work!
I hope that's clear and not too wordy. Let me know if I can add any other details in here. Thanks in advance.
Edit
Am looking into websockets as an idea. Any advice will be more than welcome!
Update
Thanks for all comments. I've now got a few ideas on how to solve the problem:
Websockets. May be problematic with firewall issues since I don't have easy access to the system (geographical distance)
Read browser cookies from the application. Possible solution http://www.codeproject.com/Articles/330142/Cookie-Quest-A-Quest-to-Read-Cookies-from-Four-Pop. This covers all the browsers that are in use in the warehouse. I can poll the local cookie values and see if any new labels have been created, then download them. Therefore no polling on the database server.
ActiveX control. Limited to IE and perhaps there'd be some security/setup issues with installing this on each PC.
Leave the code as is. Gauge whether the load on the database server is too much or ok.
You could create a local WebSocket server in your C# application and then make the browser connect to it and send the data you need to print.
I'm not sure, though, that this is what you need. As I see it you need to pass graphical data to your application, which could be really tricky to do using only javascript.
The appropriate way to achieve the communication between a web application and a desktop application would be to go through a server both apps talk to.
You can get any web-server (e.g. node.js nodejs.org that will let you use the same javascript you use for the web-app on the server) and interact with it. How you talk with the server from the desktop app depends on its technology. However all languages have some way to do http communications like SOAP.
Or you can try to make:
Both apps talk to the server using socket.io. You can borrow code from the following project.
Create an MSMQ (or a queue implementation of your choice) and host a WCF service in your windows application that polls the MSMQ.
Have your ASP.NET application write any relevant information to this queue so that the WCF service in the windows app that pulls this information will know what to make of it and print your labels.
The reason I mention a queue is for reliability, if your windows app goes down for any reason, the queue will at least be preserved and waiting for you to bring the windows application back up.
Although there is a bit of polling involved, it is very quick and almost neglibible. Implementing it is automatic with NetMsmqBinding, it's all taken care of. All you need to do is configure it.
If you go for a non-MSMQ queue, then I don't know whether you can still use NetMsmqBinding, you may have to create your own.
I'm not sure, but it seems like your application is polling a filesystem for these new labels to print? Have you considered using a FileSystemWatcher in your application? You can set that to watch a directory and be notified of anything new.
I have a few questions on good programming design. I'm going to first describe the project I'm building so you are better equipped to help me out.
I am coding a Remote Assistance Tool similar to TeamViewer, Microsoft Remote Desktop, CrossLoop. It will incorporate concepts like UDP networking (using Lidgren networking library), NAT traversal (since many computers are invisible behind routers nowadays), Mirror Drivers (using DFMirage's Mirror Driver (http://www.demoforge.com/dfmirage.htm) for realtime screen grabbing on the remote computer).
That being said, this program has a concept of being a client-server architecture, but I made only one program with both the functionality of client and server. That way, when the user runs my program, they can switch between giving assistance and receiving assistance without having to download a separate client or server module.
I have a Windows Form that allows the user to choose between giving assistance and receiving assistance. I have another Windows Form for a file explorer module. I have another Windows Form for a chat module. I have another Windows Form form for a registry editor module. I have another Windows Form for the live control module. So I've got a Form for each module, which raises the first question:
1. Should I process module-specific commands inside the code of the respective Windows Form? Meaning, let's say I get a command with some data that enumerates the remote user's files for a specific directory. Obviously, I would have to update this on the File Explorer Windows Form and add the entries to the ListView. Should I be processing this code inside the Windows Form though? Or should I be handling this in another class (although I have to eventually pass the data to the Form to draw, of course). Or is it like a hybrid in which I process most of the data in another class and pass the final result to the Form to draw?
So I've got like 5-6 forms, one for each module. The user starts up my program, enters the remote machine's ID (not IP, ID, because we are registering with an intermediary server to enable NAT traversal), their password, and connects. Now let's suppose the connection is successful. Then the user is presented with a form with all the different modules. So he can open up a File Explorer, or he can mess with the Registry Editor, or he can choose to Chat with his buddy. So now the program is sort of idle, just waiting for the user to do something. If the user opens up Live Control, then the program will be spending most of it's time receiving packets from the remote machine and drawing them to the form to provide a 'live' view.
2. Second design question. A spin off question #1. How would I pass module-specific commands to their respective Windows Forms? What I mean is, I have a class like "NetworkHandler.cs" that checks for messages from the remote machine. NetworkHandler.cs is a static class globally accessible. So let's say I get a command that enumerates the remote user's files for a specific directory. How would I "give" that command to the File Explorer Form. I was thinking of making an OnCommandReceivedEvent inside NetworkHandler, and having each form register to that event. When the NetworkHandler received a command, it would raise the event, all forms would check it to see if it was relevant, and the appropriate form would take action. Is this an appropriate/the best solution available?
3. The networking library I'm using, Lidgren, provides two options for checking networking messages. One can either poll ReadMessage() to return null or a message, or one can use an AutoResetEvent OnMessageReceived (I'm guessing this is like an event). Which one is more appropriate?
Put as little code as possible in the form. You should create a seperate class/set of classes to handle this and make the form use them to draw.
An event seems like a good idea. I wouldn't let the form subscribe, but have another class do the processing and just pass the processed data to the form (through another event).
I would use the event, because it probably checks async, which is what you want. You do not want to lock the form while waiting on messages.