如何防止 Windows 中的策略强制屏幕锁定?

Gab*_* R. 146 windows screensaver security-policy

我们的公司 BOFH 强加了屏幕锁定设置,但延迟时间短得可笑。这是令人沮丧和适得其反的。

有没有办法防止自动锁屏?我认为没有办法覆盖策略强制设置,但也许有一个模仿用户活动的软件。

在我设置永久鼠标滚轮之前问一下。(得到它?)

小智 121

如果仍安装了 Windows Media Player,您可以循环播放视频并将其最小化(示例“Wildlife”视频对此很有效)。默认情况下,只要正在播放视频,屏幕就不会锁定。

  • 谢谢!这是最简单、最有效的解决方案。(虽然我没有尝试,我前段时间离开了公司,并试图远离 Windows。) (6认同)
  • 我确认这适用于使用 MP3 文件而不是视频的 Windows XP。 (6认同)
  • 辉煌的黑客! (6认同)
  • 对于那些喜欢它而不是 Windows Media Player 的人,这也适用于使用 VLC (5认同)
  • 在 Windows 7 中运行良好。不错的 hack! (4认同)
  • 伟大的黑客。我构建了一个小的空白视频和批处理脚本来启动它。[box.net] (https://app.box.com/s/khcc45viol53oswmzo3v) 上的文件和 [我的个人网站] (http://www.ericcloninger.com/?p=578) 上的博客文章 (3认同)
  • @ShatayuDarbhe 是的,它也适用于 Windows 10。 (2认同)

Jos*_*ers 111

我使用了一个名为 idle.vbs 的脚本:

Dim objResult

Set objShell = WScript.CreateObject("WScript.Shell")    

Do While True
  objResult = objShell.sendkeys("{NUMLOCK}{NUMLOCK}")
  Wscript.Sleep (6000)
Loop
Run Code Online (Sandbox Code Playgroud)

每六秒,这会快速切换键盘上的 numlock,使 Windows 相信有人正在与键盘交互,从而防止屏幕锁定。这在 vanilla windows 上运行,您不需要开发或脚本工具来使用它,只需制作一个以 .vbs 作为扩展名的文本文件,然后双击它(或将它放在您的启动项中)。

编辑:您可以将此脚本放在您的启动项中

 choco install IdleVbs -source https://www.myget.org/F/joshrivers-utility/
Run Code Online (Sandbox Code Playgroud)

有关 Choclatey ( choco) CLI 安装程序的更多信息,请参阅:

https://chocolatey.org/

  • @DeeJayh 我想你可以在任务管理器中找到 wscript.exe 的实例并杀死它。通常没有很多运行该可执行文件的实例。您可能可以为终止(http://stackoverflow.com/a/22325745)或通过将代码放在监视外部事实的 Do While 部分中来制定自动解决方案。就像让脚本在启动时创建一个文件一样,然后检查该文件是否存在于 While 中。这样您就可以删除文件以使脚本终止。(不过,我从不退出这个东西,所以我只是运行脚本,很少用任务管理器杀死它)。 (7认同)
  • 在 Windows 10 上,找到启动文件夹的一种简单方法是显示开始->运行窗口(例如 WindowsKey+R),然后键入 `shell:startup`。有关更多信息,请参阅此站点 http://www.thewindowsclub.com/startup-folder-in-windows-8 (3认同)

小智 34

另一种选择是免费软件Caffeine程序。它也可免费用于商业用途。从程序的主页:

如果您的 PC 锁定或进入睡眠状态有问题,咖啡因会使其保持清醒。它的工作原理是每 59 秒模拟一次按键操作,因此您的机器认为您仍在使用键盘,因此不会锁定屏幕或激活屏幕保护程序。

Caffeine 的工作原理是每 59 秒模拟一次 F15 键按下事件。在所有可用的按键中,F15 可能是干扰最少的(我从未见过带有该键的 PC 键盘!),并且最不可能干扰您的工作。

这种现成的解决方案还允许您控制何时启用和禁用它:

双击程序图标会清空咖啡壶,这就是图标所代表的,并暂时禁用程序。再次双击它会重新装满锅,并使您的机器保持清醒。

  • 我在等待政府员工将咖啡因放在他们的计算机上的那一天,而 Shift+F15 之类的东西恰好会发射核武器...... (23认同)
  • 我认为在企业环境中,您可能(并且应该)在机器上安装此类工具时遇到麻烦,尤其是如果它不是“您的”机器。VBS 解决方案要简洁得多,至少您确切地知道它的作用。 (2认同)
  • 请记住,模拟按键是防止屏幕锁定的一种非常残酷的方法。为了更好的方法,请查看我的[答案](https://superuser.com/a/1604470/1182474)。 (2认同)

Pol*_*ear 10

1.(最佳选择)Microsoft PowerToys Awake

PowerToys 觉醒 在此输入图像描述

它是如何工作的

该工具使用SetThreadExecutionState WinApi 函数来保持屏幕打开。这是视频播放器用来在您观看电影时保持屏幕打开的功能。

2.咖啡豆

我创建了一个类似于 PowerToys Awake 的小托盘图标应用程序CoffeeBean 。我的工具的优点是:

  • 轻的。
  • 支持旧版本的 Windows。
  • 无需安装即可作为独立可执行文件使用。

3.自动热键脚本

如果您了解 AutoHotkey 工具,则可以使用以下脚本


Hex*_*gon 9

扩展Cherona答案,这里是 PowerShell 中使用 SetThreadExecutionState() 的实现。

只要脚本正在运行,屏幕保护程序和屏幕锁定就不会启动。

Set-StrictMode -version 3.0

# Definition of SetThreadExecutionState from -
#   http://www.pinvoke.net/default.aspx/kernel32/SetThreadExecutionState.html
#   https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
# "EXECUTION_STATE" changed to "uint", added "public" modifier.
$Signature = @'
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint SetThreadExecutionState(uint esFlags);
'@

$ES_AWAYMODE_REQUIRED = 0x00000040L
$ES_CONTINUOUS        = 0x80000000L
$ES_DISPLAY_REQUIRED  = 0x00000002L
$ES_SYSTEM_REQUIRED   = 0x00000001L

# Details on Add-Type in https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/add-type?view=powershell-7.
$Kernel32 = Add-Type -MemberDefinition $Signature -Name 'Kernel32' -Namespace 'Kernel32' -PassThru

echo "Forcing system to not go to sleep (disable screen saver)."
echo "Close the window to allow sleep again."
$result = $Kernel32::SetThreadExecutionState($ES_CONTINUOUS -bor $ES_DISPLAY_REQUIRED -bor $ES_SYSTEM_REQUIRED)

# Loop until script is forcibly stopped.
While ($true) {
  Start-Sleep (60 * 60 * 24)  # 24 hours.
}
Run Code Online (Sandbox Code Playgroud)


Bre*_*ugh 8

您可以创建一个AutoIt脚本来连续按下一个未使用的键(例如,让它切换数字锁定、滚动锁定)、休眠一分钟左右,然后重复。或者,如果你经常使用键盘,你可以让它在任何方向移动一个像素左右。

如果您不希望它持续运行,您还可以将脚本作为计划任务(如果您有访问权限)启动,以便在计算机处于非活动状态一段时间后启动。

如果您不想进入 AutoIt 语法,这是一个非常简单的脚本来执行不可见的鼠标移动:

While True
   Local $pos = MouseGetPos()
   MouseMove($pos[0]-1, $pos[1]-1, 0)
   MouseMove($pos[0], $pos[1], 0)
   Sleep(540000)
WEnd
Run Code Online (Sandbox Code Playgroud)

此脚本将鼠标光标在左上方向移动一个像素,然后将其返回,然后休眠 9 分钟(540000毫秒)。当脚本运行时,您可以在托盘中看到 AutoIt 图标。您可以通过右键单击此图标并选择相应选项来停止它。

要制作脚本,请安装 AutoIt,右键单击任何文件夹并选择New> AutoIt v3 Script,命名它,右键单击这个新脚本,选择Edit,粘贴上面提供的代码并保存。您甚至可以将其编译为.exe(同样,从上下文菜单)以启动,例如,从 Windows 调度程序。


eli*_*eli 7

我喜欢使用简单集成的选项(没有额外的软件),比如一个 powershell 脚本(感谢https://dmitrysotnikov.wordpress.com/2009/06/29/prevent-desktop-lock-or-screensaver-with-powershell/ ) 使用“f15”作为成功的关键(感谢咖啡因。它确实干扰最少)

param($minutes = 180)

write "... screen will be awake for $minutes"

 $myshell = New-Object -com "Wscript.Shell"

 for ($i = 0; $i -lt $minutes; $i++) {
 write "... screen will be awake for" ($minutes-$i)
 Start-Sleep -Seconds 60    
 $myshell.sendkeys("{F15}")
}
Run Code Online (Sandbox Code Playgroud)

将其放入 myScriptName.ps1 并通过桌面快捷方式或命令行启动它: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -nop "C:\Users\myUser\Desktop\myScriptName.ps1"

更新: 也许管理员进行了一些更改,但这对我不再适用现在我必须使用来自 NBirnel 的 autohotkey 脚本:https : //github.com/nbirnel/nosleep - 这个工作完美,因为它移动鼠标(不会分散任何工作的注意力)


小智 6

有一个名为“Timeout Blocker”的安卓应用,它会每隔一段时间振动一次,你可以把鼠标放在上面。它说不要在工作中使用它。https://play.google.com/store/apps/details?id=com.isomerprogramming.application.timeoutblocker&hl=en


Che*_*ona 6

很多这些答案都是旧的,只有通过输入/鼠标移动才能保持活力。用 C 或 C++ 编译它,这将通过设置线程执行状态来保持会话处于活动状态(当然仅限 Windows)

#include <windows.h>

//https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate

#define ES_CONTINUOUS       0x80000000
#define ES_DISPLAY_REQUIRED 0x00000002
#define ES_SYSTEM_REQUIRED  0x00000001

int main()
{
    int result = 0;
    while(1)
    {
        result = SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED | ES_CONTINUOUS);
        Sleep(30 * 1000);
    }

    //unreachable
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

  • PowerShell 等效实现位于 https://superuser.com/a/1596783。 (2认同)

小智 5

在 Visual Studio 或 C# Express 中编译它并从命令提示符运行它(或双击它)。需要 .NET 4.0 或更高版本。它可以完成您正在寻找的一切。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using System.Windows.Forms; 

namespace ImWorkin
{
    class Program
    {
        [FlagsAttribute]
        public enum EXECUTION_STATE : uint
        {
            ES_SYSTEM_REQUIRED = 0x00000001,
            ES_DISPLAY_REQUIRED = 0x00000002,
            ES_CONTINUOUS = 0x80000000
        }
        public SYSTEMTIMEOUTS TimeOuts
        {
            get { return sysTimeouts; }
        }
        public struct SYSTEMTIMEOUTS
        {
            public int BATTERYIDLETIMEOUT;
            public int EXTERNALIDLETIMEOUT;
            public int WAKEUPIDLETIMEOUT;
        }

        [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE flags);

        [DllImport("user32.dll", SetLastError = true, EntryPoint ="SystemParametersInfo")]
        internal static extern int SystemParametersInfo(int uiAction, int uiParam, ref int pvParam, int fWinIni);

        private static System.Threading.Timer preventSleepTimer = null;
        public const int SPI_GETBATTERYIDLETIMEOUT = 252;
        public const int SPI_GETEXTERNALIDLETIMEOUT = 254;
        public const int SPI_GETWAKEUPIDLETIMEOUT = 256;
        public static int Counter = 0;
        public static int timeOutinMS = 0;
        public static int batteryIdleTimer;
        public static int externalIdleTimer;
        public static int wakeupIdleTimer;
        public static SYSTEMTIMEOUTS sysTimeouts;


        static void Main(string[] args)
        {
            Console.WriteLine("You are about to be workin!! Just a moment...I need to calculate a few values.");
            string dots = string.Empty;
            for (int i =2; i < 60; i++)
            {
                dots = "";
                for (int ii = 0; ii < i; ii++)
                {
                    dots = dots + ".";
                }
                Thread.Sleep(100);
                Console.Clear();
                Console.WriteLine("You are about to be workin!! Just a moment...I need to calculate a few values.");
                Console.WriteLine(dots);
            }


            GetSystemTimeOuts();


            if (timeOutinMS < sysTimeouts.BATTERYIDLETIMEOUT)
                timeOutinMS = sysTimeouts.BATTERYIDLETIMEOUT;
            if (timeOutinMS < sysTimeouts.EXTERNALIDLETIMEOUT)
                timeOutinMS = sysTimeouts.EXTERNALIDLETIMEOUT;
            if (timeOutinMS < sysTimeouts.WAKEUPIDLETIMEOUT)
                timeOutinMS = sysTimeouts.WAKEUPIDLETIMEOUT;

            if (timeOutinMS == 0)
                timeOutinMS = 30;

            DisableDeviceSleep();
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("OK. I have calculated your computers timeout periods and set the   ");
            Console.WriteLine("necessary hooks. Your computer will not shut off the monitor, will");
            Console.WriteLine("show active in any chat programs,the screensaver is disabled and ");
            Console.WriteLine("the computer will not lock! Anyone looking at you eaither locally ");
            Console.WriteLine("or remotely will think you are hard at work.");
            Console.WriteLine("");
            Console.WriteLine("Now go do something fun...I got your back ;)");
            Console.WriteLine("Oh yeah....if you close this window OR press `q' in this ");
            Console.WriteLine("window you are going to have to actually work.");
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("This text will disappear in a 30 seconds. Just in case someone comes ");
            Console.WriteLine("by and reads your screen!");
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("Need custom coding? Kenneth.gore@gmail.com");
            while (Console.KeyAvailable == false)
            {
                Thread.Sleep(250);
                ConsoleKeyInfo cki = Console.ReadKey(true);

                if (cki.KeyChar == 'q')
                    break;
            }

        }


        public static void DisableDeviceSleep()
        {
           SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
           preventSleepTimer = new System.Threading.Timer(new TimerCallback(PokeDeviceToKeepAwake), null, 0, timeOutinMS * 1000);
        }

        public static void EnableDeviceSleep()
        {

           preventSleepTimer.Dispose();
           preventSleepTimer = null;

        }

        private static void PokeDeviceToKeepAwake(object extra)
        {

            Counter++;
            try
            {
                   SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
                   IntPtr Handle = FindWindow("SysListView32", "FolderView");

                   if (Handle == IntPtr.Zero)
                   {
                       SetForegroundWindow(Handle);
                       SendKeys.SendWait("%1");
                   }

                   if (Counter > 1)
                       Console.Clear();
            } 
            catch 
            {

            }
        }

        public static void GetSystemTimeOuts()  
        {
            sysTimeouts.BATTERYIDLETIMEOUT = -2;
            sysTimeouts.EXTERNALIDLETIMEOUT = -2;
            sysTimeouts.WAKEUPIDLETIMEOUT = -2;


            if (SystemParametersInfo(SPI_GETBATTERYIDLETIMEOUT, 0, ref batteryIdleTimer, 0) == 1)
                sysTimeouts.BATTERYIDLETIMEOUT = batteryIdleTimer;
            else
                sysTimeouts.BATTERYIDLETIMEOUT = -1;

            if (SystemParametersInfo(SPI_GETEXTERNALIDLETIMEOUT, 0, ref externalIdleTimer, 0) == 1)
                sysTimeouts.EXTERNALIDLETIMEOUT = externalIdleTimer;
            else
                sysTimeouts.EXTERNALIDLETIMEOUT = -1;



            if (SystemParametersInfo(SPI_GETWAKEUPIDLETIMEOUT, 0, ref wakeupIdleTimer, 0) == 1)
                sysTimeouts.WAKEUPIDLETIMEOUT = wakeupIdleTimer;
            else
                sysTimeouts.WAKEUPIDLETIMEOUT = -1;


        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在回应 c# 代码发布时,通常习惯于向作者表示感谢。那恰好是我。我大约两年前在堆栈溢出上发布了这个,我相信。 (10认同)
  • WTF 表示“稍等,我正在计算一些值!” 虚拟循环? (9认同)

KER*_*ERR 5

Mouse Jiggler 可能是一个选项:https ://mousejiggler.codeplex.com/