Вопрос или проблема
У меня есть цифровая клавиатура, которую я использую для ввода чисел. Обычно, когда моя Windows загружается (Windows 11 Pro 10.0.22621), NumLock включен.
Однако, когда я запускаю виртуальную машину Hyper-V (gen 2), это отключает NumLock, и это действительно раздражает.
Есть ли способ предотвратить отключение NumLock при запуске виртуальной машины?
Я столкнулся с той же проблемой и перепробовал различные решения, чтобы исправить ее, но ни один из найденных в интернете подходов действительно не помог: ключ реестра:
В конце концов, я нашел только одно рабочее решение для устранения проблемы с NumLock. Необходимо создать скрипт PowerShell на виртуальной машине, например, назовем его ‘NumlockEnable.ps1’ с следующим содержимым:
$WshShell = New-Object -ComObject WScript.Shell
if ([console]::NumberLock -eq $false) {
$WshShell.SendKeys("{NUMLOCK}")
}
И сделать так, чтобы скрипт выполнялся при входе в систему, например, используя Group Policy Object (GPO), согласно инструкциям.
Также, в моем случае (гостевая ОС Windows 10), следующий ключ реестра должен быть установлен на следующее значение
[HKEY_USERS\.DEFAULT\Control Panel\Keyboard]
"InitialKeyboardIndicators"="80000002"
P.S. Конечно, это костыль, но все остальное не работает
После многих часов обратного проектирования сборок ‘Microsoft.HyperV.PowerShell.Cmdlets’ и ‘Microsoft.HyperV.PowerShell.Objects’, я наконец нашел лучший способ сделать так, чтобы виртуальная машина Hyper-V “включала NumLock по умолчанию”.
TL;DR; Вот код PowerShell:
function Set-VMNumLock {
param(
[Microsoft.HyperV.PowerShell.ComputeResource]$vm,
[bool]$NumLockEnabled
)
# Получаем объект настроек с помощью рефлексии
$ComputerResourceType = [Microsoft.HyperV.PowerShell.ComputeResource]
$SettingField = $ComputerResourceType.GetDeclaredField("_settings")
$settingUpdater = $SettingField.GetValue($vm)
$vmComputerSystemView = $settingUpdater.GetData([Microsoft.HyperV.Powershell.UpdatePolicy]::EnsureUpdated)
$vmComputerSystemView.BiosNumLock = $NumLockEnabled
$vmComputerSystemView.Put()
}
Примечание: Это настройка не может быть изменена, когда виртуальная машина включена.
Вот как использовать это
$vm = Get-VM -VMName “SampleVM”
Set-VMNumLock -vm $vm -NumLockEnabled $true
Полная история
Сначала я был вдохновлен неким кодом PowerShell на основе “WMI”/”CIM” с другого сайта. (Не уверен, могу ли я упоминать гиперссылки на других сайтах здесь). Хотя этот код не работает, но он показал мне основное, о том, “где хранится настройка NumLock”.
В итоге я декомпилировал ‘Microsoft.HyperV.PowerShell.Cmdlets.dll’ и ‘Microsoft.HyperV.PowerShell.Objects.dll’. В классе Microsoft.HyperV.PowerShell.Commands.SetVMFirmware
, вы найдете все определено в Microsoft.HyperV.PowerShell.VMFirmware
. Углубляясь дальше, его основная структура данных была
Microsoft.Virtualization.Client.Management.IVMComputerSystemSetting
(На самом деле это общая структура для виртуальных машин Gen1 и Gen2), есть булево свойство, называемое BiosNumLock
.
Фактически, программист Microsoft всего на один шаг от поддержки NumLock в Set-VMFirmware
командлете.
В классе VMBios
, есть свойство, называемое NumLockEnabled
, которое по сути обертка для этого BiosNumLock
namespace Microsoft.HyperV.PowerShell;
public sealed class VMBios : VMComponentObject, IUpdatable
{
private readonly DataUpdater<IVMComputerSystemSetting> m_VMSetting;
public bool NumLockEnabled
{
get
{
return m_VMSetting.GetData(UpdatePolicy.EnsureUpdated).BiosNumLock;
}
internal set
{
m_VMSetting.GetData(UpdatePolicy.None).BiosNumLock = value;
}
}
// ... другой код
Если Microsoft хочет поддерживать NumLock в виртуальных машинах Gen2, они просто вставляют это свойство в класс VMFirmware
. Я не знаю, почему они слишком ленивы, чтобы это сделать.
.
Ответ или решение
Проблема с отключением NumLock при запуске виртуальной машины Hyper-V в Windows 11 может быть весьма неприятной, особенно если работа с цифровой клавиатурой является частью вашей повседневной деятельности. Чтобы понять, как можно решить эту проблему, рассмотрим несколько аспектов, связанных с работой Hyper-V и управления указанной функцией.
Теория
Что такое Hyper-V и как он работает?
Hyper-V — это технология виртуализации от Microsoft, интегрированная в Windows Server и Windows 10/11, позволяющая запускать несколько виртуальных машин (ВМ) на одном физическом сервере. Каждая виртуальная машина действует как автономная система, что позволяет гибко управлять различными операционными системами и приложениями на одном устройстве.
Проблема с NumLock
Проблемы с NumLock при работе с виртуальными машинами могут возникать вследствие особенностей взаимодействия компонентов Hyper-V и настройки BIOS виртуальной машины (или эквивалента для систем Gen 2). Hyper-V генерирует отдельную среду ввода-вывода, и нередки случаи, когда настройки по умолчанию не соответствуют вашим предпочтениям или настройкам хост-системы.
Пример
Первоначальные решения
Некоторые пользователи, как вы описали, пробовали использовать скрипты PowerShell для исправления этой проблемы. Представленный скрипт PowerShell проверяет состояние NumLock и при необходимости включает его:
$WshShell = New-Object -ComObject WScript.Shell
if ([console]::NumberLock -eq $false) {
$WshShell.SendKeys("{NUMLOCK}")
}
Этот подход с использованием PowerShell достаточно прост и может быть автоматизирован через Политику групп (GPO) для запуска при входе в систему, что позволяет автоматически включать NumLock при каждом запуске виртуальной машины.
Более глубокий подход
Расширенное решение, представленное сообществом, включает использование собственных возможностей Hyper-V через рефлексию, чтобы изменить внутренние настройки виртуальной машины, включая свойство BiosNumLock
.
Для этого в PowerShell создается функция Set-VMNumLock
, которая извлекает настройки объекта виртуальной машины и модифицирует их:
function Set-VMNumLock {
param(
[Microsoft.HyperV.PowerShell.ComputeResource]$vm,
[bool]$NumLockEnabled
)
# Получаем объект настроек с помощью рефлексии
$ComputerResourceType = [Microsoft.HyperV.PowerShell.ComputeResource]
$SettingField = $ComputerResourceType.GetDeclaredField("_settings")
$settingUpdater = $SettingField.GetValue($vm)
$vmComputerSystemView = $settingUpdater.GetData([Microsoft.HyperV.Powershell.UpdatePolicy]::EnsureUpdated)
$vmComputerSystemView.BiosNumLock = $NumLockEnabled
$vmComputerSystemView.Put()
}
Этот метод позволяет непосредственно управлять настройками через внутренние API Hyper-V, что является более устойчивым решением при наличии доступа к необходимой среде и инструментам.
Применение
Как использовать
Чтобы применить данное решение, сначала необходимо выключить виртуальную машину и затем выполнить следующие команды в PowerShell:
$vm = Get-VM -VMName “SampleVM”
Set-VMNumLock -vm $vm -NumLockEnabled $true
Обратите внимание, что изменение собственных настроек невозможно, когда виртуальная машина включена. Поэтому сначала необходимо убедиться, что все изменения применяются, когда машина отключена.
Дополнительные рекомендации
- Проверка и настройка реестра: на гостевой ОС рекомендуется задать ключ реестра для начальной настройки NumLock:
[HKEY_USERS\.DEFAULT\Control Panel\Keyboard]
"InitialKeyboardIndicators"="80000002"
- Убедитесь, что все обновления Windows и Hyper-V установлены, так как они могут содержать исправления функциональности и управления оборудованием.
Заключение
Данная проблема решаема несколькими способами в зависимости от уровня доступа и возможностей вашей системы. Предложенные решения обеспечивают как простые патчи с использованием PowerShell скриптов, так и более комплексные подходы через глубокую настройку Hyper-V. Рекомендуется протестировать оба варианта, чтобы определить, какой из них лучше всего подходит для вашей специфической конфигурации. Обслуживайте рабочую среду с регулярными резервными копиями и тестами, чтобы минимизировать простои и потенциальные проблемы с функциональностью NumLock.