System.Windows.Forms.Screen.DeviceName在Windows XP上提供了垃圾

GSe*_*erg 8 .net c# windows-xp screen winforms

我的3.5 .NET Framework程序处理多个监视器,因此我Screen.DeviceName用来区分不同的监视器(不能仅仅比较Screen对象实例的引用- 不同的实例可以引用同一个屏幕).

该程序在Windows 7上没有问题,但在安装了所有.NET框架的Windows XP SP3上,它会随机做一些奇怪的事情,好像它没有意识到两个给定的屏幕实际上是同一个屏幕,它应该能够认识到他们应该有相同的DeviceNames.

有什么问题,我该如何解决?

GSe*_*erg 14

在框架或Windows XP中似乎存在某个错误.

如果你Screen.DeviceName在Windows 7下转储,你会得到类似的东西

\\.\DISPLAY1
\\.\DISPLAY2

但是如果你在Windows XP上做同样的事情,你会得到类似的东西

\\.\DISPLAY1    ????A??M????  ?
\\.\DISPLAY2    ????? ? ? ?????

显然微软已经意识到了这个错误,所以他们在文档中写了一个注释:

此字符串可能包含不可打印的字符.

如果不可打印的字符每次都相同,那就完全可以了.
但它们不是,因为实际上它们是垃圾,随机存储器内容,它们位于终止空字符之后.

如果您只创建一个Screen对象的缓存实例并DeviceName多次调用其属性,则每次垃圾都是相同的,因为该Screen对象会自动缓存该名称.但是,如果Screen为每个请求创建对象的新实例,则这些实例的垃圾可能会有所不同,即使它们引用同一设备:

System.Windows.Forms.Screen s = null;
System.Drawing.Point p = new System.Drawing.Point(0,0);

Console.WriteLine("Using same instance of Screen:");
s = System.Windows.Forms.Screen.FromPoint(p);
for (int i = 0; i < 5; ++i)
{
    Console.WriteLine(s.DeviceName);
}

Console.WriteLine();

Console.WriteLine("Using new instance of Screen:");
for (int i = 0; i < 5; ++i)
{
    Console.WriteLine(System.Windows.Forms.Screen.FromPoint(p).DeviceName);
}
Run Code Online (Sandbox Code Playgroud)

如果您在Windows XP上运行此代码段,您将获得以下内容:

在此输入图像描述

请注意你在DeviceName这里至少有三个版本.

相反,在Windows 7上,垃圾部分将被剥离.

这就是代码无法识别屏幕的原因 - 设备名称每次都不同.

要解决此问题,请DeviceName在第一个'\0'字符后裁剪字符串.

  • 但是...表情符号!`:D' (6认同)