Take the 2-minute tour ×

I created my own parental control app using C# to monitor my kids activity. It logs all the keyboard input and screens in the background silently, with the only gui of taskbar icon. So far, I just let it run in my admin account and everybody share the same account and it works fine. The problem is that as kids grow up, they found a way to kill it from the task manager. So, I need to use a more sophisticated way to protect my app. I thought I could solve this problem easily by creating a separate standard account for each kid and I can setup my app to run as an admin to monitor all their activities. However, I faced a lot of issues.

  1. The keyboard hooks seem to stop working once I switched to a different user account. Is it true? I thought it's global hook - is it just global within the user account?

  2. The screen capturing doesn't work on another user account either. This is my code and

it failed at g.CopyFromScreen with error "the handle is invalid":

RECT rc = Win32.GetWindowRect();
using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(rc.Width, rc.Height))
    using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
        g.CopyFromScreen(rc.Location, System.Drawing.Point.Empty, new System.Drawing.Size(rc.Width, rc.Height));
        string fileName = Settings.Instance.GetImageFileName();
        bitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);

Your help is much appreciated.

share|improve this question
You have bumped into the new Windows 7 features. Message filters and integrity levels. My question, though, how do you run the application? Within their account within the admin account? On what desktop? It will only work on the same desktop. Did you fix the desktop and window station ACL to grant access to the credentials as which your program runs? –  0xC0000022L Apr 3 '11 at 2:24
Actually, I tried different ways to run the program (e.g. from Windows Service, or through Scheduled Tasks), but couldn't get it work. I'm not familiar with Win7's new features as you mentioned. For my testing, I simply started the program from my admin account, then switched to kid's account as standard user. –  miliu Apr 3 '11 at 2:30
that won't work. Service also won't work (since about Vista due to the session separation restrictions). You have to run the process within the same desktop/winsta as the shell of the account that you want to monitor. –  0xC0000022L Apr 3 '11 at 2:57
add comment

1 Answer

up vote 2 down vote accepted

As long as the kids aren't administrators, you can run the program under their accounts and deny access to the process.

For example (tested):

static void SetAcl() {
    var sd = new RawSecurityDescriptor(ControlFlags.None,
        new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null),
        null, null, new RawAcl(2, 0));

    sd.SetFlags(ControlFlags.DiscretionaryAclPresent | ControlFlags.DiscretionaryAclDefaulted);
    var rawSd = new byte[sd.BinaryLength];

    sd.GetBinaryForm(rawSd, 0);
    if (!NativeMethods.SetKernelObjectSecurity(Process.GetCurrentProcess().Handle, SecurityInfos.DiscretionaryAcl, rawSd))
        throw new Win32Exception();

static class NativeMethods {
    [DllImport("Advapi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SetKernelObjectSecurity(IntPtr target, SecurityInfos info, byte[] descriptor);
share|improve this answer
It's not so much tied to a particular group as it is to privileges, though. –  0xC0000022L Apr 3 '11 at 2:20
Hi Slaks: Thanks a million. This is exactly what I want, I believe. But could you please elaborate a little bit more on how to use it? Who is going to call SetAcl()? –  miliu Apr 3 '11 at 2:37
Call in in your program, and run under the limited user. –  SLaks Apr 3 '11 at 2:38
+1 from me. Also, make sure that you don't have any windows that would accept messages from other processes. There are no ACLs on windows, which is the reason why this could be a loophole. –  0xC0000022L Apr 3 '11 at 3:00
I just tried it. In the installer, there is an option "Launch automatically when Windows starts up" > "For all users". After installion with this option, the program started automatically after reboot. However, in the standard user account, this program shows up in the task manager as my "admin" user. I guess, because of that, I cannot find the task bar icon for this app and the app doesn't seem to be working either. How do I workaround this limitation? I'd like to install once from my admin account and make it run for all accounts. Is it possible? How? –  miliu Apr 3 '11 at 3:34
show 6 more comments

Your Answer


