diff --git a/README.md b/README.md index a55cf90..6e617d8 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,11 @@ Import-Module set-display-resolution.psm1 Usage: ``` powershell -Set-DisplayResolution(1024,768,CDSFlags.SetPrimary); +Set-DisplayResolution -Width 1024 -Height 768 +Set-DisplayResolution -Width 1024 -Height 768 -RefreshRate 60 +Set-DisplayResolution -Width 1024 -Height 768 -RefreshRate 60 -flag "t" -write-host Get-DisplayResolution() +Get-DisplayResolution ``` ## .Net Tool @@ -37,6 +39,8 @@ ChangeDisplaySettings --help -h, --height Required. Height of the screen + -r, --refreshrate Optional. Refresh rate of the screen + -t, --test (Default: false) Test resolution change or actually perform the change. --help Display this help screen. diff --git a/cds/DisplaySettings/CDS.cs b/cds/DisplaySettings/CDS.cs index f885f91..cae1599 100644 --- a/cds/DisplaySettings/CDS.cs +++ b/cds/DisplaySettings/CDS.cs @@ -43,6 +43,7 @@ public struct DEVMODE /// public class Helper { + #nullable enable /// /// Gets the display settings. @@ -70,11 +71,12 @@ public static DEVMODE GetDisplaySettings() /// /// The width. /// The height. + /// The refresh rate. /// The flags. /// - public static string ChangeDisplaySettings(int width, int height, Flags flags) + public static string ChangeDisplaySettings(int width, int height, int refreshrate, Flags flags) { - return ChangeDisplaySettings(width, height, flags, out var _); + return ChangeDisplaySettings(width, height, refreshrate, flags, out var _); } /// @@ -82,10 +84,11 @@ public static string ChangeDisplaySettings(int width, int height, Flags flags) /// /// The width. /// The height. + /// The refresh rate. /// The flags. /// if set to true the change was successful. /// - public static string ChangeDisplaySettings(int width, int height, Flags flags, out bool success) + public static string ChangeDisplaySettings(int width, int height, int refreshrate, Flags flags, out bool success) { // /* Return values for ChangeDisplaySettings */ // #define DISP_CHANGE_SUCCESSFUL 0 @@ -103,7 +106,9 @@ public static string ChangeDisplaySettings(int width, int height, Flags flags, o devMode.dmPelsWidth = width; devMode.dmPelsHeight = height; - + if (refreshrate > 0) { + devMode.dmDisplayFrequency = refreshrate; + } var res = ChangeDisplaySettings(ref devMode, (int)flags); success = false; switch (res) @@ -137,7 +142,7 @@ public static string ChangeDisplaySettings(int width, int height, Flags flags, o private static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags); /// - /// Resolution chgange flags + /// Resolution change flags /// [Flags] public enum Flags:int diff --git a/cds/DisplaySettings/DisplaySettings.psd1 b/cds/DisplaySettings/DisplaySettings.psd1 index 7b77078..dc87e03 100644 --- a/cds/DisplaySettings/DisplaySettings.psd1 +++ b/cds/DisplaySettings/DisplaySettings.psd1 @@ -12,7 +12,7 @@ RootModule = './set-display-resolution.psm1' # Version number of this module. - ModuleVersion = '0.0.2' + ModuleVersion = '0.0.4' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/cds/DisplaySettings/set-display-resolution.psm1 b/cds/DisplaySettings/set-display-resolution.psm1 index 796fb2d..4672811 100644 --- a/cds/DisplaySettings/set-display-resolution.psm1 +++ b/cds/DisplaySettings/set-display-resolution.psm1 @@ -23,11 +23,15 @@ function Set-DisplayResolution { [int] $Height, + [Parameter(Mandatory = $false, Position = 2)] + [int] + $RefreshRate=0, + [CDSFlags] $Flag = [CDSFlags]::Dynamically ) - [cds.Helper]::ChangeDisplaySettings($width, $height, $flag) + [cds.Helper]::ChangeDisplaySettings($width, $height, $refreshrate, $flag) } function Get-DisplayResolution { diff --git a/cds/Program.cs b/cds/Program.cs index 7fe1273..a2c1960 100644 --- a/cds/Program.cs +++ b/cds/Program.cs @@ -1,5 +1,6 @@ using CommandLine; using System; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace cds @@ -14,6 +15,7 @@ static int Main(string[] args) string res = Helper.ChangeDisplaySettings( o.Width, o.Height, + o.RefreshRate, o.Test ? Helper.Flags.CDS_TEST : Helper.Flags.CDS_SET_PRIMARY, @@ -56,6 +58,16 @@ public class Options [Option('h', "height", Required = true, HelpText = "Height of the screen")] public int Height { get; set; } + /// + /// Gets or sets the refresh rate. + /// + /// + /// The refresh rate. + /// + [Range(1, int.MaxValue)] + [Option('r', "refreshrate", Required = false, HelpText = "Refresh rate of the screen", Default = 0)] + public int RefreshRate { get; set; } + /// /// Test resolution change or actually perform. /// diff --git a/cds/cds.csproj b/cds/cds.csproj index d0b1a42..ccb6923 100644 --- a/cds/cds.csproj +++ b/cds/cds.csproj @@ -6,11 +6,11 @@ True Change Display Settings Sets display resolution info on Windows - jiajun.qian, Robert Sirre + jiajun.qian, Robert Sirre, Samuel Zamvil cds.Program enable True - 0.0.3 + 0.0.4 ChangeDisplaySettings True MIT @@ -27,6 +27,7 @@ README.md Screen Resolution;Display Resolution;Resolution + 0.0.4: Added support for setting the refresh rate. 0.0.3: Used more appropriate command 'ChangeDisplaySettings' instead of 'ChangeDisplayResolution', which is better suited to later improvements. 0.0.2: First release as .Net tool en-US diff --git a/cds_legacy/DisplaySettings.Powershell.51.Compatible/CDS.cs b/cds_legacy/DisplaySettings.Powershell.51.Compatible/CDS.cs new file mode 100644 index 0000000..c0ca54e --- /dev/null +++ b/cds_legacy/DisplaySettings.Powershell.51.Compatible/CDS.cs @@ -0,0 +1,115 @@ +namespace cds +{ + using System; + using System.Runtime.InteropServices; + + [StructLayout(LayoutKind.Explicit)] + public struct DEVMODE + { + [FieldOffset(102)] + public short dmLogPixels; + [FieldOffset(104)] + public int dmBitsPerPel; + [FieldOffset(108)] + public int dmPelsWidth; + [FieldOffset(112)] + public int dmPelsHeight; + [FieldOffset(116)] + public int dmDisplayFlags; + [FieldOffset(120)] + public int dmDisplayFrequency; + } + + + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changedisplaysettingsa + public class Helper + { + public static DEVMODE GetDisplaySettings() + { + // #define ENUM_CURRENT_SETTINGS ((DWORD)-1) + // #define ENUM_REGISTRY_SETTINGS ((DWORD)-2) + var devMode = new DEVMODE(); + + // A NULL value specifies the current display device on the computer on which the calling thread is running. + var retCode = EnumDisplaySettings(null, -1, ref devMode); + if (retCode == 0) + { + throw new Exception("can't get resolution from win api"); + } + + return devMode; + } + + public static string ChangeDisplaySettings(int width, int height, int refreshrate, int flags) + { + // /* Return values for ChangeDisplaySettings */ + // #define DISP_CHANGE_SUCCESSFUL 0 + // #define DISP_CHANGE_RESTART 1 + // #define DISP_CHANGE_FAILED -1 + // #define DISP_CHANGE_BADMODE -2 + // #define DISP_CHANGE_NOTUPDATED -3 + // #define DISP_CHANGE_BADFLAGS -4 + // #define DISP_CHANGE_BADPARAM -5 + // #if(_WIN32_WINNT >= 0x0501) + // #define DISP_CHANGE_BADDUALVIEW -6 + // #endif /* _WIN32_WINNT >= 0x0501 */ + + var devMode = GetDisplaySettings(); + + devMode.dmPelsWidth = width; + devMode.dmPelsHeight = height; + + if (refreshrate > 0) { + devMode.dmDisplayFrequency = refreshrate; + } + + var res = ChangeDisplaySettings(ref devMode, flags); + switch (res) + { + case 0: + return "The settings change was successful."; + case 1: + return "The computer must be restarted for the graphics mode to work."; + case -1: + return "The display driver failed the specified graphics mode."; + case -2: + return "The graphics mode is not supported."; + case -3: + return "Unable to write settings to the registry."; + case -4: + return "An invalid set of flags was passed in."; + case -5: + return "An invalid parameter was passed in. This can include an invalid flag or combination of flags."; + case -6: + return "The settings change was unsuccessful because the system is DualView capable."; + default: + return "unknow return code: " + res; + } + } + + [DllImport("user32.dll")] + static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode); + + [DllImport("user32.dll")] + public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags); + + public class Flags + { + // #define CDS_UPDATEREGISTRY 0x00000001 + // #define CDS_TEST 0x00000002 + // #define CDS_FULLSCREEN 0x00000004 + // #define CDS_GLOBAL 0x00000008 + // #define CDS_SET_PRIMARY 0x00000010 + // #define CDS_RESET 0x40000000 + // #define CDS_NORESET 0x10000000 + + public const int CDS_UPDATEREGISTRY = 0x01; + public const int CDS_TEST = 0x02; + public const int CDS_FULLSCREEN = 0x04; + public const int CDS_GLOBAL = 0x08; + public const int CDS_SET_PRIMARY = 0x10; + public const int CDS_RESET = 0x40000000; + public const int CDS_NORESET = 0x10000000; + } + } +} \ No newline at end of file diff --git a/cds_legacy/DisplaySettings.Powershell.51.Compatible/DisplaySettings.psd1 b/cds_legacy/DisplaySettings.Powershell.51.Compatible/DisplaySettings.psd1 new file mode 100644 index 0000000..dc87e03 --- /dev/null +++ b/cds_legacy/DisplaySettings.Powershell.51.Compatible/DisplaySettings.psd1 @@ -0,0 +1,132 @@ +# +# Module manifest for module 'DisplaySettings' +# +# Generated by: jiajun.qian +# +# Generated on: 7/21/2020 +# + +@{ + + # Script module or binary module file associated with this manifest. + RootModule = './set-display-resolution.psm1' + + # Version number of this module. + ModuleVersion = '0.0.4' + + # Supported PSEditions + # CompatiblePSEditions = @() + + # ID used to uniquely identify this module + GUID = 'a0b9c4f9-1d76-48a4-8c2a-a29c65dfb1be' + + # Author of this module + Author = 'jiajun.qian' + + # Company or vendor of this module + # CompanyName = 'Unknown' + + # Copyright statement for this module + # Copyright = '(c) jiajun.qian. All rights reserved.' + + # Description of the functionality provided by this module + Description = 'get/set display resolution info on windows' + + # Minimum version of the PowerShell engine required by this module + # PowerShellVersion = '' + + # Name of the PowerShell host required by this module + # PowerShellHostName = '' + + # Minimum version of the PowerShell host required by this module + # PowerShellHostVersion = '' + + # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. + # DotNetFrameworkVersion = '' + + # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. + # ClrVersion = '' + + # Processor architecture (None, X86, Amd64) required by this module + # ProcessorArchitecture = '' + + # Modules that must be imported into the global environment prior to importing this module + # RequiredModules = @() + + # Assemblies that must be loaded prior to importing this module + # RequiredAssemblies = @() + + # Script files (.ps1) that are run in the caller's environment prior to importing this module. + # ScriptsToProcess = @() + + # Type files (.ps1xml) to be loaded when importing this module + # TypesToProcess = @() + + # Format files (.ps1xml) to be loaded when importing this module + # FormatsToProcess = @() + + # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess + # NestedModules = @() + + # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. + FunctionsToExport = @("Set-DisplayResolution", "Get-DisplayResolution") + + # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. + CmdletsToExport = @() + + # Variables to export from this module + VariablesToExport = '*' + + # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. + AliasesToExport = @() + + # DSC resources to export from this module + # DscResourcesToExport = @() + + # List of all modules packaged with this module + # ModuleList = @() + + # List of all files packaged with this module + FileList = @("./CDS.cs") + + # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. + PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @("ScreenResolution", "DisplayResolution") + + # A URL to the license for this module. + LicenseUri = 'https://github.com/lust4life/display-resolution/blob/master/LICENSE' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/lust4life/display-resolution' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + # Prerelease string of this module + # Prerelease = '' + + # Flag to indicate whether the module requires explicit user acceptance for install/update/save + # RequireLicenseAcceptance = $false + + # External dependent modules of this module + # ExternalModuleDependencies = @() + + } # End of PSData hashtable + + } # End of PrivateData hashtable + + # HelpInfo URI of this module + # HelpInfoURI = '' + + # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. + # DefaultCommandPrefix = '' + +} + diff --git a/cds_legacy/DisplaySettings.Powershell.51.Compatible/set-display-resolution.psm1 b/cds_legacy/DisplaySettings.Powershell.51.Compatible/set-display-resolution.psm1 new file mode 100644 index 0000000..4672811 --- /dev/null +++ b/cds_legacy/DisplaySettings.Powershell.51.Compatible/set-display-resolution.psm1 @@ -0,0 +1,42 @@ +[Flags()] enum CDSFlags { + Dynamically = 0 + UpdateRegistry = 0x01 + Test = 0x02 + FullScreen = 0x04 + Global = 0x08 + SetPrimary = 0x10 + Reset = 0x40000000 + NoReset = 0x10000000 +} + +<# +.LINK +https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changedisplaysettingsa#parameters +#> +function Set-DisplayResolution { + param ( + [Parameter(Mandatory = $true, Position = 0)] + [int] + $Width, + + [Parameter(Mandatory = $true, Position = 1)] + [int] + $Height, + + [Parameter(Mandatory = $false, Position = 2)] + [int] + $RefreshRate=0, + + [CDSFlags] + $Flag = [CDSFlags]::Dynamically + ) + + [cds.Helper]::ChangeDisplaySettings($width, $height, $refreshrate, $flag) +} + +function Get-DisplayResolution { + [cds.Helper]::GetDisplaySettings() +} + +$cds = Get-Content $PSScriptRoot/CDS.cs -Raw +Add-Type -TypeDefinition $cds