, тогда я хочу использовать переменную s в os.system
blockquote>Использовать функцию
string.format
.os.system("shutdown -s -t 10 -c {}".format(s))
Для тестирования я установил заставку на 1 минуту и потребовал пароль.
Я попытался перехватить SC_SCREENSAVE и вернуть -1 в VB .Net. Как уже отмечалось, он работает, когда нет пароля заставки, но не срабатывает , если активен пароль заставки. (Я попробовал это в Windows XP). Я также помещаю это в событие тика Timer, каждые 1000 миллисекунд:
Static dir As Integer = 4
Cursor.Position = Cursor.Position + New Size(dir, dir)
dir = -dir
Это не работает. Курсор покачивается назад и вперед, и через 1 минуту экранная заставка кратковременно мигает, а затем выключается. Заставка включается только на мгновение, недостаточно долго, чтобы требовать пароль. Но, тем не менее, вспышка ужасна.
Затем я попытался использовать setCursorPos и GetCursorPos для user32.dll. Вы можете посмотреть их на pinvoke. Тот же результат, что и выше.
Затем Я заглянул в код "JiggleMouse", упомянутый в другом месте в этом вопросе. JiggleMouse использует SendInput. SendInput работает! Нет заставки. Я положил вызов SendInput внутри таймера, который срабатывает каждые 50 секунд (чуть меньше минимального тайм-аута заставки 60 секунд). Достаточно переместить мышь на 0,0, никакого реального движения. Это работает . Код для добавления в событие Tick:
Dim i(0) As INPUT
i(0).dwType = INPUT.InputType.INPUT_MOUSE
i(0).mkhi = New MOUSEKEYBDHARDWAREINPUT
i(0).mkhi.mi = New MOUSEINPUT
i(0).mkhi.mi.dx = 0
i(0).mkhi.mi.dy = 0
i(0).mkhi.mi.mouseData = 0
i(0).mkhi.mi.dwFlags = MOUSEINPUT.MouseEventFlags.MOUSEEVENTF_MOVE
i(0).mkhi.mi.time = 0
i(0).mkhi.mi.dwExtraInfo = IntPtr.Zero
SendInput(1, i(0), Marshal.SizeOf(i(0)))
Это взято из pinvoke.com:
Public Declare Function SendInput Lib "user32" (ByVal nInputs As Integer, ByRef pInputs As INPUT, ByVal cbSize As Integer) As Integer
Public Structure INPUT
Enum InputType As Integer
INPUT_MOUSE = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2
End Enum
Dim dwType As InputType
Dim mkhi As MOUSEKEYBDHARDWAREINPUT
End Structure
Public Structure MOUSEINPUT
Enum MouseEventFlags As Integer
MOUSEEVENTF_MOVE = &H1
MOUSEEVENTF_LEFTDOWN = &H2
MOUSEEVENTF_LEFTUP = &H4
MOUSEEVENTF_RIGHTDOWN = &H8
MOUSEEVENTF_RIGHTUP = &H10
MOUSEEVENTF_MIDDLEDOWN = &H20
MOUSEEVENTF_MIDDLEUP = &H40
MOUSEEVENTF_XDOWN = &H80
MOUSEEVENTF_XUP = &H100
MOUSEEVENTF_WHEEL = &H800
MOUSEEVENTF_VIRTUALDESK = &H4000
MOUSEEVENTF_ABSOLUTE = &H8000
End Enum
Dim dx As Integer
Dim dy As Integer
Dim mouseData As Integer
Dim dwFlags As MouseEventFlags
Dim time As Integer
Dim dwExtraInfo As IntPtr
End Structure
Public Structure KEYBDINPUT
Public wVk As Short
Public wScan As Short
Public dwFlags As Integer
Public time As Integer
Public dwExtraInfo As IntPtr
End Structure
Public Structure HARDWAREINPUT
Public uMsg As Integer
Public wParamL As Short
Public wParamH As Short
End Structure
Const KEYEVENTF_EXTENDEDKEY As UInt32 = &H1
Const KEYEVENTF_KEYUP As UInt32 = &H2
Const KEYEVENTF_UNICODE As UInt32 = &H4
Const KEYEVENTF_SCANCODE As UInt32 = &H8
Const XBUTTON1 As UInt32 = &H1
Const XBUTTON2 As UInt32 = &H2
<StructLayout(LayoutKind.Explicit)> Public Structure MOUSEKEYBDHARDWAREINPUT
<FieldOffset(0)> Public mi As MOUSEINPUT
<FieldOffset(0)> Public ki As KEYBDINPUT
<FieldOffset(0)> Public hi As HARDWAREINPUT
End Structure
Тонкое. Официальный способ сообщить Windows, что система не находится в режиме ожидания, - SetThreadExecutionState. Это сбрасывает таймер простоя (или выключает его, если вы передадите ES_CONTINUOUS
). Однако, хотя SetThreadExecutionState сбрасывает таймер простоя, он не останавливает экранную заставку!
Из MSDN :
Windows не запускает заставку, если существует любое из следующих условий:
- Активное приложение не приложение для Windows.
- Имеется окно СВТ.
- Активное приложение получает сообщение WM_SYSCOMMAND с параметром wParam, установленным в значение SC_SCREENSAVE, но оно не передает сообщение в функцию DefWindowProc.
Однако есть предостережение:
Windows Vista и более поздние версии: если защита паролем включена политикой, экранная заставка запускается независимо от того, что приложение делает с SC_SCREENSAVE уведомление.
Это, кажется, применимо, даже если вы используете SetThreadExecutionState с ES_CONTINUOUS.
Итак, если бы не предостережение, ваш выбор был бы:
Последний вариант хорош тем, что работает даже с политикой защиты паролем.
В этом блоге подробно рассказывается о том, что вам нужно делать в C ++.
Фактический фрагмент кода с веб-сайта:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_SCREENSAVE:
return 0;
case SC_MONITORPOWER:
return 0;
}
break;
}
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
Я использую Mouse Jiggler для сброса состояния ожидания. Это обходит групповую политику, которая имеет тенденцию запускать мою заставку (и блокировать машину) в неподходящее время: когда я читаю длинный документ, изучаю сложный фрагмент кода или говорю / слушаю / не набираю постоянно во время встречу.
Поскольку это может немного раздражать, когда мышь прыгает на 1 пиксель по диагонали каждую секунду, я собираюсь использовать AutoHotKey , чтобы написать сценарий, который делает в основном то же самое, но только после настроенной клавиатуры / Тайм-аут простоя мыши и, возможно, использование клавиши Shift (или блокировки прокрутки) вместо движения мыши.
В частности, параметр SPI_SETSCREENSAVEACTIVE
.
Это не работает? Я был удивлен, что не увидел его здесь. Обратите внимание, что SetThreadExecutionState вообще не влияет на хранитель экрана, а только на спящий режим дисплея.