Skip to content

Commit 6646d97

Browse files
committed
引导顺序切换(2/2)
1 parent 5950ef2 commit 6646d97

3 files changed

Lines changed: 35 additions & 37 deletions

File tree

src/Services/VmBootService.cs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -102,58 +102,46 @@ public async Task<bool> SetBootOrderAsync(string vmName, List<BootOrderItem> ite
102102
{
103103
return await Task.Run(() =>
104104
{
105-
string timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
106-
System.Diagnostics.Debug.WriteLine($"\n[{timestamp}] [WMI-START] 开始同步引导顺序: {vmName}");
107-
108105
try
109106
{
107+
// 🟢 关键修改:每次保存都重新获取最鲜活的 VM 和 Settings 句柄
108+
// 不要复用任何外部传入的 ManagementObject
110109
using var vm = GetVmObject(vmName);
111110
using var settings = GetVmSettings(vm);
111+
112112
bool isGen2 = settings["VirtualSystemSubType"]?.ToString() == "Microsoft:Hyper-V:SubType:2";
113113

114114
if (isGen2)
115115
{
116+
// 确保 Reference 数组内容完整
116117
string[] newOrder = items.Select(i => i.Reference.ToString()).ToArray();
117118
settings["BootSourceOrder"] = newOrder;
118-
System.Diagnostics.Debug.WriteLine($"[{timestamp}] [WMI-DEBUG] Gen2 路径总数: {newOrder.Length}, 第一项: {newOrder.FirstOrDefault()}");
119119
}
120120
else
121121
{
122122
ushort[] newOrder = items.Select(i => Convert.ToUInt16(i.Reference)).ToArray();
123123
settings["BootOrder"] = newOrder;
124-
System.Diagnostics.Debug.WriteLine($"[{timestamp}] [WMI-DEBUG] Gen1 顺序: {string.Join(",", newOrder)}");
125124
}
126125

127126
using var vmSvc = GetManagementService();
128127
using var inParams = vmSvc.GetMethodParameters("ModifySystemSettings");
128+
129+
// 🟢 关键:Hyper-V 极其依赖这个 XML 序列化格式来确认“这是整套配置更新”
129130
inParams["SystemSettings"] = settings.GetText(TextFormat.CimDtd20);
130131

131-
// 计时开始
132-
var watch = System.Diagnostics.Stopwatch.StartNew();
133132
using var outParams = vmSvc.InvokeMethod("ModifySystemSettings", inParams, null);
134-
watch.Stop();
135-
136133
uint returnValue = (uint)outParams["ReturnValue"];
137-
System.Diagnostics.Debug.WriteLine($"[{timestamp}] [WMI-RESULT] InvokeMethod 返回值: {returnValue} (耗时: {watch.ElapsedMilliseconds}ms)");
138134

139-
if (returnValue == 0) return true;
140-
if (returnValue == 4096)
141-
{
142-
string jobPath = outParams["Job"]?.ToString();
143-
System.Diagnostics.Debug.WriteLine($"[{timestamp}] [WMI-JOB] 启动异步任务: {jobPath}");
144-
return WaitForJob(jobPath);
145-
}
146-
147-
return false;
135+
if (returnValue == 4096) return WaitForJob(outParams["Job"]?.ToString());
136+
return returnValue == 0;
148137
}
149138
catch (Exception ex)
150139
{
151-
System.Diagnostics.Debug.WriteLine($"[{timestamp}] [WMI-ERROR] 异常: {ex.Message}");
140+
System.Diagnostics.Debug.WriteLine($"[WMI-CRITICAL-ERROR] {ex.Message}");
152141
return false;
153142
}
154143
});
155144
}
156-
157145
private bool WaitForJob(string jobPath)
158146
{
159147
if (string.IsNullOrEmpty(jobPath)) return false;

src/ViewModels/VirtualMachinesPageViewModel.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2606,22 +2606,21 @@ public async Task SilentSaveBootOrderAsync()
26062606
{
26072607
if (SelectedVm == null || SelectedVm.BootOrderItems == null) return;
26082608

2609-
// 🟢 增加异步排队锁:确保上一次 WMI 没写完,下一次就在这等着,不丢失操作
26102609
await _bootOrderLock.WaitAsync();
26112610
try
26122611
{
2613-
System.Diagnostics.Debug.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [VM-SAVE-PROCESS] 开始处理 WMI 写入...");
2612+
// 🟢 技巧 1:给 UI 动画留 100ms 稳定期,防止集合正在 Move 时进行快照
2613+
await Task.Delay(100);
26142614

2615-
// 必须在 UI 线程外创建快照
26162615
var currentOrder = SelectedVm.BootOrderItems.ToList();
2616+
string vmName = SelectedVm.Name;
26172617

2618-
bool result = await _vmBootService.SetBootOrderAsync(SelectedVm.Name, currentOrder);
2618+
// 🟢 技巧 2:在写入 WMI 时,直接调用 Service
2619+
// 之前的日志显示 ReturnValue 是 0,说明逻辑通了,但可能由于
2620+
// 虚拟机实例对象在内存中已过期,导致修改了“旧快照”。
2621+
bool result = await _vmBootService.SetBootOrderAsync(vmName, currentOrder);
26192622

2620-
System.Diagnostics.Debug.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [VM-SAVE-FINISHED] WMI 写入完成,结果: {result}");
2621-
}
2622-
catch (Exception ex)
2623-
{
2624-
System.Diagnostics.Debug.WriteLine($"[VM-SAVE-ERROR] {ex.Message}");
2623+
System.Diagnostics.Debug.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [VM-SAVE] 结果: {result}");
26252624
}
26262625
finally
26272626
{
@@ -2630,7 +2629,6 @@ public async Task SilentSaveBootOrderAsync()
26302629
}
26312630

26322631

2633-
26342632
// ----------------------------------------------------------------------------------
26352633
// GPU 管理模块 - 列表与基础操作
26362634
// ----------------------------------------------------------------------------------

src/Views/Components/VmDashboardView.xaml

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -692,12 +692,24 @@
692692
</StackPanel>
693693
</Border>
694694
<ui:FontIcon Glyph="&#xE76C;"
695-
FontSize="10"
696-
Margin="8,0"
697-
Opacity="0.3"
698-
VerticalAlignment="Center"
699-
Foreground="{ui:ThemeResource TextFillColorPrimaryBrush}"
700-
Visibility="{Binding IsLast, Converter={StaticResource InverseBooleanToVisibilityConverter}, FallbackValue=Visible}"/>
695+
FontSize="10"
696+
Margin="8,0"
697+
Opacity="0.3"
698+
VerticalAlignment="Center"
699+
Foreground="{ui:ThemeResource TextFillColorPrimaryBrush}">
700+
<ui:FontIcon.Style>
701+
<Style TargetType="ui:FontIcon">
702+
<!-- 默认显示箭头 -->
703+
<Setter Property="Visibility" Value="Visible"/>
704+
<Style.Triggers>
705+
<!-- 如果是最后一个人 (IsLast=True),则隐藏 -->
706+
<DataTrigger Binding="{Binding IsLast}" Value="True">
707+
<Setter Property="Visibility" Value="Collapsed"/>
708+
</DataTrigger>
709+
</Style.Triggers>
710+
</Style>
711+
</ui:FontIcon.Style>
712+
</ui:FontIcon>
701713
</StackPanel>
702714
</DataTemplate>
703715
</ItemsControl.ItemTemplate>

0 commit comments

Comments
 (0)