简体   繁体   English

powershell 鼠标移动不会阻止空闲模式

[英]powershell mouse move does not prevent idle mode

Before I start, here is my very first little code I wrote in PowerShell :)在开始之前,这是我在 PowerShell 中编写的第一个小代码 :)

[System.Windows.Forms.Cursor]::Position = `
    New-Object System.Drawing.Point($pos.X, ($pos.Y - 1))
[System.Windows.Forms.Cursor]::Position = `
    New-Object System.Drawing.Point($pos.X, $pos.Y)

What do I want to achieve?我想达到什么目标?

Well, I want to move the mouse cursor every 4 minutes to prevent the screensaver from appearing (every second in the code above for testing).好吧,我想每 4 分钟移动一次鼠标光标以防止屏幕保护程序出现(上面代码中的每一秒进行测试)。 The code does really move the mouse every time one pixel up and then down immediately.每次向上和向下一个像素时,代码确实确实移动了鼠标。 The thing is, the screensaver (or idle mode of windows) is still appearing.问题是,屏幕保护程序(或窗口的空闲模式)仍在出现。

Now, I am learning PowerShell and I have little experience with the Windows architecture.现在,我正在学习 PowerShell,但我对 Windows 架构几乎没有经验。

Does anybody see my mistake?有人看到我的错误吗? I would appreciate an answer a lot!我会很感激一个答案! :D Thanks in advance. :D 在此先感谢。

The solution from the blog Prevent desktop lock or screensaver with PowerShell is working for me.博客中的解决方案使用 PowerShell 防止桌面锁定或屏幕保护程序对我有用。 Here is the relevant script, which simply sends a single period to the shell:这是相关的脚本,它只是向 shell 发送一个句点:

param($minutes = 60)

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

for ($i = 0; $i -lt $minutes; $i++) {
  Start-Sleep -Seconds 60
  $myshell.sendkeys(".")
}

I tried a mouse move solution too, and it likewise didn't work.也尝试了鼠标移动解决方案,它同样没有用。 This was my solution, to quickly toggle Scroll Lock every 4 minutes:这是我的解决方案,每 4 分钟快速切换一次 Scroll Lock:

Clear-Host
Echo "Keep-alive with Scroll Lock..."

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

while ($true)
{
  $WShell.sendkeys("{SCROLLLOCK}")
  Start-Sleep -Milliseconds 100
  $WShell.sendkeys("{SCROLLLOCK}")
  Start-Sleep -Seconds 240
}

I used Scroll Lock because that's one of the most useless keys on the keyboard.我使用了 Scroll Lock,因为这是键盘上最没用的键之一。 Also could be nice to see it briefly blink every now and then.也很高兴看到它时不时地短暂闪烁。 This solution should work for just about everyone, I think.我认为这个解决方案应该适用于几乎所有人。

Some people get success using $WShell.sendkeys("SCROLLLOCK") instead of $WShell.sendkeys("{SCROLLLOCK}")有些人使用 $WShell.sendkeys("SCROLLLOCK") 而不是 $WShell.sendkeys("{SCROLLLOCK}") 获得成功

See also:也可以看看:

There is an analog solution to this also.对此也有一个模拟解决方案。 There's an android app called "Timeout Blocker" that vibrates at a set interval and you put your mouse on it.有一个名为“Timeout Blocker”的安卓应用程序会以设定的时间间隔振动,然后你将鼠标放在它上面。 https://play.google.com/store/apps/details?id=com.isomerprogramming.application.timeoutblocker&hl=en https://play.google.com/store/apps/details?id=com.isomerprogramming.application.timeoutblocker&hl=en

<# Stay Awake by Frank Poth 2019-04-16 #>

(Get-Host).UI.RawUI.WindowTitle = "Stay Awake"

[System.Console]::BufferWidth  = [System.Console]::WindowWidth  = 40
[System.Console]::BufferHeight = [System.Console]::WindowHeight = 10

$shell = New-Object -ComObject WScript.Shell

$start_time = Get-Date -UFormat %s <# Get the date in MS #>
$current_time = $start_time
$elapsed_time = 0

Write-Host "I am awake!"

Start-Sleep -Seconds 5

$count = 0

while($true) {

  $shell.sendkeys("{NUMLOCK}{NUMLOCK}") <# Fake some input! #>

  if ($count -eq 8) {

    $count = 0
    Clear-Host

  }

  if ($count -eq 0) {

    $current_time = Get-Date -UFormat %s
    $elapsed_time = $current_time - $start_time

    Write-Host "I've been awake for "([System.Math]::Round(($elapsed_time / 60), 2))" minutes!"

  } else { Write-Host "Must stay awake..." }

  $count ++

  Start-Sleep -Seconds 2.5

}

The part that matters is $shell.sendkeys("{NUMLOCK}{NUMLOCK}") This registers two presses on the numlock key and fools the shell into thinking input was entered.重要的部分是$shell.sendkeys("{NUMLOCK}{NUMLOCK}")这会记录两次按下 numlock 键并欺骗 shell 以为输入已输入。 I wrote this today after searching through various scripts that didn't work for me.在搜索了对我不起作用的各种脚本后,我今天写了这篇文章。 Hope it helps someone!希望它可以帮助某人!

