How to check the current user logged in and time logged - c#

I need to create a Windows service that checks when a user logs in windows (in a computer with several users) and when the users logs out (or lock the computer) and with this information calculate the time the user has been logged in (I don't care about idle time) or better if I can get this last piece directly. (I don't mind if the user pull the cord, the service will be polling the current user and logging this information so I will know if the computer was turned off that way the next time it wakes up. It does not has to be exact).
I need to know this in order to kick the user out when they exceed certain limit of time.
I will be using either C# or Delphi, I'd appreciate to point me out which API's to look for to get this information.
There's already software around that checks this like that targeted to check the kids computer usage, I need something like that, but I will customize for another purpose than watch kids.
Actually, I may just need to know when the user logged in, and from that I will calculate the rest on my own.

Try the Win32_LogonSession WMI class, check the StartTime, LogonId and LogonType properties. Also you can take a look to the Win32_Session class.

The origin of the information come from SECURITY_LOGON_SESSION_DATA. You can use LsaGetLogonSessionData or LsaEnumerateLogonSessions. To get session Id of the thread (or user logon token) you can use GetTokenInformation with TokenSessionId as parameter.
In the old answer you will find the source code of the small demo.
If you need monitor user login and logoff I would recommend you to implement ISensLogon2 callback interface (see of the System Event Notification Service (SENS)) in your windows service. If you plan use it in C# I would recommend you the article.

You'll need to probably interrogate the windows event log to get this information. Eric Fitzgerald talks about some of this here. Note also that he links to here, on how relying on the "LogOff" event is, well, unreliable. This mentions my comment above, about people pulling out the power-chord.
The articles also mention the idiosyncrasies involved, such as the work-station being locked, etc...

Related

What type of Application should I choose to be executed daily while having a Global List?

