2

I have a windows form that needs to be able to check the windows screen saver settings (Is it active, is it under 15 minutes, is "on resume, display logon" active) Essentially if all of those are true the user gets a nice big PASS if not the user gets a big FAIL in a textbox. I have looked online and have found nothing that accomplishes this. I was thinking I would check the settings through windows registry since I will have to do this method of other system settings anyway.

(I used to use a BAT to accomplish this which I will post below for context, but I need somethings compatible with vista and up that displays the results in a user-friendly manner)

echo The following check is for 15 minute inactive lock
echo if true the setting will be set to 1 of false 0
echo            
echo is the screen saver active
reg query "HKCU\Control Panel\Desktop" /v ScreenSaveActive
echo is the screen saver locking the device
reg query "HKCU\Control Panel\Desktop" /v ScreenSaverIsSecure
echo How long until the screen saver activates (900 or below for compliance) 
reg query "HKCU\Control Panel\Desktop" /v ScreenSaveTimeOut
reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\GroupPolicyObjects"
Joe Pearson
  • 105
  • 10
  • You could always query those registry settings with C#... – Der Kommissar Apr 29 '15 at 19:15
  • I have been searching how to query them for 2 days straight haha, any chance you found an article or have some sample code? – Joe Pearson Apr 29 '15 at 19:17
  • https://msdn.microsoft.com/en-us/library/microsoft.win32.registry.getvalue%28v=vs.110%29.aspx – Der Kommissar Apr 29 '15 at 19:19
  • http://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C has most of it, just not sure where the Is Secure flag is... – Ron Beyer Apr 29 '15 at 19:20
  • Im a little confused from his article, I get that it makes a segmented call to registry after setting the const strings userRoot and subkey. However, I honestly don't understand about anything else below it haha. Im assuming i set those const string userRoot = "HKEY_CURRENT_USER"; const string subkey = "Desktop"; const string keyName = userRoot + "\\" + subkey; – Joe Pearson Apr 29 '15 at 19:28
  • Actually, if you want to just read Reg keys, that article is a horrible resource. – DonBoitnott Apr 29 '15 at 19:30
  • I'm not sure I'd trust the registry values, on my machine HKCU\Control Panel\ScreenSaveActive is 1, but very clearly I've disabled the screen saver... The article I posted doesn't make registry calls. – Ron Beyer Apr 29 '15 at 19:31
  • I simply want to query, read the value, and set a bool to either say the user's settings are correct or incorrect. if there are better resources than this, I would LOVE to find them. – Joe Pearson Apr 29 '15 at 19:31
  • Set what flag where? – DonBoitnott Apr 29 '15 at 19:32
  • the query would post to either an invisible textbox so that I can go back and see if things arent working properly, or I could simply set the query result to a string and assign that string to a variable that is already being checked. – Joe Pearson Apr 29 '15 at 19:35

2 Answers2

1

Add to your code page: using Microsoft.Win32;

Then use this code to pull values from the registry:

using (var key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop"))
{
    if (key != null)
    {
        Boolean isActive = false;
        Boolean isSecure = false;
        Int32 timeoutSeconds = 0;
        var o = key.GetValue("ScreenSaveActive", "");
        if (!String.IsNullOrWhiteSpace(o as String))
        {
            Int32 i;
            if (Int32.TryParse((String)o, out i))
                isActive = (i == 1);
        }
        o = key.GetValue("ScreenSaverIsSecure", "");
        if (!String.IsNullOrWhiteSpace(o as String))
        {
            Int32 i;
            if (Int32.TryParse((String)o, out i))
                isSecure = (i == 1);
        }
        o = key.GetValue("ScreenSaveTimeOut", "");
        if (!String.IsNullOrWhiteSpace(o as String))
        {
            Int32 i;
            if (Int32.TryParse((String)o, out i))
                timeoutSeconds = i;
        }
    }
}

As Ron Beyer pointed out in comments, the ScreenSaveActive flag alone might not be reliable. It might be that you have to consider the flags together to get the complete picture.

Note that all of the string parsing is due to the fact that the values are stored as REG_SZ, and not numeric, as this link describes for one of them.

DonBoitnott
  • 10,787
  • 6
  • 49
  • 68
  • You could also just compare to a string value instead of converting it to another type – Rufus L Apr 29 '15 at 19:47
  • this looks awesome, I get what you were doing here. My only confusion is it looks like your result for pass is predicated on retrieving a null or black answer? how do I apply this check to something tangible like a textbox. (let's say textbox1.Text for simplicity) – Joe Pearson Apr 29 '15 at 20:12
  • One comment on this code (which is good) is that, for consistency, your default value for `timeoutSeconds` should probably be `Int.Max` rather than `0`, since `0` is a "compliant" value. – Rufus L Apr 29 '15 at 21:11
1

It sounds like you're trying to read a registry key and set a Boolean based on the value. If that's the case, this should help:

RegistryKey regDesktop = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop");

bool isScreenSaverActive = regDesktop != null && 
    regDesktop.GetValue("ScreenSaveActive").ToString() == "1";

If the settings you described in your question are the only ones you want to check, here's a method that will return true if they exist and match your expected values (ScreenSaveActive == 1, ScreenSaverIsSecure == 1, and ScreenSaveTimeOut <= 900):

public static bool LockSettingsAreCompliant()
{
    bool lockSettingsAreCompliant = false;

    try
    {
        using (var regKey = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop"))
        {
            lockSettingsAreCompliant =
                regKey.GetValue("ScreenSaveActive").ToString() == "1" &&
                regKey.GetValue("ScreenSaverIsSecure").ToString() == "1" &&
                int.Parse(regKey.GetValue("ScreenSaveTimeOut").ToString()) <= 900;
        }
    }
    catch
    {
        // Swallow exceptions and let the method return false
    }

    return lockSettingsAreCompliant;
}

And then you can use this method like the following to set the textbox text:

screenSaver.Text = LockSettingsAreCompliant() ? "PASS" : "FAIL";
Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • So then would that if/then work? or am i drawing form the wrong var – Joe Pearson Apr 29 '15 at 20:15
  • Oh, you are trying to edit my answer? That is not correct. The Boolean `isScreenSaverActive` will be true if the registry key equals one. then you still need to check the other keys, right? This is just an example of how to check a key. – Rufus L Apr 29 '15 at 20:20
  • I updated my answer with a full example, hopefully that helps some. – Rufus L Apr 29 '15 at 20:35
  • Im running this code and just don't seem to see an output when compiled. Im sure its something on my end. I checked the textbox name, (yes i know C# is case sensitive) I just can seem to get this to display pass or fail. I will keep plugging away. Thanks for all your help, you guys are awesome! I will post answer once I get this to work. – Joe Pearson Apr 29 '15 at 22:31
  • Is there some DLL or call like (using Microsoft.Win32;) that I am supposed to be using for this? I cant seem to get a response – Joe Pearson Apr 29 '15 at 22:50
  • Where did you put this code: `screenSaver.Text = LockSettingsAreCompliant() ? "PASS" : "FAIL";` – Rufus L Apr 30 '15 at 04:11
  • I found the issue, I placed it internal of the private void textbox, instead I moved it to PublicForm1() and now it works like a dream. I can't thank you enough. – Joe Pearson Apr 30 '15 at 18:57