I had a similar situation where a download needed to stay active overnight and required a key press that refreshed my connection.我也遇到过类似的情况,下载需要在一夜之间保持活跃,并且需要按键来刷新我的连接。 I also found that the mouse move does not work.我还发现鼠标移动不起作用。 However, using notepad and a send key function appears to have done the trick.但是,使用记事本和发送键功能似乎可以解决问题。 I send a space instead of a "."我发送一个空格而不是一个“。” because if there is a [yes/no] popup, it will automatically click the default response using the spacebar.因为如果有一个 [yes/no] 弹出窗口,它会使用空格键自动单击默认响应。 Here is the code used.这是使用的代码。

param($minutes = 120)

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

for ($i = 0; $i -lt $minutes; $i++) {
  Start-Sleep -Seconds 30
  $myShell.sendkeys(" ")
}

This function will work for the designated 120 minutes (2 Hours), but can be modified for the timing desired by increasing or decreasing the seconds of the input, or increasing or decreasing the assigned value of the minutes parameter.此功能将在指定的 120 分钟(2 小时)内工作,但可以通过增加或减少输入的秒数或增加或减少分钟参数的指定值来修改所需的时间。

Just run the script in powershell ISE, or powershell, and open notepad.只需在 powershell ISE 或 powershell 中运行脚本,然后打开记事本。 A space will be input at the specified interval for the desired length of time ($minutes).将在指定的时间间隔输入一个空格,持续所需的时间长度($ 分钟)。

Good Luck!祝你好运!

