Как я могу заставить обнаружение в Windows?

Я часто загружаю свой компьютер с Windows 7 с подключенным KVM-переключателем, сфокусированным на другом компьютере. Когда я переключаюсь на загруженный ПК, разрешение дисплея неверно (и второй подключенный монитор не обнаружен).

Я могу исправить это, щелкнув правой кнопкой мыши на рабочем столе, выбрав Screen Resolution и нажав Detect. Это позволяет Windows обнаруживать подключенные дисплеи и настраивать оптимальное разрешение.

Я хотел бы написать небольшую утилиту, чтобы сделать это автоматически. Какой вызов Win32 API или объект С# следует использовать?

Ответ 1

Вы можете попробовать:

  • Вы можете использовать Spy ++ для поиска открываемых окон и просмотра их свойств и сообщений.
  • Используйте процесс для запуска "rundll32.exe shell32.dll, Control_RunDLL desk.cpl" или экспериментируйте с его вызовом напрямую, чтобы узнать, можете ли вы получить дескриптор окна, проверьте ссылку ниже для идей.
  • Используйте код "отправить кнопку, нажмите на внешнее приложение" и измените ее, чтобы найти окно с надписью "Разрешение экрана" и отправьте BN_CLICK в дочернее окно с надписью "Обнаружить".
  • Поскольку компьютер уже включен, вы можете запустить его автоматически при входе в систему, для чего используется планировщик задач.

Ответ 2

Не уверен, что это сработает для вас, но вы можете попробовать что-то вроде этого. По крайней мере, вы можете начать.

[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 714)]
public struct DISPLAY_DEVICE
{
    [FieldOffset(0)]
    public int cb;
    [FieldOffset(4)]
    public char DeviceName;
    [FieldOffset(68)]
    public char DeviceString;
    [FieldOffset(324)]
    public int StateFlags;
    [FieldOffset(328)]
    public char DeviceID;
    [FieldOffset(584)]
    public char DeviceKey;
}

[DllImport("User32.dll", SetLastError = true)]
static extern Boolean EnumDisplayDevices(
        string lpDevice,
        uint iDevNum,
        ref DISPLAY_DEVICE lpDisplayDevice,
        uint dwFlags
);

public void DetectDevices()
{
    var flag = true;
    for (uint i = 0; flag && i < 100; i++)
    {
        var device = new DISPLAY_DEVICE();
        device.cb = Marshal.SizeOf(device);
        flag = EnumDisplayDevices(null, i, ref device, 1);
    }
}

Ответ 3

Это поможет вам на полпути:

Выполнить: control.exe desk.cpl, Настройки, @Настройки

Это приведет к появлению панели разрешения экрана напрямую.

Я также мог бы предложить инструмент для создания сценариев, например http://en.wikipedia.org/wiki/Windows_Script_Host И напишите утилиту, которая откроет панель и нажмите кнопку.

Запрет на то, что панель управления напрямую вызывает в Windows.dll, которую вы можете загружать и вызывать в коде напрямую, но для этого требуется некоторое отслеживание. (вы можете начать с запуска .cpl в отладчике и посмотреть, что произойдет, когда вы нажмете обнаружение).

Ответ 4

Почему бы просто не использовать Do It Again и написать макрос, который сбрасывает разрешение для вас, записывая действия мыши и клавиатуры?