8

私の3.5.NETFrameworkプログラムは複数のモニターを処理するScreen.DeviceNameため、異なるモニターを区別するために使用します(Screenオブジェクトのインスタンスへの参照を比較するだけではなく、異なるインスタンスが同じ画面を参照する可能性があります)。

このプログラムはWindows7では問題なく動作しますが、すべての.NETFrameworkがインストールされているWindowsXP SP3では、指定された2つの画面が実際には同じ画面であることに気付かなかったかのように、ランダムに奇妙なことを行います。それらは同一である必要があるため、認識しDeviceNameます。

問題は何ですか?どうすれば修正できますか?

4

1 に答える 1

14

フレームワークまたはWindowsXPのどこかにバグがあるようです。

Windows 7でダンプするScreen.DeviceNameと、次のようになります。

\\。\DISPLAY1
\\。\DISPLAY2

しかし、Windows XPで同じことを行うと、次のようになります。

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

どうやらMicrosoftはバグを認識していたので、ドキュメントにメモを入れました:

この文字列には、印刷できない文字が含まれている可能性があります。

そして、印刷できない文字が毎回同じであれば、それは完全に問題ありません。
しかし、実際には、それらはゴミであり、終了するヌル文字の後に続くランダムなメモリの内容であるため、そうではありません。

オブジェクトのキャッシュされたインスタンスを1つだけ作成し、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);
}

このスニペットをWindowsXPで実行すると、次のようになります。

ここに画像の説明を入力してください

ここに少なくとも3つのバージョンがあることに注意してくださいDeviceName

逆に、Windows 7では、ガベージ部分が削除されます。

これが、コードが画面を認識できない理由です。デバイス名は毎回異なります。

これを修正するにはDeviceName、最初の文字の後に文字列をトリミングします'\0'

于 2012-09-07T14:18:22.917 に答える