I want to build an application to email field workers in our company when their passwords have expired. I'll be using some type of C# application while communicating with Active Directory.
I also want to ensure that users do not get emailed every single day/night, as this sounds a bit obnoxious. The idea I have is to create a web application with no UI, and have a global list of emailed users that never gets reset, just gets updated (user gets added when they are emailed, and get removed when their password is no longer expired). So I'll fill that list with a user object containing their samaccountname and the day they were emailed. If they are in the list, I don't want to email them again.
However, upon doing some reading, I found that multiple sources said that having a non-interactive web application to be executed on a schedule isn't a good way to do it. Instead, it seemed people were fond of Windows Services, which is something I don't know a lot about.
What would best practice to implement something like this? My ideas might also be completely off. Thanks for any insight.
Edit: New idea - Perhaps using an SQL table would be a better idea than a global list.
Yes, you're absolutely right about the storage, sql or nosql should do the job.
My advice is to store the the information you have describied in some database, this way you will have secure and long-living storage about the data (scenarios like power-cut, network drop or even simple restart of the server won't lead to loosing the information about the send emails).
Using the task scheduler with simple console application will be just fine. It sound more close to your needs (executing checks and notification at periods).

Automatically refreshing cache on a IIS server

Sorry for the lack of knowledge here guys by the agency I work for has inherited a site built on windows server with ASP.net.
We're having problems with the user login system. The basic story is when a user requests an account an admin must approve it. If the admin rejects the user application the user can then still login by using the forgot password option.
My initial reaction is bad logic in the code but we've had some ASP guys take a quick look and were unable to reproduce the problem. Because of this they've suggested it might be some kind of caching issue. If so is there anyway to set the sever to reset it's cache every hour or so? or any other recommendations on this are also welcome. Sorry for the complete lack of code examples but a scenario is all I can offer right now.
Cheers.
If you can't reproduce it then there is no problem; although I concede there might be a caching problem. But without knowing more about your application all I can suggest is to grep your source code for references to the System.Web.Caching.Cache class (usually accessed via the Page class directly if not by HttpContext.Current).
Removing the idea of a cache being responsible, I think it's just a case of bad coding of the forgot-password feature. I guess is the forgot-password feature resets some kind of "account disabled" flag and that's what allows the user to get in.
The ASP.Net caching class has an iterator for the cached items, and a method to remove an item. It's difficult to host long-running processes in IIS -- because "idle" worker processes get killed -- so you can't just run a timer. But you can use the IIS auto-start feature, combined with a persistent store, to run your "nuke the cache" method every hour.
With that said, I can't see how this is a sensible solution to the problem -- I hope the plan here is just to help isolate the real issue.

Determine if subscription is still valid without comparing to DateTime.Now

This question may be easy and the answer obvious, but I can't seem to be able to find a solution right now.
I built an application which has a big flaw in it. In a property of my User class, I check to see if the user subscription is expired. To do this, I compare the ending date of the subscription with DateTime.Now:
return (DateTime.Compare(DateTime.Now, subEndDate) > 0);
It doesn't take a genius user to realize that all it is needed is to change the Windows date to an earlier one, and then the application won't expire at all. So I think that comparing to DateTime.Now should not be done, is there a better method that I could use in order to validate a subscription date?
Thanks.
Regards,
Call a webservice or check a database to determine if the subscription is still active
Does this actually matter? If your product is purely web based the only time you have to worry about is your server time. If the server time is able to be altered without your consent you probably have larger problems to worry about.
If your product is desktop based, then how much protection do you want build in? If you just want to protect against your casual user the solution you have is probably enough. If someone is determined to pirate your software then they will probably be successful. If you want to make it harder for these users one solution would be to keep a log of all the times the application has been run. This way you can get an idea of they are playing with the clock.
Maybe you could extract the subscription expiration logic out of your client program and put it into an external service, then your client app could connect to a different server and retrieve expiration details based on a user parameter passed in?
There are several NTP servers out there which you can use for free... they return the exact time and your casual user won't have a hand in manipulating those... to access them you have several options - though none built-in:
http://dotnet-snippets.com/dns/simple-network-time-ntp-protocol-client-SID571.aspx
http://www.codeproject.com/KB/IP/ntpclient.aspx
http://www.codeproject.com/KB/datetime/SNTPClient.aspx
http://www.rebex.net/time.net/ (commercial)

Kick users out of an application

I have written an application that is used company wide. A lot of users have the tendency to leave the application open 24-7. This application is under development constantly as the Marketing department's needs change. Most changes are minor but often times need to be implemented quickly. Salesmen are often away from their desks or on the phone, so an intercom announcement does not always do the trick. The application is housed on a network file share and shortcutted to.
What I envision is something like a message popping up something like "The program will exit for an update in five minutes, please save your changes now." Is there a way to display this message and kick them from the exe remotely? I thought of maybe just having a database value that it checks periodically to see if an update is pending, but that seems like a cheap hack to me.
Your database check is as good as any other; I personally would recommend polling some service to which it subscribes that would do the same thing. If your app connects directly to the database, however, you're probably better off making the check in the database.
You'd be best off going with a ClickOnce deployment method, however. That would require a major architectural change, but would be best in the long run, IMO.
Pity it's not a web application. Deployment would be a snap!
Anyhow what I'd do is this. Make the application log users out after several minutes of inactivity.
Two approaches to unsaved work. Do nothing and therefore they loose it if unsaved when they are inactive and it logs them out.
As they work, a local journal of changes is kept. When they are logged out due to inactivity, logging back will use the journal to open things back up as they were.
EDIT: To prevent users from using the old version. Write a database field with a version or build number. If running version < version in db field then refuse login, and/or restart program to load new image.
You can set up a central server that the .exe sends requests to to find out when updates are available.
I would recommend that you look into WCF as a framework for your solution; there are many great references for the framework as well as posts on sites like this one. You can probably spin up a separate thread in your application that checks for updates every X minutes.
As for your specific question, "Is there way to display this message and kick them from the exe remotely?", yes it is possible, but it is more feasible to make the program automatically query for the update.
If you want to shut them down for update remotely, then you have to know where they are on the network. If the program periodically contacts a central database, then there is no need for the server to know where the program is on the network, the program can automatically reach out to the server from wherever it is.
You could use a messaging system such as RabbitMQ, or any other one, and have the applications listen to a channel in the system. Then an administrative application could send a message to the user applications forcing them to shut down.
If the changes aren't breaking changes, you might want to look at something like ClickOnce which allows you to publish updates to applications while the users are running them, though users will be running old versions of the application until it restarts.
I didn't get what you got stuck on. Just create a timer, and on user interaction, reset the timer, to e.g. 5 minutes. Then, when the timer fires, show the message box, and create another timer, when that one fires, just kill the current process.
Rather tangential answer but if the issue is people leaving workstations up and logged on then take a look at something like nightwatchman from www.1e.com that powers down the PC after x period of inactivity. Sell it to your company as "doing your bit for the environment" and saving wasted electricity costs.

Filling Windows XP Security Event Log

I am in need of filling the Windows Security Event Log to a near full state. Since write access to this log is not possible, could anybody please advise as to an action that could be programatically performed which would add an entry to this log? It does not need to be of any significance as long as it gives an entry (one with the least overhead would be desired as it will need to be executed thousands of times).
This is needed purely for testing purposes on a testing rig, any dirty solution will do. Only requirement is that it's .NET 2.0 (C#).
You can enable all the security auditing categories in local security policy (secpol.msc | Local Policies | Audit Policy). Object access tends to give plenty of events. Enabling file access auditing, then set audit for everyone on some frequently accesses files and folders will also generate lots of events.
And that's normal usage, and that includes any programmatic access to those resources being audited (its all programmatic in the end, just someone else's program).
Enable Login Auditing as Richard mentioned above. Success or Failure is dependent upon how you handle step 2:
Use LoginUser to impersonate a local user on the system - or FAIL to impersonate that local user on the system. Tons of samples via good for viable C# implementations.
Call in a tight loop, repeatedly.
Another approach you can take involves engaging object access, and doing a large number of file or register I/O operations. This will also cause the log to fill out completely in an extremely short period of time.

Categories

Resources