Detecting User logon/logoff events

G

Guest

I have written a windows service that needs to perform certain functions only if a User is logged in. The problem I am running into is that I get an error if the computer is in the process of being shut down or restarted. At all other times, the service runs just fine.

I need to either detect a logon/logoff event OR check somehow as to whether there is currently a valid logged on user. The closest I have found is ManagementEventWatcher class, but I am not able to determine the appropiate event class to query for the Audit logon/logoff events. Basically I just need to not try and open the ad-watch if the user has logged off (Event Id 538). Of course, if there is an easier check, please let me know of that! (WindowsIdentity.CurrentIdentity() does not work because it returns the system account, which is the context that the service is running under).

I do appreciate any assistance on this. Thank you!
 
N

Nick

Aarti said:
I have written a windows service that needs to perform certain functions only if a User is logged in. The problem I am running into is that I get an error if the computer is in the process of being shut down or restarted. At all other times, the service runs just fine.

I need to either detect a logon/logoff event OR check somehow as to whether there is currently a valid logged on user. The closest I have found is ManagementEventWatcher class, but I am not able to determine the appropiate event class to query for the Audit logon/logoff events. Basically I just need to not try and open the ad-watch if the user has logged off (Event Id 538). Of course, if there is an easier check, please let me know of that! (WindowsIdentity.CurrentIdentity() does not work because it returns the system account, which is the context that the service is running under).

I do appreciate any assistance on this. Thank you!

I hope I understood you correctly.

As far as I understand your problem is in the startup and shutdown processes. I think there is an option/property/something else?
that tells windows to warn the service when windows is about to shutdown. So when the service gets this message you can shut it
down manually to prevent the error that occurs from occuring. I'm sorry for being so vague, but I really dont know much about
services. I only read somewhere (cant find where) that there is this option, as I am implementing a service for my application in
the near future.

One other thing that I had in mind. Instead of checking if someone is logged on, you could test if some vital system service is
running, something that would be running only if the user was logged on. Not the best solution, just an idea.

Good luck.
Nick Z.
 
G

Guest

If you want the service to be notified when computer is shut down or restarted,
(1) Set CanShutDown property to true.
(2) Override OnShutDown() method to write appropriate code.

Set the serviceInstallers StartupType to Automatic, so that the service is started automatically when the computer is restarted, and you can write code for starting up the service in OnStart().

Similarly there are two more properties CanStop and CanHandlePowerEvent, which decide whether the service is notified of being stopped and when there is a change in power status (for example when computer goes into suspended mode), and corresponding methods, OnStop and OnPowerEvent, which may be used as per demand of application.

Hope this helps.
 
S

Sunny

OT, and just for fun: (lsc stands for logon status checker)
http://www.stupidapps.com/lsc-home.html

Sunny


I have written a windows service that needs to perform certain functions only if a User is logged in. The problem I am running into is that I get an error if the computer is in the process of being shut down or restarted. At all other times, the service runs just fine.

I need to either detect a logon/logoff event OR check somehow as to whether there is currently a valid logged on user. The closest I have found is ManagementEventWatcher class, but I am not able to determine the appropiate event class to query for the Audit logon/logoff events. Basically I just need to not try and open the ad-watch if the user has logged off (Event Id 538). Of course, if there is an easier check, please let me know of that!
(WindowsIdentity.CurrentIdentity() does not work because it returns the system account, which is the context that the service is running under).
 
N

Nick

On another note, I cannot believe how difficult it is to determine whether or not the icon tray or windows taskbar was loaded!!

I got an idea for that. Find out the class name or the window name of the tray icon. You can try to do that using GetWindowText
API call, you only need to find this out once, not everytime at runtime.

Now whenever your service starts you can call FindWindow with window text you found out previously as the windowName parameter. If
the window is found then the tray icon exists, if not then it didnt load yet. =) All controls including the tray icon are
technically windows as the OS sees it.

If you need further info or clarification, post here. If you cant find the class name or window name to call find window, post the
name and version of the application that loads the tray icon (ad-watch right? I even think I got it installed) I can probably get
it for you. A few days ago I made a litle program that gets the handles of any window from mouse clicks, I think it would be
fairly easy to expand to get some more info about the window.

Good luck.
Nick Z.
 
N

Nick

Aarti said:
Nick
I will try this out. I have not done any API-related stuff in .NET as yet, but will give this a shot. Seems to make sense! Thanks again for your help. I'll post back with the trial results!
Aarti

:

Here is something to help you out.
First include System.Runtime.InteropServices

//then import the function that you need using interop
[DllImport("user32.dll",EntryPoint="SendMessage")]
public static extern int SendMessage(IntPtr h_Window,uint message,uint param1,uint param2);

The uint values you can get from winuser.h which is included with the platform sdk.
By the way I tried sending the message to the desktop window it does nothing.
Anybody know which direction the numlock key down event gets sent?
 
N

Nick

