【发布时间】:2018-01-10 09:08:22
【问题描述】:
在我的公司,我们有时会使用表面自动化来自动化我们的流程。这意味着,程序正在屏幕上搜索图像并单击它们,例如:
我们正在使用2560 x 1440 的屏幕分辨率进行开发。我们有许多计算机在那里为我们工作——并非所有计算机都始终连接到显示器。当我断开显示器时,Windows 将分辨率更改为1024 x 768。 我想避免这种情况。在互联网上,我读到了 NirCmd 工具 - 但在我的大型保守公司中使用这样的工具并不容易,我想知道 C# 是否有可能。
我找到了一个完美的解决方案 - 但前提是连接了监视器(在此请求末尾找到代码)。 即使没有连接显示器,是否有可能更改分辨率? 或者是否有可能一劳永逸地定义分辨率,Windows 在没有连接屏幕的情况下使用?这对我不起作用: https://superuser.com/questions/604026/how-to-set-default-screen-resolution-and-color-depth-without-monitor-in-windows
运行良好的代码 - 但仅限于连接屏幕时:
[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 static class ScreenResolution
{
/// <summary>
/// Ändert die Bildschirmauflösung in die gewünschte Größe
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
public static void ChangeResolution(int width, int height)
{
Screen screen = Screen.PrimaryScreen;
int iWidth = width;
int iHeight = height;
DEVMODE1 dm = new DEVMODE1();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
{
dm.dmPelsWidth = iWidth;
dm.dmPelsHeight = iHeight;
int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST);
if (iRet == User_32.DISP_CHANGE_FAILED)
{
MessageBox.Show("Unable to process your request");
MessageBox.Show("Description: Unable To Process Your Request. Sorry For This Inconvenience.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY);
switch (iRet)
{
case User_32.DISP_CHANGE_SUCCESSFUL:
{
break;
//successfull change
}
case User_32.DISP_CHANGE_RESTART:
{
MessageBox.Show("Description: You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
//windows 9x series you have to restart
}
default:
{
MessageBox.Show("Description: Failed To Change The Resolution.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
//failed to change
}
}
}
}
}
}
【问题讨论】:
-
我建议你在C++中找到一个解决方案,然后翻译。试图通过增加 p/invoke 的复杂性来解决这个问题,只会导致缓慢的痛苦进展和错误的结论。
-
当你运行它时,你是以用户身份还是“以管理员身份”运行它?
-
是的,我这样做了。正如我所说,如果连接了显示器,它就可以工作。只有在没有连接显示器的情况下,他才会给我一条消息,他不能更改分辨率。我写了一个程序,每秒将屏幕分辨率写入控制台。 10 秒后,他正在执行更改分辨率的功能。我以管理员身份运行它,然后断开监视器。当我重新连接它时,我可以看到,他降低了分辨率。
标签: c# winapi screen-resolution