Try this: (source: http://just-another-blog.net/programming/powershell-and-the-net-framework/ )试试这个:(来源:http: //just-another-blog.net/programming/powershell-and-the-net-framework/

Add-Type -AssemblyName System.Windows.Forms 

$position = [System.Windows.Forms.Cursor]::Position  
$position.X++  
[System.Windows.Forms.Cursor]::Position = $position 

    while(1) {  
    $position = [System.Windows.Forms.Cursor]::Position  
    $position.X++  
    [System.Windows.Forms.Cursor]::Position = $position  

    $time = Get-Date;  
    $shorterTimeString = $time.ToString("HH:mm:ss");  

    Write-Host $shorterTimeString "Mouse pointer has been moved 1 pixel to the right"  
    #Set your duration between each mouse move
    Start-Sleep -Seconds 150  
    }  

I created a PS script to check idle time and jiggle the mouse to prevent the screensaver.我创建了一个 PS 脚本来检查空闲时间并摇动鼠标以防止屏幕保护程序。

There are two parameters you can control how it works.有两个参数可以控制它的工作方式。

$checkIntervalInSeconds : the interval in seconds to check if the idle time exceeds the limit $checkIntervalInSeconds :检查空闲时间是否超过限制的间隔(以秒为单位)

$preventIdleLimitInSeconds : the idle time limit in seconds. $preventIdleLimitInSeconds :以秒为单位的空闲时间限制。 If the idle time exceeds the idle time limit, jiggle the mouse to prevent the screensaver如果空闲时间超过空闲时间限制,请摇动鼠标以阻止屏幕保护程序

Here we go.开始了。 Save the script in preventIdle.ps1 .将脚本保存在preventIdle.ps1中。 For preventing the 4-min screensaver, I set $checkIntervalInSeconds = 30 and $preventIdleLimitInSeconds = 180 .为了防止 4 分钟屏幕保护程序,我设置$checkIntervalInSeconds = 30$preventIdleLimitInSeconds = 180

Add-Type @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PInvoke.Win32 {

    public static class UserInput {

        [DllImport("user32.dll", SetLastError=false)]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        [StructLayout(LayoutKind.Sequential)]
        private struct LASTINPUTINFO {
            public uint cbSize;
            public int dwTime;
        }

        public static DateTime LastInput {
            get {
                DateTime bootTime = DateTime.UtcNow.AddMilliseconds(-Environment.TickCount);
                DateTime lastInput = bootTime.AddMilliseconds(LastInputTicks);
                return lastInput;
            }
        }

        public static TimeSpan IdleTime {
            get {
                return DateTime.UtcNow.Subtract(LastInput);
            }
        }

        public static double IdleSeconds {
            get {
                return IdleTime.TotalSeconds;
            }
        }

        public static int LastInputTicks {
            get {
                LASTINPUTINFO lii = new LASTINPUTINFO();
                lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
                GetLastInputInfo(ref lii);
                return lii.dwTime;
            }
        }
    }
}
'@

Add-Type @'
using System;
using System.Runtime.InteropServices;

namespace MouseMover
{
    public class MouseSimulator
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetCursorPos(out POINT lpPoint);

        [StructLayout(LayoutKind.Sequential)]
        struct INPUT
        {
            public SendInputEventType type;
            public MouseKeybdhardwareInputUnion mkhi;
        }
        [StructLayout(LayoutKind.Explicit)]
        struct MouseKeybdhardwareInputUnion
        {
            [FieldOffset(0)]
            public MouseInputData mi;

            [FieldOffset(0)]
            public KEYBDINPUT ki;

            [FieldOffset(0)]
            public HARDWAREINPUT hi;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct KEYBDINPUT
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct HARDWAREINPUT
        {
            public int uMsg;
            public short wParamL;
            public short wParamH;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
        }
        struct MouseInputData
        {
            public int dx;
            public int dy;
            public uint mouseData;
            public MouseEventFlags dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        [Flags]
        enum MouseEventFlags : uint
        {
            MOUSEEVENTF_MOVE = 0x0001
        }
        enum SendInputEventType : int
        {
            InputMouse
        }
        public static void MoveMouseBy(int x, int y) {
            INPUT mouseInput = new INPUT();
            mouseInput.type = SendInputEventType.InputMouse;
            mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE;
            mouseInput.mkhi.mi.dx = x;
            mouseInput.mkhi.mi.dy = y;
            SendInput(1, ref mouseInput, Marshal.SizeOf(mouseInput));
        }
    }
}
'@

$checkIntervalInSeconds = 30
$preventIdleLimitInSeconds = 180

while($True) {
    if (([PInvoke.Win32.UserInput]::IdleSeconds -ge $preventIdleLimitInSeconds)) {
        [MouseMover.MouseSimulator]::MoveMouseBy(10,0)
        [MouseMover.MouseSimulator]::MoveMouseBy(-10,0)
    }
    Start-Sleep -Seconds $checkIntervalInSeconds
}

Then, open Windows PowerShell and run然后,打开 Windows PowerShell 并运行

powershell -ExecutionPolicy ByPass -File C:\SCRIPT-DIRECTORY-PATH\preventIdle.ps1

I've added a notification that you can easily enable / disable just setting its variable to $true or $false.我添加了一条通知,您只需将其变量设置为 $true 或 $false 即可轻松启用/禁用。 Also the mouse cursor moves 1 px right and then 1 px left so it basically stays in the same place even after several iterations.此外,鼠标光标向右移动 1 px,然后向左移动 1 px,因此即使经过多次迭代,它也基本上保持在同一个位置。

# Lines needed for the notification
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
Add-Type -AssemblyName System.Windows.Forms 
$isNotificationOn = $true

$secondsBetweenMouseMoves = 6
$Pos = [System.Windows.Forms.Cursor]::Position
$PosDelta = 1
$logFilename = "previousMouseMoverAction.txt"
$errorLogFilename = "mouseMoverLog.txt"

if (!(Test-Path "$PSScriptRoot\$logFilename")) {
   New-Item -path $PSScriptRoot -name $logFilename -type "file" -value "right"
   Write-Host "Warning: previousMouseMoverAction.txt missing, created a new one."
}

$previousPositionChangeAction = Get-Content -Path $PSScriptRoot\$logFilename

if ($previousPositionChangeAction -eq "left") {
    $PosDelta = 1
    Set-Content -Path $PSScriptRoot\$logFilename -Value 'right'
} else {
    $PosDelta = -1
    Set-Content -Path $PSScriptRoot\$logFilename -Value 'left'
}

for ($i = 0; $i -lt $secondsBetweenMouseMoves; $i++) {
    [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) + $PosDelta) , $Pos.Y)
    if ($isNotificationOn) {
        # Sending a notification to the user
        $global:balloon = New-Object System.Windows.Forms.NotifyIcon
        $path = (Get-Process -id $pid).Path
        $balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path) 
        $balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Warning 
        $balloon.BalloonTipText = 'I have just moved your cheese...'
        $balloon.BalloonTipTitle = "Attention, $Env:USERNAME" 
        $balloon.Visible = $true 
        $balloon.ShowBalloonTip(3000)
    }
}

Below PowerShell script toggles scroll lock every minute, prints out current time, and clears console every 5 minutes (in case you want to keep the script going indefinitely).下面的 PowerShell 脚本每分钟切换一次滚动锁定,打印当前时间,并每 5 分钟清除一次控制台(以防您想无限期地保持脚本运行)。

$WShell = New-Object -com "Wscript.Shell"
cls

$count = 0
while ($true)
{
  $count = $count + 1
  if($count -eq 5) {
    cls
    $count=0
  }
  $WShell.sendkeys("{SCROLLLOCK}")
  Start-Sleep -Milliseconds 100
  Write-Output "Toggle Scroll at $(Get-Date -Format u)"
  $WShell.sendkeys("{SCROLLLOCK}")
  Start-Sleep -Seconds 60
}

I simply run alt+tab after every random second between 5 to 10 sec Because new tools even track pattern of any key press.我只是在 5 到 10 秒之间的每个随机秒后运行 alt+tab,因为新工具甚至可以跟踪任何按键的模式。

Add it inside a loop and you are done.将它添加到一个循环中,你就完成了。

[System.Windows.Forms.SendKeys]::SendWait("%{TAB}")

$ran=(Get-Random -Minimum 5 -Maximum 10)
echo "sleep for $ran sec"
sleep $ran 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM