我有一台运行 Windows 10 的 HP Spectre x360 13 笔记本电脑。显示器的默认分辨率为 3480 x 2160,缩放比例为 300%。
我需要将单个应用程序的分辨率更改为 1920 x 1080,缩放比例为 125%。当我使用完该应用程序后,我需要将其改回原样。
当然,我可以手动完成此操作;右键单击桌面,更改设置,启动应用程序,关闭应用程序,右键单击,更改设置......
但我觉得我应该能够编写一个批处理脚本来执行此操作。我对这类事情的能力有限,在这种情况下,我不知道在脚本中包含哪些命令。有人能帮忙吗?
答案1
这是 Windows 10 64 位 Visual Basic 脚本和 Powershell 5 脚本。
屏幕捕捉VBscript 的实际操作。(1.1MB mp4)
Windows 10 64 位Visual Basic 脚本使用发送键更改显示比例和分辨率,打开应用程序,并在应用程序关闭时恢复比例和分辨率。无需重启。
将代码复制粘贴到新的文本文档中。将其保存为.vbs 文件(即 ChangeDisplay.vbs),编辑并运行。
更改缩放比例和分辨率会弄乱您的桌面图标布局。下载、安装并学习如何使用命令行桌面图标布局备份,例如:
DesktopOK v4.24。从命令行保存和恢复桌面图标布局。将 DesktopCmd64.exe 放在你的小路,将其添加到您的 PATH,或者将其放在您的 Windows 文件夹中。
和
DesktopRestore v1.6.3.031。从命令行保存和恢复桌面图标布局。64 位命令行版本在 Windows 10 64 位中偶尔会失败?将 DesktopRestore64.exe 放在您的 PATH 中的某个位置,将其添加到您的小路,或者直接把它放在你的 windows 文件夹中。
编辑脚本:
改变“把图片名称您的应用程序”、“更改以下内容 {UP} / {DOWN}?”,以及更改启动您的应用程序的命令。
打开显示设置窗口资源管理器 ms-settings:显示并找出您需要的 TAB 和 UP 或 DOWN 按键组合,以获得您想要的设置,然后“更改以下内容 {UP} / {DOWN}?”如果您以另一种方式打开显示设置窗口,您的 TAB/S 数量可能会有所不同。
Wscript.Sleep 的计时可能很棘手。减少或增加睡眠时间都可能破坏脚本。在磁盘使用率高的时候运行脚本可能会导致脚本失败。您可以尝试多种不同的方法:
但我坚持只使用 Wscript.Sleep,因为它对我有用。请参阅周围的评论Wscript.Sleep 2000
。
使用 Visual Basic 脚本开始大部分原生操作
' WINDOWS 10 64-BIT VISUAL BASIC SCRIPT TO CHANGE DISPLAY SCALE AND RESOLUTION, OPEN APP, AND RESTORE SCALE AND RESOLUTION WHEN APP CLOSES.
' https://superuser.com/questions/1489592/windows-10-batch-script-to-change-display-settings-for-specific-application
' All native except DesktopOK and DesktopRestore. Does not require restart.
' Changing the scaling and resolution will mess up your desktop icon layout. Download, install, and learn how to use a command line desktop icon layout backup like:
' DesktopOK v4.24. Save and restore desktop icon layout from the command line. https://www.softwareok.com/?Download=DesktopOK
' Put DesktopCmd64.exe somewhere in your PATH.
' and
' DesktopRestore v1.6.3.031. Save and restore desktop icon layout from the command line. 64-bit command line version fails occasionally in Windows 10 64-bit? http://www.midiox.com/desktoprestore.htm
' Put DesktopRestore64.exe somewhere in your PATH.
' Change "PUT THE IMAGENAME OF YOUR APP HERE", "CHANGE THE FOLLOWING {UP} / {DOWN}?", AND CHANGE THE COMMAND THAT STARTS YOUR APP.
' Open the display settings window (explorer ms-settings:display) and figure out what combination of TAB AND UP OR DOWN keystrokes you need to get the setting you want and "CHANGE THE FOLLOWING {UP} / {DOWN}?"
' If you open the display settings window another way your number of TAB/S might be different.
' BEGIN CHANGE TO 1920 X 1080 W/ 100% SCALING
option explicit
DIM strComputer,WshShell,HostName,Ping,FileName,Return
SET WshShell = WScript.CreateObject("WScript.Shell")
' BEGIN BACKUP DESKTOP ICON LAYOUT
FileName = "%USERPROFILE%\Desktop\DesktopIconLayout" & timer & ".dok"
WshShell.Run "desktoprestore64.exe /save /silent " & FileName, 0, False
FileName = "%USERPROFILE%\Desktop\DesktopIconLayout" & timer & ".dtr"
WshShell.Run "DesktopCmd64.exe save /f " & FileName, 0, False
' END BACKUP DESKTOP ICON LAYOUT
' BEGIN KILL APP
' PUT THE IMAGENAME OF YOUR APP HERE
' I.E. replace iexplore.exe
FileName = "iexplore.exe"
WshShell.Run "taskkill /im " & FileName & " /f", 0, False
' END KILL APP
' BEGIN CLOSE AND OPEN DISPLAY SETTINGS WINDOW
strComputer = "." ' local computer
FileName = "SystemSettings.exe"
if isProcessRunning(strComputer,FileName) then
WshShell.Run "taskkill /im " & FileName & " /f", 0, False
WshShell.Run "explorer ms-settings:display"
else
WshShell.Run "explorer ms-settings:display"
end if
Set strComputer = Nothing
Set FileName = Nothing
' END CLOSE AND OPEN DISPLAY SETTINGS WINDOW
' You have to give the display settings window enough time to load.
' There are a lot of different things you can try.
' If I change the following Wscript.Sleep to 4 seconds and leave the later one at 2 seconds the script fails
' even though 2 seconds works.
Wscript.Sleep 2000
' BEGIN CHANGE SCALE
' CHANGE THE FOLLOWING {UP} / {DOWN}?
WshShell.SendKeys "{TAB 2}{DOWN}"
' END CHANGE SCALE
Wscript.Sleep 750
' BEGIN CHANGE RESOLUTION
' CHANGE THE FOLLOWING {UP} / {DOWN}?
WshShell.SendKeys "{TAB 2}{DOWN}"
' END CHANGE RESOLUTION
Wscript.Sleep 750
' BEGIN ACCEPT RESOLUTION CHANGE
WshShell.SendKeys "{TAB}"
Wscript.Sleep 750
WshShell.SendKeys "{ENTER}"
' END ACCEPT RESOLUTION CHANGE
Wscript.Sleep 750
' BEGIN Return TO THE "FIND A SETTING" BOX. IMPROVES RELIABILITY.
' BEGIN PROCEDURE CHANGES IF PC IS ON/OFFLINE
' Dim HostName
' HostName = "8.8.8.8"
' Ping = WshShell.Run("Ping -n 1 " & HostName, 0, True)
' Select Case Ping
' Case 0
' WshShell.SendKeys "{TAB}" ' Online
' Case 1
' WshShell.SendKeys "{TAB}" ' Offline
' End Select
' END PROCEDURE CHANGES IF PC IS ON/OFFLINE
WshShell.SendKeys "{TAB}"
' END Return TO THE "FIND A SETTING" BOX. IMPROVES RELIABILITY.
Wscript.Sleep 750
' CLOSE DISPLAY SETTINGS WINDOW
WshShell.SendKeys "%{F4}"
' END CHANGE TO 1920 X 1080 W/ 100% SCALING
' BEGIN OPEN APP. SCRIPT STOPS UNTIL APP CLOSED.
' CHANGE THE COMMAND THAT STARTS YOUR APP.
' Return = WshShell.Run("""C:\Program Files (x86)\Jasc Software Inc\Paint Shop Pro 7\psp.exe""", 1, true)
Return = WshShell.Run("iexplore.exe", 1, true)
' WScript.Echo "HI"
' END OPEN APP. SCRIPT STOPS UNTIL APP CLOSED.
' BEGIN CHANGE TO 3840 X 2160 W/ 300% SCALING
' BEGIN OPEN DISPLAY SETTINGS WINDOW
WshShell.Run "explorer ms-settings:display"
' END OPEN DISPLAY SETTINGS WINDOW
' You have to give the display settings window enough time to load.
Wscript.Sleep 2000
' BEGIN CHANGE SCALE
' CHANGE THE FOLLOWING {UP} / {DOWN}?
WshShell.SendKeys "{TAB 2}{UP}"
' END CHANGE SCALE
Wscript.Sleep 750
' BEGIN CHANGE RESOLUTION
' CHANGE THE FOLLOWING {UP} / {DOWN}?
WshShell.SendKeys "{TAB 2}{UP}"
Wscript.Sleep 750
' END CHANGE RESOLUTION
' BEGIN ACCEPT RESOLUTION CHANGE
WshShell.SendKeys "{TAB}"
Wscript.Sleep 750
WshShell.SendKeys "{ENTER}"
' END ACCEPT RESOLUTION CHANGE
Wscript.Sleep 750
' BEGIN Return TO THE "FIND A SETTING" BOX. IMPROVES RELIABILITY.
WshShell.SendKeys "{TAB}"
Wscript.Sleep 750
' END Return TO THE "FIND A SETTING" BOX. IMPROVES RELIABILITY.
' CLOSE DISPLAY SETTINGS WINDOW
WshShell.SendKeys "%{F4}"
' END CHANGE TO 3840 X 2160 W/ 300% SCALING
' EXIT THE SCRIPT
WScript.Quit
' Function to check if a process is running
function isProcessRunning(byval strComputer,byval FileNameName)
Dim objWMIService, strWMIQuery
strWMIQuery = "Select * from Win32_Process where name like '" & FileNameName & "'"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
if objWMIService.ExecQuery(strWMIQuery).Count > 0 then
isProcessRunning = true
else
isProcessRunning = false
end if
end function
根据我上面的评论,您也可以使用这个 POWERSHELL 脚本。
WINDOWS 10 64 位 powershell 5 脚本使用 sendkeys 更改显示比例和分辨率、打开应用程序并在应用程序关闭时恢复比例和分辨率。
屏幕捕捉powershell 脚本实际运行情况 (1.22MB mp4)
创建脚本的快捷方式:
C:\Windows\System32\cmd.exe /c start /min "" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -Command "& "%userprofile%\desktop\1.ps1""
或者
C:\Windows\System32\cmd.exe /c start /min "" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -ExecutionPolicy Bypass -Command "& "%userprofile%\desktop\1.ps1""
# WINDOWS 10 64-BIT POWERSHELL 5 SCRIPT USING SENDKEYS TO CHANGE DISPLAY SCALE AND RESOLUTION, OPEN APP, AND RESTORE SCALE AND RESOLUTION WHEN APP CLOSES.
# https://superuser.com/questions/1489592/windows-10-batch-script-to-change-display-settings-for-specific-application
# find process name with get-process
# if the app and / or settings windows are open the script will fail.
stop-process -name iexplore
stop-process -name systemsettings
# save the desktop icon layout
$a = (Get-Date).ToString('mmss')
start-process "$env:windir\DesktopRestore64.exe" "/save /silent $env:userprofile\Desktop\DesktopIconLayout$a.dok"
start-process "$env:windir\DesktopCmd64.exe" "save /f $env:userprofile\Desktop\DesktopIconLayout$a.dtr"
# the settings window
$WshShell = New-Object -com Wscript.Shell
explorer ms-settings:display
Start-Sleep -s 2
$WshShell.SendKeys("{TAB}"*2)
$WshShell.SendKeys("{DOWN}")
Start-Sleep -s 1
$WshShell.SendKeys("{TAB}"*2)
$WshShell.SendKeys("{DOWN}")
Start-Sleep -s .750
$WshShell.SendKeys("{TAB}{ENTER}{TAB}")
Start-Sleep -s .750
$WshShell.SendKeys("%{F4}")
# Start-Process can be tricky. Run "gci Env:" On my machine:
# $env:ProgramFiles = c:\program files (x86)
# $env:ProgramW6432 = c:\program files
# Start-Process "$env:ProgramFiles\Internet Explorer\iexplore.exe" -NoNewWindow -Wait
Start-Process "$env:ProgramW6432\Internet Explorer\iexplore.exe" -NoNewWindow -Wait
# the settings window
explorer ms-settings:display
Start-Sleep -s 2
$WshShell.SendKeys("{TAB}"*2)
$WshShell.SendKeys("{UP}")
Start-Sleep -s 2
$WshShell.SendKeys("{TAB}"*2)
$WshShell.SendKeys("{UP}")
Start-Sleep -s .750
$WshShell.SendKeys("{TAB}{ENTER}{TAB}")
Start-Sleep -s .750
$WshShell.SendKeys("%{F4}")
exit
答案2
我也需要更改显示设置。我使用这个作为开始:https://www.codeproject.com/Articles/36664/Changing-Display-Settings-Programmatically(注意:您下载的是将源安装到您的计算机上的 MSI,这很奇怪)。
我更改了 MainForm.cs 以让应用程序在启动时更改设置(FHD60)并在关闭时恢复设置(4K60):
private readonly DisplaySettings _originalSettings;
public MainForm()
{
....
_originalSettings = DisplayManager.GetCurrentSettings();
}
private DisplaySettings disp_1920_1080_60Hz;
private void MainForm_Load(object sender, EventArgs e)
{
....
DisplayManager.SetDisplaySettings(disp_1920_1080_60Hz);
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
DisplayManager.SetDisplaySettings(_originalSettings);
return;
}
protected void ListAllModes()
{
....
while (enumerator.MoveNext())
{
....
//you can get the detail setting for your purpose from the list of display modes in the UI
if (set.Width == 1920 && set.Height == 1080 && set.BitCount == 32 && set.Frequency == 60)
disp_1920_1080_60Hz = set;
}
....
}
@somebadhat 提供了一个可以修改缩放设置的链接,这是@Sahil Singh 在这个问题中的回答https://stackoverflow.com/questions/35233182/how-can-i-change-windows-10-display-scaling-programmatically-using-c-sharp/58568499#58568499,代码位于:https://github.com/lihas/windows-DPI-scaling-sample
(注:已更新:下面的代码不处理多显示器,你可以在上面的问题中查看我的答案,了解执行此操作的 C# 程序)
再次修改代码,以便在启动时更改设置并在关闭时恢复,
在 DPIScalingMFCAppDlg.h 中:
....
afx_msg void OnBnClickedButton1();
afx_msg void OnClose();//add
void autoSet(int sel);//add
....
在 DPIScalingMFCAppDlg.cpp 中:
BEGIN_MESSAGE_MAP(CDPIScalingMFCAppDlg, CDialogEx)
....
ON_WM_CLOSE() //add
END_MESSAGE_MAP()
//add
static int yoursel;
static int yourseldpi = 150;//this is the DPI/scaling that you want
//set to a number in the list in the UI
static int defaultsel=-1;
//addend
BOOL CDPIScalingMFCAppDlg::OnInitDialog()
{
....
Refresh();
autoSet(yoursel);//add
Refresh();//add
return TRUE; // return TRUE unless you set the focus to a control
}
//add
void CDPIScalingMFCAppDlg::autoSet(int sel)
{
auto dpiToSet = m_dpiList.GetItemData(sel);
int cacheIndex = m_displayList.GetItemData(0);
auto itr = m_displayDataCache.find(cacheIndex);
auto res = DpiHelper::SetDPIScaling(itr->second.m_adapterId, itr->second.m_sourceID, dpiToSet);
}
//addend
bool CDPIScalingMFCAppDlg::FillDisplayInfo(LUID adapterID, int sourceID)
{
....
m_dpiList.SetItemData(iIndex, dpi);
if (dpi == yourseldpi) yoursel = iIndex; //add
....
m_dpiList.SetCurSel(currentIndex);
if (defaultsel ==-1) defaultsel = currentIndex;//add
....
}
//add
void CDPIScalingMFCAppDlg::OnClose()
{
autoSet(defaultsel);
CDialogEx::OnClose();
}
//addend
然后你可以写一个批处理文件,先运行上述两个程序,然后运行你的应用程序,实现“一键操作”。虽然复杂,但完全 DIY 且干净。
以下是完整的 MainForm.cs,供参考,它与 codeproject 中的代码基本相同:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
namespace Magic.Samples.DisplaySettings
{
/// <summary>
/// The start-up form
/// </summary>
public partial class MainForm : Form
{
/// <summary>
/// Encapsulates the display settings. Initialized by the constructor of the form.
/// </summary>
private readonly DisplaySettings _originalSettings;
/// <summary>
/// Initializes a new instance of MainForm.
/// </summary>
public MainForm()
{
InitializeComponent();
this.Text = Application.ProductName;
_originalSettings = DisplayManager.GetCurrentSettings();
}
private void MainForm_Load(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
GetCurrentSettings();
ListAllModes();
this.Cursor = Cursors.Default;
//ListAllModes has initialized disp_1920_1080_60Hz
DisplayManager.SetDisplaySettings(disp_1920_1080_60Hz);
}
/// <summary>
/// Loads current display settings and refreshes the current settings labels.
/// </summary>
protected void GetCurrentSettings()
{
DisplaySettings set = DisplayManager.GetCurrentSettings();
this.widthLabel.Text = set.Width.ToString(CultureInfo.InvariantCulture);
this.heightLabel.Text = set.Height.ToString(CultureInfo.InvariantCulture);
this.orientationLabel.Text = ((int)set.Orientation * 90).ToString(CultureInfo.InvariantCulture);
this.bitsLabel.Text = set.BitCount.ToString(CultureInfo.InvariantCulture);
this.freqLabel.Text = set.Frequency.ToString(CultureInfo.InvariantCulture);
}
private DisplaySettings disp_1920_1080_60Hz;
/// <summary>
/// Loads all supported display modes and lists them in the modes list view.
/// </summary>
protected void ListAllModes()
{
this.modesListView.BeginUpdate();
this.modesListView.Items.Clear();
IEnumerator<DisplaySettings> enumerator = DisplayManager.GetModesEnumerator();
DisplaySettings set;
ListViewItem itm;
while (enumerator.MoveNext())
{
set = enumerator.Current;
itm = new ListViewItem(set.Index.ToString(CultureInfo.InvariantCulture));
itm.SubItems.Add(set.Width.ToString(CultureInfo.InvariantCulture));
itm.SubItems.Add(set.Height.ToString(CultureInfo.InvariantCulture));
itm.SubItems.Add(((int)set.Orientation * 90).ToString(CultureInfo.InvariantCulture));
itm.SubItems.Add(set.BitCount.ToString(CultureInfo.InvariantCulture));
itm.SubItems.Add(set.Frequency.ToString(CultureInfo.InvariantCulture));
itm.Tag = set;
this.modesListView.Items.Add(itm);
if (set.Width == 1920 && set.Height == 1080 && set.BitCount == 32 && set.Frequency == 60)
disp_1920_1080_60Hz = set;
}
this.modesListView.EndUpdate();
}
private void rotateClockwiseButton_Click(object sender, EventArgs e)
{
if (MessageBox.Show(this, Properties.Resources.Msg_Disp_Change_Rotate, Application.ProductName,
MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, (MessageBoxOptions)0) == DialogResult.Yes)
{
DisplayManager.RotateScreen(true);
GetCurrentSettings();
ListAllModes();
}
}
private void rotateAntiClockwiseButton_Click(object sender, EventArgs e)
{
if (MessageBox.Show(this, Properties.Resources.Msg_Disp_Change_Rotate, Application.ProductName,
MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, (MessageBoxOptions)0) == DialogResult.Yes)
{
DisplayManager.RotateScreen(false);
GetCurrentSettings();
ListAllModes();
}
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
DisplayManager.SetDisplaySettings(_originalSettings);
return;
DialogResult result = MessageBox.Show(this, string.Format(CultureInfo.CurrentCulture,
Properties.Resources.Msg_Disp_Change_Original, _originalSettings),
Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0);
if (result == DialogResult.Cancel)
e.Cancel = true;
else if (result == DialogResult.Yes)
DisplayManager.SetDisplaySettings(_originalSettings);
}
private void modesListView_DoubleClick(object sender, EventArgs e)
{
if (this.modesListView.SelectedItems.Count == 0) return;
DisplaySettings set = (DisplaySettings)this.modesListView.SelectedItems[0].Tag;
if (MessageBox.Show(this, string.Format(CultureInfo.CurrentCulture,
Properties.Resources.Msg_Disp_Change, set),
Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, (MessageBoxOptions)0) == DialogResult.Yes)
{
DisplayManager.SetDisplaySettings(set);
GetCurrentSettings();
ListAllModes();
}
}
private void resetButton_Click(object sender, EventArgs e)
{
if (MessageBox.Show(this, string.Format(CultureInfo.CurrentCulture,
Properties.Resources.Msg_Disp_Change_Reset, _originalSettings),
Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0) == DialogResult.Yes)
{
DisplayManager.SetDisplaySettings(_originalSettings);
GetCurrentSettings();
ListAllModes();
}
}
private void siteLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://JustLikeAMagic.Wordpress.com");
}
private void modesListView_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
答案3
你需要使用名为设置分辨率工具
您的应用程序文件名将替换下面的 program.exe 名称。执行后,它会改变分辨率,您的应用程序运行,脚本在后台暂停,您只需在退出应用程序时按任意键,暂停后它就会继续以您设置为原始分辨率的分辨率设置。
@echo off
::======================================
:: SetResolution
::======================================
setlocal
set EXE_PATH=SetResolution.exe
set OPT_WIDTH=1920
set OPT_HEIGHT=1080
set OPT_ROTATE=0
@echo on
cmd /c %EXE_PATH% %OPT_WIDTH% %OPT_HEIGHT% %OPT_ROTATE%
@echo off
::--------------------------------------
start program.exe
pause
::======================================
@echo off
::======================================
:: SetResolution
::======================================
setlocal
set EXE_PATH=SetResolution.exe
set OPT_WIDTH=1280
set OPT_HEIGHT=720
set OPT_ROTATE=0
::------------------
@echo on
cmd /c %EXE_PATH% %OPT_WIDTH% %OPT_HEIGHT% %OPT_ROTATE%
@echo off
::--------------------------------------
endlocal
::======================================