以编程方式停用屏幕保护程序
Deactivate a ScreenSaver programmatically
我有一台 ACEPC T6,带有一个通过 HDMI 连接的 7 英寸液晶显示屏和一个 USB 触摸屏。
该系统通过 USB 串行连接到处理器板 link,它读取各种传感器并将数据反馈回 PC。
PC上的程序是用VB.NET2019写的。一切正常,只有一个例外。
我在 activity 10 分钟后使用屏幕保护程序使屏幕黑屏,然后触摸屏幕恢复正常。
我的问题是我有一个 PIR 传感器连接到处理器,它向 PC 发回命令。我的objective就是为了这个模拟屏幕被触摸,恢复显示,即当有人走进房间时,显示returns.
各种办法都试过了,模拟鼠标效果,发送击键,都无济于事
任何帮助将不胜感激。
我应该提到我是 运行 Windows 10 Pro。
您可能无法使用 SendInput() 或其他函数获得肯定结果,因为 special 桌面中的 ScreenSaver 运行s,命名为(猜猜是什么) Screen-saver
.
您需要获取此桌面的句柄才能与其或其 Windows.
主动交互
您可以使用 SystemParametersInfo function, passing SPI_GETSCREENSAVERRUNNING
to determine whether a ScreenSaver is currently active, then call OpenDesktop() 获取桌面的句柄(使用其 name),找到 ScreenSaver Window(ScreenSaver 是标准的可执行文件)和 post 一个 WM_CLOSE
消息来关闭它。
在这里,我使用 EnumDesktopWindows 来查找屏幕保护程序。
(屏幕保护程序 Window 应该是前景 Window 无论如何)。
如果失败,我们可以尝试关闭桌面,调用 CloseDesktop().
这里有一些与屏幕保护程序相关的更有趣的信息:
Handling Screen Savers
如果您有一个通过串行端口或类似的东西接收命令的过程,请验证此过程是否在 运行 线程而不是 UI 线程中,以防您需要本次访问UI。
将此代码添加到过程中:它检查屏幕保护程序是否处于活动状态并尝试将其关闭。
它已经在 Windows 10 (19H2) 和 Windows 7 SP1 中进行了测试。
.Net Framework 4.8 - VB.Net v.15
NOTE: your app is meant to run as a 64bit process. If you have set Prefer 32-bit
in your Project's Build option, you need to
deselect it.
► 假设此过程是 运行 在 UI 线程中。 Me.Activate()
不是严格要求的,只能从 UI 胎面使用。如果您的代码 运行 在不同的线程上,请将其删除。
Protected Sub SomeProcedure()
If NativeMethods.GetScreenSaverActiveState() Then
NativeMethods.TerminateScreenSaver()
Me.Activate()
End If
End Sub
NativeMethods
class 和辅助方法:
Imports System.Runtime.InteropServices
Imports System.Security.Permissions
Friend Class NativeMethods
Public Shared Sub TerminateScreenSaver()
Try
TerminateScreenSaverCore()
Catch wex As Win32Exception
MessageBox.Show(wex.Message)
End Try
End Sub
Public Shared Function GetScreenSaverActiveState() As Boolean
Dim scState As IntPtr = IntPtr.Zero
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0UI, scState, 0UI)
Return scState <> IntPtr.Zero
End Function
<UIPermission(SecurityAction.Demand, Action:=SecurityAction.Demand, Window:=UIPermissionWindow.AllWindows)>
Private Shared Sub TerminateScreenSaverCore()
Call New SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand()
Dim hDesktop As IntPtr = OpenDesktop("Screen-saver", 0, False,
DesktopAccessRights.DESKTOP_READOBJECTS Or DesktopAccessRights.DESKTOP_WRITEOBJECTS)
If hDesktop <> IntPtr.Zero Then
If Not EnumDesktopWindows(hDesktop,
Function(hWnd, lp)
If IsWindowVisible(hWnd) Then CloseWindow(hWnd)
Return True
End Function, IntPtr.Zero) Then
If Not CloseDesktop(hDesktop) Then
CloseWindow(GetForegroundWindow())
End If
End If
End If
End Sub
Private Shared Sub CloseWindow(hWnd As IntPtr)
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)
End Sub
Private Const WM_CLOSE As Integer = &H10
Private Const SPI_GETSCREENSAVERRUNNING As UInteger = &H72
Public Enum DesktopAccessRights As Long
DESKTOP_CREATEMENU = &H4L
DESKTOP_CREATEWINDOW = &H2L
DESKTOP_ENUMERATE = &H40L
DESKTOP_HOOKCONTROL = &H8L
DESKTOP_JOURNALPLAYBACK = &H20L
DESKTOP_JOURNALRECORD = &H10L
DESKTOP_READOBJECTS = &H1L
DESKTOP_SWITCHDESKTOP = &H100L
DESKTOP_WRITEOBJECTS = &H80L
End Enum
Private Delegate Function EnumWindowsProc(hDesktop As IntPtr, lParam As IntPtr) As Boolean
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function OpenDesktop(
lpszDesktop As String,
dwFlags As UInteger,
<[In], MarshalAs(UnmanagedType.Bool)> fInherit As Boolean,
dwDesiredAccess As DesktopAccessRights) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function CloseDesktop(hDesktop As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function EnumDesktopWindows(
hDesktop As IntPtr,
callback As EnumWindowsProc,
lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Public Shared Function GetForegroundWindow() As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function IsWindowVisible(hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function PostMessage(hWnd As IntPtr, msg As UInteger, wParam As IntPtr, lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function SystemParametersInfo(uiAction As UInteger, uiParam As UInteger, ByRef pvParam As IntPtr, fWinIni As UInteger) As Boolean
End Function
End Class
C#版本,以防万一:
using System.Runtime.InteropServices;
using System.Security.Permissions;
internal static class NativeMethods
{
public static void TerminateScreenSaver()
{
try {
TerminateScreenSaverCore();
}
catch(Win32Exception wex){
MessageBox.Show(wex.Message);
}
}
public static bool GetScreenSaverActiveState()
{
var scState = IntPtr.Zero;
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0U, ref scState, 0U);
return scState != IntPtr.Zero;
}
[UIPermission(SecurityAction.Demand, Action = SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]
private static void TerminateScreenSaverCore()
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
IntPtr hDesktop = OpenDesktop("Screen-saver", 0, false,
DesktopAccessRights.DESKTOP_READOBJECTS | DesktopAccessRights.DESKTOP_WRITEOBJECTS);
if (hDesktop != IntPtr.Zero) {
if (!EnumDesktopWindows(hDesktop, (hWnd, lp)=> {
if (IsWindowVisible(hWnd)) CloseWindow(hWnd);
return true;
}, IntPtr.Zero) || !CloseDesktop(hDesktop)) {
CloseWindow(GetForegroundWindow());
}
}
}
private static void CloseWindow(IntPtr hWnd)
{
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
private const uint SPI_GETSCREENSAVERRUNNING = 0x0072;
private const int WM_CLOSE = 0x0010;
public enum DesktopAccessRights : long
{
DESKTOP_CREATEMENU = 0x0004L, // Required to create a menu on the desktop.
DESKTOP_CREATEWINDOW = 0x0002L, // Required to create a window on the desktop.
DESKTOP_ENUMERATE = 0x0040L, // Required for the desktop to be enumerated.
DESKTOP_HOOKCONTROL = 0x0008L, // Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK = 0x0020L, // Required to perform journal playback on a desktop.
DESKTOP_JOURNALRECORD = 0x0010L, // Required to perform journal recording on a desktop.
DESKTOP_READOBJECTS = 0x0001L, // Required to read objects on the desktop.
DESKTOP_SWITCHDESKTOP = 0x0100L, // Required to activate the desktop using the SwitchDesktop function.
DESKTOP_WRITEOBJECTS = 0x0080L // Required to write objects on the desktop.
}
private delegate bool EnumWindowsProc(IntPtr hDesktop, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr OpenDesktop(
string lpszDesktop,
uint dwFlags,
[In, MarshalAs(UnmanagedType.Bool)]bool fInherit,
DesktopAccessRights dwDesiredAccess);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool CloseDesktop(IntPtr hDesktop);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumWindowsProc callback, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref IntPtr pvParam, uint fWinIni);
}
我有一台 ACEPC T6,带有一个通过 HDMI 连接的 7 英寸液晶显示屏和一个 USB 触摸屏。
该系统通过 USB 串行连接到处理器板 link,它读取各种传感器并将数据反馈回 PC。
PC上的程序是用VB.NET2019写的。一切正常,只有一个例外。
我在 activity 10 分钟后使用屏幕保护程序使屏幕黑屏,然后触摸屏幕恢复正常。
我的问题是我有一个 PIR 传感器连接到处理器,它向 PC 发回命令。我的objective就是为了这个模拟屏幕被触摸,恢复显示,即当有人走进房间时,显示returns.
各种办法都试过了,模拟鼠标效果,发送击键,都无济于事
任何帮助将不胜感激。
我应该提到我是 运行 Windows 10 Pro。
您可能无法使用 SendInput() 或其他函数获得肯定结果,因为 special 桌面中的 ScreenSaver 运行s,命名为(猜猜是什么) Screen-saver
.
您需要获取此桌面的句柄才能与其或其 Windows.
您可以使用 SystemParametersInfo function, passing SPI_GETSCREENSAVERRUNNING
to determine whether a ScreenSaver is currently active, then call OpenDesktop() 获取桌面的句柄(使用其 name),找到 ScreenSaver Window(ScreenSaver 是标准的可执行文件)和 post 一个 WM_CLOSE
消息来关闭它。
在这里,我使用 EnumDesktopWindows 来查找屏幕保护程序。
(屏幕保护程序 Window 应该是前景 Window 无论如何)。
如果失败,我们可以尝试关闭桌面,调用 CloseDesktop().
这里有一些与屏幕保护程序相关的更有趣的信息:
Handling Screen Savers
如果您有一个通过串行端口或类似的东西接收命令的过程,请验证此过程是否在 运行 线程而不是 UI 线程中,以防您需要本次访问UI。
将此代码添加到过程中:它检查屏幕保护程序是否处于活动状态并尝试将其关闭。
它已经在 Windows 10 (19H2) 和 Windows 7 SP1 中进行了测试。
.Net Framework 4.8 - VB.Net v.15
NOTE: your app is meant to run as a 64bit process. If you have set
Prefer 32-bit
in your Project's Build option, you need to deselect it.
► 假设此过程是 运行 在 UI 线程中。 Me.Activate()
不是严格要求的,只能从 UI 胎面使用。如果您的代码 运行 在不同的线程上,请将其删除。
Protected Sub SomeProcedure()
If NativeMethods.GetScreenSaverActiveState() Then
NativeMethods.TerminateScreenSaver()
Me.Activate()
End If
End Sub
NativeMethods
class 和辅助方法:
Imports System.Runtime.InteropServices
Imports System.Security.Permissions
Friend Class NativeMethods
Public Shared Sub TerminateScreenSaver()
Try
TerminateScreenSaverCore()
Catch wex As Win32Exception
MessageBox.Show(wex.Message)
End Try
End Sub
Public Shared Function GetScreenSaverActiveState() As Boolean
Dim scState As IntPtr = IntPtr.Zero
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0UI, scState, 0UI)
Return scState <> IntPtr.Zero
End Function
<UIPermission(SecurityAction.Demand, Action:=SecurityAction.Demand, Window:=UIPermissionWindow.AllWindows)>
Private Shared Sub TerminateScreenSaverCore()
Call New SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand()
Dim hDesktop As IntPtr = OpenDesktop("Screen-saver", 0, False,
DesktopAccessRights.DESKTOP_READOBJECTS Or DesktopAccessRights.DESKTOP_WRITEOBJECTS)
If hDesktop <> IntPtr.Zero Then
If Not EnumDesktopWindows(hDesktop,
Function(hWnd, lp)
If IsWindowVisible(hWnd) Then CloseWindow(hWnd)
Return True
End Function, IntPtr.Zero) Then
If Not CloseDesktop(hDesktop) Then
CloseWindow(GetForegroundWindow())
End If
End If
End If
End Sub
Private Shared Sub CloseWindow(hWnd As IntPtr)
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)
End Sub
Private Const WM_CLOSE As Integer = &H10
Private Const SPI_GETSCREENSAVERRUNNING As UInteger = &H72
Public Enum DesktopAccessRights As Long
DESKTOP_CREATEMENU = &H4L
DESKTOP_CREATEWINDOW = &H2L
DESKTOP_ENUMERATE = &H40L
DESKTOP_HOOKCONTROL = &H8L
DESKTOP_JOURNALPLAYBACK = &H20L
DESKTOP_JOURNALRECORD = &H10L
DESKTOP_READOBJECTS = &H1L
DESKTOP_SWITCHDESKTOP = &H100L
DESKTOP_WRITEOBJECTS = &H80L
End Enum
Private Delegate Function EnumWindowsProc(hDesktop As IntPtr, lParam As IntPtr) As Boolean
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function OpenDesktop(
lpszDesktop As String,
dwFlags As UInteger,
<[In], MarshalAs(UnmanagedType.Bool)> fInherit As Boolean,
dwDesiredAccess As DesktopAccessRights) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function CloseDesktop(hDesktop As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function EnumDesktopWindows(
hDesktop As IntPtr,
callback As EnumWindowsProc,
lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Public Shared Function GetForegroundWindow() As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function IsWindowVisible(hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function PostMessage(hWnd As IntPtr, msg As UInteger, wParam As IntPtr, lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function SystemParametersInfo(uiAction As UInteger, uiParam As UInteger, ByRef pvParam As IntPtr, fWinIni As UInteger) As Boolean
End Function
End Class
C#版本,以防万一:
using System.Runtime.InteropServices;
using System.Security.Permissions;
internal static class NativeMethods
{
public static void TerminateScreenSaver()
{
try {
TerminateScreenSaverCore();
}
catch(Win32Exception wex){
MessageBox.Show(wex.Message);
}
}
public static bool GetScreenSaverActiveState()
{
var scState = IntPtr.Zero;
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0U, ref scState, 0U);
return scState != IntPtr.Zero;
}
[UIPermission(SecurityAction.Demand, Action = SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]
private static void TerminateScreenSaverCore()
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
IntPtr hDesktop = OpenDesktop("Screen-saver", 0, false,
DesktopAccessRights.DESKTOP_READOBJECTS | DesktopAccessRights.DESKTOP_WRITEOBJECTS);
if (hDesktop != IntPtr.Zero) {
if (!EnumDesktopWindows(hDesktop, (hWnd, lp)=> {
if (IsWindowVisible(hWnd)) CloseWindow(hWnd);
return true;
}, IntPtr.Zero) || !CloseDesktop(hDesktop)) {
CloseWindow(GetForegroundWindow());
}
}
}
private static void CloseWindow(IntPtr hWnd)
{
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
private const uint SPI_GETSCREENSAVERRUNNING = 0x0072;
private const int WM_CLOSE = 0x0010;
public enum DesktopAccessRights : long
{
DESKTOP_CREATEMENU = 0x0004L, // Required to create a menu on the desktop.
DESKTOP_CREATEWINDOW = 0x0002L, // Required to create a window on the desktop.
DESKTOP_ENUMERATE = 0x0040L, // Required for the desktop to be enumerated.
DESKTOP_HOOKCONTROL = 0x0008L, // Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK = 0x0020L, // Required to perform journal playback on a desktop.
DESKTOP_JOURNALRECORD = 0x0010L, // Required to perform journal recording on a desktop.
DESKTOP_READOBJECTS = 0x0001L, // Required to read objects on the desktop.
DESKTOP_SWITCHDESKTOP = 0x0100L, // Required to activate the desktop using the SwitchDesktop function.
DESKTOP_WRITEOBJECTS = 0x0080L // Required to write objects on the desktop.
}
private delegate bool EnumWindowsProc(IntPtr hDesktop, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr OpenDesktop(
string lpszDesktop,
uint dwFlags,
[In, MarshalAs(UnmanagedType.Bool)]bool fInherit,
DesktopAccessRights dwDesiredAccess);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool CloseDesktop(IntPtr hDesktop);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumWindowsProc callback, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref IntPtr pvParam, uint fWinIni);
}