Aarti said:
Nick
It appears that the System tray window does not have a title. From what I could gather, the title it returns in GetWindowText is what appears in the title bar and since there is none for the system tray, it returns nothing. I am thinking of perhaps using GetDesktopWindow as a proxy, although I don't know if that is too much better than checking for whether explorer.exe is running. I read that there is some other Shell dll to manipulate icons in the system tray .. perhaps that also has something to retrieve something I can use as a check. For example, the System Date and Time is always displayed and the user cannot remove it (thus invalidating my check). Thanks!
Aarti

:

Aarti said:
Nick
I will try this out. I have not done any API-related stuff in .NET as yet, but will give this a shot. Seems to make sense! Thanks again for your help. I'll post back with the trial results!
Aarti

:



On another note, I cannot believe how difficult it is to determine whether or not the icon tray or windows taskbar was loaded!!

I got an idea for that. Find out the class name or the window name of the tray icon. You can try to do that using GetWindowText
API call, you only need to find this out once, not everytime at runtime.

Now whenever your service starts you can call FindWindow with window text you found out previously as the windowName parameter. If
the window is found then the tray icon exists, if not then it didnt load yet. =) All controls including the tray icon are
technically windows as the OS sees it.

If you need further info or clarification, post here. If you cant find the class name or window name to call find window, post the
name and version of the application that loads the tray icon (ad-watch right? I even think I got it installed) I can probably get
it for you. A few days ago I made a litle program that gets the handles of any window from mouse clicks, I think it would be
fairly easy to expand to get some more info about the window.

Good luck.
Nick Z.

Here is something to help you out.
First include System.Runtime.InteropServices

//then import the function that you need using interop
[DllImport("user32.dll",EntryPoint="SendMessage")]
public static extern int SendMessage(IntPtr h_Window,uint message,uint param1,uint param2);

The uint values you can get from winuser.h which is included with the platform sdk.
By the way I tried sending the message to the desktop window it does nothing.
Anybody know which direction the numlock key down event gets sent?

I was thinking of getting the class name of the tray app. I just cant find anything that would give me such info.
I'll give it a deeper look.

Nick Z.
 
N

Nick

Aarti said:
Nick
It appears that the System tray window does not have a title. From what I could gather, the title it returns in GetWindowText is what appears in the title bar and since there is none for the system tray, it returns nothing. I am thinking of perhaps using GetDesktopWindow as a proxy, although I don't know if that is too much better than checking for whether explorer.exe is running. I read that there is some other Shell dll to manipulate icons in the system tray .. perhaps that also has something to retrieve something I can use as a check. For example, the System Date and Time is always displayed and the user cannot remove it (thus invalidating my check). Thanks!
Aarti

:

Aarti said:
Nick
I will try this out. I have not done any API-related stuff in .NET as yet, but will give this a shot. Seems to make sense! Thanks again for your help. I'll post back with the trial results!
Aarti

:



On another note, I cannot believe how difficult it is to determine whether or not the icon tray or windows taskbar was loaded!!

I got an idea for that. Find out the class name or the window name of the tray icon. You can try to do that using GetWindowText
API call, you only need to find this out once, not everytime at runtime.

Now whenever your service starts you can call FindWindow with window text you found out previously as the windowName parameter. If
the window is found then the tray icon exists, if not then it didnt load yet. =) All controls including the tray icon are
technically windows as the OS sees it.

If you need further info or clarification, post here. If you cant find the class name or window name to call find window, post the
name and version of the application that loads the tray icon (ad-watch right? I even think I got it installed) I can probably get
it for you. A few days ago I made a litle program that gets the handles of any window from mouse clicks, I think it would be
fairly easy to expand to get some more info about the window.

Good luck.
Nick Z.

Here is something to help you out.
First include System.Runtime.InteropServices

//then import the function that you need using interop
[DllImport("user32.dll",EntryPoint="SendMessage")]
public static extern int SendMessage(IntPtr h_Window,uint message,uint param1,uint param2);

The uint values you can get from winuser.h which is included with the platform sdk.
By the way I tried sending the message to the desktop window it does nothing.
Anybody know which direction the numlock key down event gets sent?

Got it to work.
Here is the code that tests whether the icon tray window is loaded. =)

First interop the only funciton we need, FindWindow, like so:

[DllImport("user32.dll",EntryPoint="FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr parentToLookFrom,IntPtr childToLookFrom,string className,IntPtr windowName);

Now whenever you need to check if the icon tray is loaded do this.

//find the handle to the whole taskbar
//First argument is the handle to desktop
//second is equal to null
//third is taskbar class name
//fourth is window name as null

IntPtr trayWindowHandle = FindWindowEx(IntPtr.Zero,IntPtr.Zero,"Shell_TrayWnd",IntPtr.Zero);

//find the handle to the specific part of taskbar
//first argument is handle to the taskbar
//second is null
//third is the class name of icon tray
//fourth is null

IntPtr notifyWindowHandle = FindWindowEx(trayWindowHandle,IntPtr.Zero,"TrayNotifyWnd",IntPtr.Zero);

//test if the handle was found

if(notifyWindowHandle.ToInt32() != 0)
{
//then icon tray exists
}
else
{
//it doesnt
}

Hope this helps.
Nick Z.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top