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

Posted

技术标签:

【中文标题】System.Windows.Forms.Screen.DeviceName 在 Windows XP 上提供垃圾【英文标题】:System.Windows.Forms.Screen.DeviceName gives garbage on Windows XP 【发布时间】:2012-09-01 10:38:33 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

框架或 Windows XP 中的某处似乎存在错误。

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

\\.\DISPLAY1
\\.\DISPLAY2

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

\\.\DISPLAY1 ????A??M?↕?☺ ?
\\.\DISPLAY2 ????☺ ? ☺ ?????

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

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

如果不可打印的字符每次都相同,那就完全没问题了。但它们不是,因为事实上,它们是垃圾,随机内存内容终止空字符。

如果您只创建一个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);

如果你在 Windows XP 上运行这个 sn-p,你会得到类似的东西:

请注意您在此处如何拥有至少三个版本的DeviceName

相反,在 Windows 7 上,垃圾部分会被剔除。

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

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

【讨论】:

以上是关于System.Windows.Forms.Screen.DeviceName 在 Windows XP 上提供垃圾的主要内容,如果未能解决你的问题,请参考以下文章