始める前に、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)
何を達成したいですか?
さて、スクリーンセーバーが表示されないように、マウスカーソルを4分ごとに移動したい(上記のテストでは1秒ごとに)。このコードは、1ピクセル上下するたびにマウスを実際に移動します。問題は、スクリーンセーバー(またはウィンドウのアイドルモード)がまだ表示されていることです。
現在、私はPowerShellを学んでおり、Windowsアーキテクチャの経験はほとんどありません。
誰かが私の間違いを見ていますか?答えをたくさんいただければ幸いです! :D事前に感謝します。
ブログのソリューション PowerShellを使用したデスクトップロックまたはスクリーンセーバーの防止 が機能しています。シェルに単一のピリオドを送信するだけの関連スクリプトは次のとおりです。
param($minutes = 60)
$myshell = New-Object -com "Wscript.Shell"
for ($i = 0; $i -lt $minutes; $i++) {
Start-Sleep -Seconds 60
$myshell.sendkeys(".")
}
およびコメントからの代替、マウスを1ピクセル移動します。
$Pos = [System.Windows.Forms.Cursor]::Position
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) + 1) , $Pos.Y)
$Pos = [System.Windows.Forms.Cursor]::Position
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) - 1) , $Pos.Y)
同じような状況で、ダウンロードを一晩アクティブにしておく必要があり、接続を更新するキーを押す必要がありました。また、マウスの動きが機能しないこともわかりました。ただし、メモ帳とキー送信機能を使用すると、トリックが完了したように見えます。 「。」の代わりにスペースを送信します。 [yes/no]ポップアップがある場合、スペースバーを使用して自動的にデフォルトの応答をクリックするためです。使用するコードは次のとおりです。
param($minutes = 120)
$myShell = New-Object -com "Wscript.Shell"
for ($i = 0; $i -lt $minutes; $i++) {
Start-Sleep -Seconds 30
$myShell.sendkeys(" ")
}
この関数は、指定された120分間(2時間)動作しますが、入力の秒を増減するか、分パラメーターの割り当て値を増減することにより、希望のタイミングに変更できます。
PowerShell ISEまたはPowerShellでスクリプトを実行し、メモ帳を開きます。スペースは、指定された間隔で必要な時間($分)の間入力されます。
幸運を!
これに対するアナログソリューションもあります。設定された間隔で振動する「タイムアウトブロッカー」と呼ばれるAndroidアプリがあり、その上にマウスを置きます。 https://play.google.com/store/apps/ details?id = com.isomerprogramming.application.timeoutblocker&hl = en
I 試行済み マウス移動ソリューションも同様に機能しませんでした。これが私の解決策であり、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
}
Scroll Lockを使用したのは、それがキーボードで最も役に立たないキーの1つだからです。また、時々簡単に点滅するのもいいかもしれません。このソリューションは、ほぼすべての人に有効なはずです。
こちらもご覧ください:
_<# 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
}
_
重要な部分は$Shell.sendkeys("{NUMLOCK}{NUMLOCK}")
です。これは、numlockキーを2回押すことを登録し、入力が入力されたと思わせるようにシェルを欺きます。今日は、私にとってはうまくいかないさまざまなスクリプトを検索した後にこれを書きました。それが誰かを助けることを願っています!
これを試してください:(ソース: 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
}
変数を$ trueまたは$ falseに設定するだけで簡単に有効/無効にできるという通知を追加しました。また、マウスカーソルは右に1ピクセル、左に1ピクセル移動するため、基本的には数回繰り返しても同じ場所に留まります。
# 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)
}
}
スクリーンセーバーを防ぐために、アイドル時間を確認してマウスを揺らすPSスクリプトを作成しました。
動作を制御できる2つのパラメーターがあります。
$checkIntervalInSeconds
:アイドル時間が制限を超えているかどうかを確認する秒単位の間隔
$preventIdleLimitInSeconds
:秒単位のアイドル時間制限。アイドル時間がアイドル時間の制限を超えている場合は、マウスを動かしてスクリーンセーバーを回避します
さあ行こう。スクリプトをpreventIdle.ps1
に保存します。 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
}
次に、Windows PowerShellを開いて実行します
powershell -ExecutionPolicy ByPass -File C:\SCRIPT-DIRECTORY-PATH\preventIdle.ps1