Credits:
- U/iRawrz @ Reddit | @iRawrz providing scripts;
- Patrick Gruenauer @ SID-500.COM for the guide on Code Signing
This is a guide on how to automate switching between 60 Hz and 144 Hz according to power mode (Battery v. AC)
Things you will need
- PowerShell and PowerShell ISE (Preinstalled on Windows 10)
- Generate a Code Signing Cert and Sign the .ps1 file
- .ps1 file: This is the power shell command that will detect and automate the switching
- Task Scheduler: We will run two (2) tasks that will detect and switch according to power source
Task Scheduler
- System_Microsoft-Windows-Kernel-Power_105.xml
- Will run PowerShell command to identify if on AC or Battery
- State Check.xml
- Determine Power profile and trigger refresh rate accordingly.
- Open Tash Scheduler and choose IMPORT TASK on the right-hand side
- Import the .xml files into task scheduler and modify directories accordingly
- The Task Scheduler.xml imports will search C:\ for "check-power-state.ps1"
Script
- Download RefreshRate.ps1 and RENAME to check-power-state.ps1
- This step is OPTIONAL, you can place/name it wherever/what ever you like but must match directory in the System_Microsoft-Windows-Kernal-Power_105.xml
- Actions Tab > Edit Actions > Add Arguments > -WindowStyle minimized "C:\check-power-state.ps1"
- There are additional scripts available (eg. RR+AB) - See README
Code Signing Cert
- Follow the guide here on sid-500.com
There were attempts to make a script to switch refresh rates, open or close AB to set OC according to power status and turn on and off SteelSeries RGB. The latter was dropped because of difficulty on personalising settings for each particular device (We could only get it to work on 1 device, the timings on the other never matched).
The RR+AB was abandoned because I found Nvidia Injector easier to use.
Code:Function Set-ScreenResolution { <# .Synopsis Sets the Screen Resolution of the primary monitor .Description Uses Pinvoke and ChangeDisplaySettings Win32API to make the change .Example Set-ScreenResolution -Width 1024 -Height 768 -Freq 60 #> param ( [Parameter(Mandatory=$true, Position = 0)] [int] $Width, [Parameter(Mandatory=$true, Position = 1)] [int] $Height, [Parameter(Mandatory=$true, Position = 2)] [int] $Freq ) $pinvokeCode = @" using System; using System.Runtime.InteropServices; namespace Resolution { [StructLayout(LayoutKind.Sequential)] public struct DEVMODE1 { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmDeviceName; public short dmSpecVersion; public short dmDriverVersion; public short dmSize; public short dmDriverExtra; public int dmFields; public short dmOrientation; public short dmPaperSize; public short dmPaperLength; public short dmPaperWidth; public short dmScale; public short dmCopies; public short dmDefaultSource; public short dmPrintQuality; public short dmColor; public short dmDuplex; public short dmYResolution; public short dmTTOption; public short dmCollate; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmFormName; public short dmLogPixels; public short dmBitsPerPel; public int dmPelsWidth; public int dmPelsHeight; public int dmDisplayFlags; public int dmDisplayFrequency; public int dmICMMethod; public int dmICMIntent; public int dmMediaType; public int dmDitherType; public int dmReserved1; public int dmReserved2; public int dmPanningWidth; public int dmPanningHeight; }; class User_32 { [DllImport("user32.dll")] public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode); [DllImport("user32.dll")] public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags); public const int ENUM_CURRENT_SETTINGS = -1; public const int CDS_UPDATEREGISTRY = 0x01; public const int CDS_TEST = 0x02; public const int DISP_CHANGE_SUCCESSFUL = 0; public const int DISP_CHANGE_RESTART = 1; public const int DISP_CHANGE_FAILED = -1; } public class PrmaryScreenResolution { static public string ChangeResolution(int width, int height, int freq) { DEVMODE1 dm = GetDevMode1(); if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm)) { dm.dmPelsWidth = width; dm.dmPelsHeight = height; dm.dmDisplayFrequency = freq; int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST); if (iRet == User_32.DISP_CHANGE_FAILED) { return "Unable to process your request. Sorry for this inconvenience."; } else { iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY); switch (iRet) { case User_32.DISP_CHANGE_SUCCESSFUL: { return "Success"; } case User_32.DISP_CHANGE_RESTART: { return "You need to reboot for the change to happen.\n If you feel any problems after rebooting your machine\nThen try to change resolution in Safe Mode."; } default: { return "Failed to change the resolution"; } } } } else { return "Failed to change the resolution."; } } private static DEVMODE1 GetDevMode1() { DEVMODE1 dm = new DEVMODE1(); dm.dmDeviceName = new String(new char[32]); dm.dmFormName = new String(new char[32]); dm.dmSize = (short)Marshal.SizeOf(dm); return dm; } } } "@ Add-Type $pinvokeCode -ErrorAction SilentlyContinue [Resolution.PrmaryScreenResolution]::ChangeResolution($width,$height,$freq) } if((Get-WmiObject -Class Win32_Battery -ea 0).BatteryStatus -eq 1) { Set-ScreenResolution -Width 1920 -Height 1080 -Freq 60 } else { Set-ScreenResolution -Width 1920 -Height 1080 -Freq 144 } # SIG # Begin signature block # MIIFcQYJKoZIhvcNAQcCoIIFYjCCBV4CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUulmi5cgiWqXjonaaIA4q/+/D # LFSgggMSMIIDDjCCAfagAwIBAgIQZUSSyB/6wI5MYDhXrRpDcDANBgkqhkiG9w0B # AQsFADAUMRIwEAYDVQQDDAlwZm9ydGVzODgwHhcNMTkwMTE5MDc1OTUzWhcNMjAw # MTE5MDgxOTUzWjAUMRIwEAYDVQQDDAlwZm9ydGVzODgwggEiMA0GCSqGSIb3DQEB # AQUAA4IBDwAwggEKAoIBAQDuGoVJLT8x6Oi9FI/oiGjVhuUFGWcWPom1qzy181Ir # EA1UVFIILfl7RTLeV1Dvfd4nTds0Ku4XEsmotnhNlq1eXm5XEtNDEyp/FS8Vli7+ # MobmMEIyA413stwqYroGF5W9mnr8ATmM6JSc9NRBartEg70YHQ6HWdpBrBXoAeJQ # AKCQEUMXIE/UmxFgOSkWeQV0wx24wPKDkG2X3sRSHmJMgIv4523ojsuEfgwaL4EB # A7xcfdvfjNSQ26tw6qYxYWt5zlep4LcR7H7dXk1LezPQTFOXCdIY9jwG7SFgqoPt # Z3qswbQyPrhXn9aHf2t93UcjJM/2nye9qCHKoBxyn1xlAgMBAAGjXDBaMA4GA1Ud # DwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAUBgNVHREEDTALgglwZm9y # dGVzODgwHQYDVR0OBBYEFC85BuoLzos+GebfI9vfRU4Uoh4cMA0GCSqGSIb3DQEB # CwUAA4IBAQCcJWRrLLB+BYr8IrS5/5+51q6fIbeuew4JKVoTxF8k/X7vg0+n0HXT # wkLBPAf31SU4AkiN4nJlyZbwZ3WON5+HOVNxSZ5cFPw55dYZ/6YMDYNO5w5i+Z8G # YfYALxYJwf/9qXJzcbfrm2N1BxroLarQZ6Njj5QnKay1Th4u+soyXl1Z8PXq09Be # wkNCa8ERpDq7iMVKF5BUx9nOw7FXxJ7wgTCnvloBxSECD8NCKl7om3sRolPybfmu # hrM61QJRIexJxA0ZU+mMZqVBC54/qRbnnBKoOKR4pgDUKUOI8HP2crZxg5uRHIOq # 8N04CN6PSyDRrlw182W3KqUFtvshJKUlMYIByTCCAcUCAQEwKDAUMRIwEAYDVQQD # DAlwZm9ydGVzODgCEGVEksgf+sCOTGA4V60aQ3AwCQYFKw4DAhoFAKB4MBgGCisG # AQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFAgi # TZn8H45eg34m+4vaTx46CLEmMA0GCSqGSIb3DQEBAQUABIIBAAQbjEz5dGtx3nSL # qaKFluK0yB2kpBtoBAfUJQKR4UAi0KPgbUetvXJBaW6YAWkzqDu3oMdV08lm6hAW # bh8gKVOgxF+jpd3dgWhFW7FAcYDcqRgj7XKLiJ19hnvBbSEU81PM6P43+ElQkeOc # gBslvIoKm9C9wgptZXCUMJ+EqgAAFtF/68r5A5ZbjQKgC9nzg5TUYn2SpB0GgjQP # o6raGM5lwmn9mGRqVnkR6bydf/0ckbe4SKTmoxzZtuANmsmfwsGgbon+GVdnrViN # SRU+L2QACq34GuUt9eOd8TZLn/Ut/wl8wSwumLhmGnTxcN5aXD2fKUJjvE5EUlWZ # 7k8+pXI= # SIG # End signature block
-
Nice.
What I did was download Qres from here:
https://www.majorgeeks.com/files/details/qres.html
Unzip and move Qres.exe to C:\Windows\System32\
Don't forget to go into Qres.exe's properties and go to compatibility and tick Run this progran as an administrator.
Next,
Set up 2 tasks in task scheduler, one named 60Hz, one named 144Hz, all with the highest privilege, trigger set to "On a schedule" and set the time to the past.
For the 60Hz task, under the Actions tab, add new program, under Settings add C:\Windows\System32\Qres.exe to Program/Script, add /r:60 to Add arguments (Optional).
For the 144Hz task, under the Actions tab, add new program, under Settings add C:\Windows\System32\Qres.exe to Program/Script, add /r:144 to Add arguments (Optional).
Remember to untick the "Start the task only if the computer is on AC power".
Now go to C:\ and create a folder called Qres, go inside and create 2 batch files, one named 60Hz.bat, one named 144Hz.bat
For 60Hz.bat, put this in the batch file:
schtasks /run /I /TN "\60Hz"
For 144Hz.bat, put this in the batch file:
schtasks /run /I /TN "\144Hz"
This is to call the task you have just set up in the Task Scheduler.
Now go to ThrottleStop, go to Options, under the Run program After Profile Change, look for the Profile linked to AC and Battery, select "After", link AC Profile to C:\Qres\144Hz.bat, link Battery Profile to C:\Qres\60Hz.bat, hit OK.
You are settled.DimitriosMSI, HandsomeGhost and thefatapple like this. -
Is there a significant boost going from 144hz to 60hz while on battery? Current GS75 lasted me about 5-6 hours watching netflix, not sure if dropping to 60hz would help there. Perhaps while browsing or doing light tasks.
custom90gt likes this. -
ryzeki likes this.
-
Also, if you turn vertical sync on then it limits the graphic card to only render the amount of frames that the screen can display. Correct me if i'm wrong, but that would mean less work for the GPU which ultimately means lower power consumption. Am i correct?
-
Kevin@GenTechPC likes this.
-
ALLurGroceries and hackness like this.
Automatically Switch Refresh Rate (AC/Battery) - 60 Hz vs 144 Hz
Discussion in 'MSI' started by xLima, Apr 1, 2019.