我一直在努力解决Chris Iverson was having in this other Stackoverflow question。
的问题我想以编程方式启动SFC
(系统文件检查器工具)。
适用于Windows XP:
private void RunSfc()
{
ProcessStartInfo startInfo = new ProcessStartInfo("cmd", "/K sfc.exe /scannow");
System.Diagnostics.Process.Start(startInfo);
}
执行的其他变种在Windows XP下工作:
//Launch SFC directly
ProcessStartInfo startInfo = new ProcessStartInfo("sfc.exe", "/scannow");
System.Diagnostics.Process.Start(startInfo);
//Use full path to SFC
String sfcPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "sfc.exe");
ProcessStartInfo startInfo = new ProcessStartInfo(sfcPath, "/scannow");
Windows 7上的相同代码失败(启动程序以管理员身份运行)。出现控制台窗口,但SFC提供错误:
Windows Resource Protection could not start the repair service.
但是,如果我从单独的提升的命令提示符手动运行sfc /scannow
,它可以正常运行:
因此,Windows Vista / 7/8显然会发生一些奇怪的事情。我完全不知道是什么。但它可能与UAC,UIPI,会话0 isoloation或console windows were run by CSRSS
的事实有关但是,我仍然不明白这个问题。
解决克里斯的问题本来不错,因为我想做他所做的事情。
并记住:我的代码已经以管理员身份运行。我右键单击并以管理员身份启动:
这并不意味着问题不是与UAC相关的其他微妙问题,但并不是因为我作为标准用户运行。
private void button1_Click(object sender, EventArgs e)
{
RunSfc();
}
原来有一个32位版本的cmd.exe
和一个32位版本的sfc.exe
:
如果您运行提升的32位 cmd ,则32位或64位版本的 sfc 都不会起作用。
因此,难题变成了如何从32位进程启动 64位 cmd.exe
。这可能意味着难题变成如何从32位进程找到 64位版本的cmd.exe
,给出:
System32
文件夹的名称答案 0 :(得分:3)
我的实验表明该问题与WOW64模拟器有关。我在非提升的WinForms应用程序中使用此代码:
...
using System.Diagnostics;
...
ProcessStartInfo startInfo = new ProcessStartInfo("cmd", "/K sfc.exe /scannow");
startInfo.UseShellExecute = true;
startInfo.Verb = "runas";
Process.Start(startInfo);
在32位WOW64进程中,此消息在控制台窗口中失败:
Windows资源保护无法启动修复服务。
从64位进程,上面的代码成功。
确实,我认为.net或WinForms根本不相关。如果我从SysWOW64文件夹运行32位cmd.exe,然后调用sfc,我会遇到故障。但我使用64位cmd.exe成功。
甚至根本不需要将cmd.exe引入其中。从64位进程开始,不进行提升,以下成功:
...
using System.Diagnostics;
...
ProcessStartInfo startInfo = new ProcessStartInfo("sfc.exe", "/scannow");
startInfo.UseShellExecute = true;
startInfo.Verb = "runas";
Process.Start(startInfo);
所以我猜你的问题的解决方案将涉及将主程序切换到64位(可能有点激烈),或者将64位进程拼接到链中,以便可以运行64位sfc
答案 1 :(得分:1)
在这里得到了所有的帮助,我最终得到了这个,它在8.1 x64上运行良好。 非常感谢你们!
...
using System.Diagnostics;
...
private void button4_Click(object sender, EventArgs e)
{
string docs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string snat = Environment.GetEnvironmentVariable("windir") + @"\sysnative\sfc.exe";
Process a = new Process();
a.StartInfo.FileName = snat;
a.StartInfo.Arguments = "/SCANNOW";
a.StartInfo.UseShellExecute = false;
a.StartInfo.RedirectStandardOutput = true;
a.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
a.StartInfo.CreateNoWindow = true;
a.Start();
string output = a.StandardOutput.ReadToEnd();
a.WaitForExit();
using (StreamWriter outfile = new StreamWriter(docs + @"\Testoutput.txt"))
{
outfile.Write(output);
}
MessageBox.Show("DONE!");
}