一开始使用PowerShell命令执行,发现过一会地区自动变回原来的值。
后来尝试了使用PowerShell脚本执行,并且增加了一些脚本策略,测试通过,不再变回原来的值。
/// <summary>
/// 设置区域
/// </summary>
/// <param name="region"></param>
/// <returns></returns>
public bool SetRegion(int geoId)
{
try
{
// 设置区域需要使用脚本文件来设置,直接使用命令设置可能会造成地区修改后自动变回去
var combine = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "setRegion.ps1");
var command = $"Set-WinHomeLocation -GeoId {geoId}";
BuildPowerShellScript(command, combine);
RunPs1File(combine);
}
catch (Exception ex)
{return false;
}
return true;
}
/// <summary>
/// 生成脚本
/// </summary>
/// <param name="scriptCommand"></param>
/// <param name="scriptFilePath"></param>
private void BuildPowerShellScript(string scriptCommand, string scriptFilePath)
{
// 如果文件存在则替换内容,如果文件不存在则创建
File.WriteAllText(scriptFilePath, scriptCommand);
}
/// <summary>
/// 执行ps1脚本文件
/// </summary>
/// <param name="ps1Path"></param>
/// <param name="isAdministrator"></param>
private string RunPs1File(string ps1Path, bool isAdministrator = true)
{
//设置执行策略
string cmd = "powershell Set-ExecutionPolicy RemoteSigned";
RunPs1Command(cmd);
//设置执行策略
cmd = "powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted";
RunPs1Command(cmd);
// 执行ps1文档
cmd = "powershell " + $"-ExecutionPolicy Bypass -File {ps1Path}";
return RunPs1Command(cmd, isAdministrator);
}
/// <summary>
/// 执行ps脚本命令
/// </summary>
/// <param name="command"></param>
/// <param name="isAdministrator"></param>
/// <returns></returns>
private string RunPs1Command(string command, bool isAdministrator = true)
{
using var pc = new Process
{
Site = null,
MaxWorkingSet = default,
MinWorkingSet = default,
PriorityBoostEnabled = false,
PriorityClass = 0,
ProcessorAffinity = default,
StartInfo = null,
SynchronizingObject = null,
EnableRaisingEvents = false
};
if (isAdministrator)
{
pc.StartInfo.Verb = "runas";
}
pc.StartInfo.FileName = "cmd.exe";
pc.StartInfo.CreateNoWindow = true;//隐藏窗口运行
pc.StartInfo.RedirectStandardError = true;//重定向错误流
pc.StartInfo.RedirectStandardInput = true;//重定向输入流
pc.StartInfo.RedirectStandardOutput = true;//重定向输出流
pc.StartInfo.UseShellExecute = false;
pc.Start();
//输入CMD命令
pc.StandardInput.WriteLine(command);
pc.StandardInput.WriteLine("exit");//结束执行,很重要的
pc.StandardInput.AutoFlush = true;
var outPut = pc.StandardOutput.ReadToEnd();//读取结果 //注释可能继续跑,app不会等待卡死
pc.WaitForExit();
pc.Close();
return outPut;
}
后续:后来又发现如果应用是安装在C:\Program Files (x86)文件夹里面,会造成无法设置成功,在其它文件夹又可以正常使用,很奇怪。
后来发现使用PowerShell命令执行,发现过一会地区自动变回原来的值,造成这个问题的根本原因是进程为x86,改成x64即可。(不知道微软后面会不会修复该问题)
public bool SetRegion(int geoId)
{
using PowerShell powerShell = PowerShell.Create();
try
{
//通过powershell设置可以触发系统变化事件,重启之后还是正常
powerShell.AddCommand("Set-WinHomeLocation")
.AddParameter("GeoId", geoId);
powerShell.Invoke();
}
catch (Exception ex)
{
return false;
}
return true;
}