Windows 10 批处理脚本用于更改特定应用程序的显示设置

Windows 10 批处理脚本用于更改特定应用程序的显示设置

我有一台运行 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 的计时可能很棘手。减少或增加睡眠时间都可能破坏脚本。在磁盘使用率高的时候运行脚本可能会导致脚本失败。您可以尝试多种不同的方法:

  1. 关注 stackoverflow
  2. 在 stackoverflow 暂停
  3. 谷歌搜索 - Windows 10 wscript 等待进程完成加载

但我坚持只使用 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

::======================================

相关内容