Windows Service with WPF management tool - wpf

i'm trying to create a windows service with C# in .net that runs before the user is logged on...
then when a user is logged on a symbol should appear in the system tray (next to the clock) to show the user that the service is running..
by double clicking that symbol a configuration utility (written in wpf) should be shown to the user, so he can configure the service, read data from it and so on ..
is there a possibility to do this within one application?
thanks in advance for any help!!!

No, you can't do this with one application as services run with a different user in a different session. You need to create two applications and implement some communication between both.
I would not recommend using named pipes directly (like Kieren Johnstone suggested), but to have a look at WCF which was designed for interprocess communication and nicely abstracts implementation details of the communication technology away from you. Here is a link that can propably help you with WCF: http://www.switchonthecode.com/tutorials/wcf-tutorial-basic-interprocess-communication.
Best Regards,
Oliver Hanappi

Within one application, no. Services run in session 0, please see here:
http://www.microsoft.com/whdc/system/sysinternals/session0changes.mspx
Your best bet is to used Named Pipes, see here:
http://www.switchonthecode.com/tutorials/dotnet-35-adds-named-pipes-support
....or a memory mapped file, see here:
http://msdn.microsoft.com/en-us/library/dd997372.aspx
Within the scope of more-.NETty, you could also use Remoting. You'll need to come up with some interface or protocol to facilitate communication between the service and the management utility. Managing the process start/stop would be easier and you could use the ServiceController class (MSDN ref).
Hope that helps (and itsn't too discouraging)!

Related

Global Settings & Commands - OO Design Patterns

I am currently building a WPF application and have some system wide settings. Where is the best place to store these settings? App.Config file, Database or some other sort of XML file? (need to read and write).
My other issue is the application has two states (i.e. Admin Mode, Client Mode) and depending on the state the application behaves differently i.e. (Shut Down, Restart, Lock, Unlock etc.) This seems like a good case to implement the State design pattern... but the issue I am facing is that the running application is itself the context class. I am a bit confused... should I be implementing the Singleton Pattern? How is this best implemented?
In general it is often easiest to store application settings using the Settings page of the Project Designer in Visual Studio. These settings can either be stored per user or per application. Either way, they can be saved easily by calling:
Properties.Settings.Default.Save();
They can be accessed similarly:
Properties.Settings.Default.FirstUserSetting = "abc";
You can find out full details by taking a look at the Managing Application Settings page on MSDN.
Regarding your second question, I would recommend using the State Design Pattern. Unfortunately, I didn't understand your problem with that, so please let me know what your issue is and I will try to address it.

WPF, Nhibernate v2 Session Persistence

I have a WPF application that loads modules into my application via prism / MEF. Each module will reference an assembly I created to house NHibernate functionality (Unit of Work & repository pattern). Now that I started on the first module, the following questions came up:
Is it common place to have an nhibernate session open for the lifetime of a WPF / windows application?
Would it be a good idea to share the nhibernate session amongst all modules or have each module create its own session?
It's my understanding that the session is lightweight, so opening and closing a session is not a problem... however, if I close the session then I lose the change tracking... when I call Save, and the object is the same as when it was retrieve, I do not want a query to be executed.
Do not have the session open for a the lifetime of a wpf/windows application. You will have performance and memory problems if you do.
It really depends how these modules interact. Are they separate systems, or do they need to work in tandem to do work. If it's the former, I would say that they shouldn't share sessions. If it's the latter, I would use some kind of session manager that can pass out the current session.

Feature tracking WinForms

I would like to extend my WinForms app, which a feature that allows me to monitor which functions are used by the users.
The idea is to count how many times e.g. a button has been clicked, or a popup was opened.
I want to know which features are used more or less often by the users.
Any ideas how this can be done? (Or even if somebody solved this problem already)
tia,
Martin
The only mechanism I can think on to do what your looking for is to use a logger like log4net / Log4PostSharp to log details to a log file on the machine, this would give you details on usage for that particular client. You would have to create a custom attribute that you could decorate your methods with that would result in something being written out to the log file, otherwise your code would end up littered with code to implement the logging!
Have a look at this article too, it uses Log4PostSharp with AOP (Aspect Oriented Programming) which would make the implementation of the logging much more cleaner (uses attributes).
http://www.codeproject.com/KB/dotnet/log4postsharp-intro.aspx
You can find some if you google for the term "application analytics" instead of "feature tracking".
I have found the following products:
includeapp.com
Software Statistics Service
Dotfuscator for .NET, DashO for Java
FusionAnalytics
Flurry Analytics
OpenSpan Desktop Analytics
DeskMetrics
EQATEC Analytics
Rapidengines
I might say that I also plan to create such a product. When it will be Beta I will add it to the list.

Logging when application is running as XBAP?

Anybody here has actually implemented any logging strategy when application is running as XBAP ? Any suggestion (as code) as to how to implement a simple strategy base on your experience.
My app in desktop mode actually logs to a log file (rolling log) using integrated asop log4net implementation but in xbap I can't log cause it stores the file in cache (app2.0 or something folder) so I check if browser hosted and dont log since i dont even know if it ever logs...(why same codebase)....if there was a way to push this log to a service like a web service or post error to some endpoint...
My xbap is full trust intranet mode.
I would log to isolated storage and provide a way for users to submit the log back to the server using either a simple PUT/POST with HttpWebRequest or, if you're feeling frisky, via a WCF service.
Keep in mind an XBAP only gets 512k of isolated storage so you may actually want to push those event logs back to the server automatically. Also remember that the XBAP can only speak back to it's origin server, so the service that accepts the log files must run under the same domain.
Here's some quick sample code that shows how to setup a TextWriterTraceListener on top of an IsolatedStorageFileStream at which point you can can just use the standard Trace.Write[XXX] methods to do your logging.
IsolatedStorageFileStream traceFileStream = new IsolatedStorageFileStream("Trace.log", FileMode.OpenOrCreate, FileAccess.Write);
TraceListener traceListener = new TextWriterTraceListener(traceFileStream);
Trace.Listeners.Add(traceListener);
UPDATE
Here is a revised answer due to the revision you've made to your question with more details.
Since you mention you're using log4net in your desktop app we can build upon that dependency you are already comfortable working with as it is entirely possible to continue to use log4net in the XBAP version as well. Log4net does not come with an implementation that will solve this problem out of the box, but it is possible to write an implementation of a log4net IAppender which communicates with WCF.
I took a look at the implementation the other answerer linked to by Joachim Kerschbaumer (all credit due) and it looks like a solid implementation. My first concern was that, in a sample, someone might be logging back to the service on every event and perhaps synchronously, but the implementation actually has support for queuing up a certain number of events and sending them back to the server in batch form. Also, when it does send to the service, it does so using an async invocation of an Action delegate which means it will execute on a thread pool thread and not block the UI. Therefore I would say that implementation is quite solid.
Here's the steps I would take from here:
Download Joachim's WCF appender implementation
Add his project's to your solution.
Reference the WCFAppender project from your XBAP
Configure log4net to use the WCF appender. Now, there are several settings for this logger so I suggest checking out his sample app's config. The most important ones however are QueueSize and FlushLevel. You should set QueueSize high enough so that, based on how much you actually are logging, you won't be chattering with the WCF service too much. If you're just configuring warnings/errors then you can probably set this to something low. If you're configuring with informational then you want to set this a little higher. As far as FlushLevel you should probably just set this to ERROR as this will just guarantee that no matter how big the queue is at the time an error occurs everything will be flushed at the moment an error is logged.
The sample appears to use LINQ2SQL to log to a custom DB inside of the WCF service. You will need to replace this implementation to log to whatever data source best suits your needs.
Now, Joachim's sample is written in a way that's intended to be very easy for someone to download, run and understand very quickly. I would definitely change a couple things about it if I were putting it into a production solution:
Separate the WCF contracts into a separate library which you can share between the client and the server. This would allow you to stop using a Visual Studio service reference in the WCFAppender library and just reference the same contract library for the data types. Likewise, since the contracts would no longer be in the service itself, you would reference the contract library from the service.
I don't know that wsHttpBinding is really necessary here. It comes with a couple more knobs and switches than one probably needs for something as simple as this. I would probably go with the simpler basicHttpBinding and if you wanted to make sure the log data was encrypted over the wire I would just make sure to use HTTPS.
My approach has been to log to a remote service, keyed by a unique user ID or GUID. The overhead isn't very high with the usual async calls.
You can cache messages locally, too, either in RAM or in isolated storage -- perhaps as a backup in case the network isn't accessible.
Be sure to watch for duplicate events within a certain time window. You don't want to log 1,000 copies of the same Exception over a period of a few seconds.
Also, I like to log more than just errors. You can also log performance data, such as how long certain functions take to execute (particularly out-of-process calls), or more detailed data in response to the user explicitly entering into a "debug and report" mode. Checking for calls that take longer than a certain threshold is also useful to help catch regressions and preempt user complaints.
If you are running your XBAP under partial trust, you are only allowed to write to the IsolatedStorage on the client machine. And it's just 512 KB, which you would probably want to use in a more valuable way (than for logging), like for storing user's preferences.
You are not allowed to do any Remoting stuff as well under partial trust, so you can't use log4net RemotingAppender.
Finally, under partial trust XBAP you have WebPermission to talk to the server of your app origin only. I would recommend using a WCF service, like described in this article. We use similar configuration in my current project and it works fine.
Then, basically, on the WCF server side you can do logging to any place appropriate: file, database, etc. You may also want to keep your log4net logging code and try to use one of the wcf log appenders available on the internets (this or this).

How do I create a database on the computer in flash?

I want to create a a application in actionscipt 3.0 that allows the user to listen to music and read descriptions of the music. For this to happen i suppose there should be a database where the textbits and music is located and then flash fetch the info when the correct buttons are pushed. The database will contain up to 100 tracks and textbits.
The application will function on a stand that won't have a connection to the internet.
What is the easiest way to do this in actionscript 3.0?
If any of you are familiar with UML and thinks this might help in understanding the problem, then here is use-case and flow-chart:
alt text http://img135.imageshack.us/img135/1498/flowchart2.jpg
alt text http://img27.imageshack.us/img27/1000/usercase.jpg
Thanks in advance.
The easiest way to do what you're asking is probably to store the files in a directory on the machine the application is going to be running on, and then design an XML structure for storing your data. The XML is easily loaded in to Flash at runtime and is easily edittable.
Your other option would be running a database server on the machine, creating web services that run locally and push/pull the data from the database, and then call those services from your Flash application.
The first option is most definitely the easiest and should be able to provide exactly what you need. The second would be more geared towards a distributed Flash application where you needed a central data repository for the clients.
If you're building an AIR application, you can use the integrated SQLITE database. But, i agree with Justin, the easiest way is to use a XML file.
You can probably consider using "Local Shared Objects" which is a kind of cookie, with bigger capacity (100Kb by default, but you can change it). Compared to other solutions already proposed, it has then advantage of not requiring any web server.

Resources