如何在Windows Vista / 7/8上以编程方式启动SFC?

我一直在试图解决Chris Iverson在其他的Stackoverflow问题中遇到的问题 。

我想以编程方式启动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上的相同代码失败(启动程序以pipe理员身份运行)。 出现控制台窗口,但SFC提供了错误:

 Windows Resource Protection could not start the repair service. 

在这里输入图像说明

但是,如果我手动运行sfc /scannow单独的提升命令提示符,它的工作原理:

在这里输入图像说明

所以Windows Vista / 7/8显然有一些奇怪的事情发生。 我不知道,究竟是什么。 但是这很可能与UAC,UIPI,session 0 isoloation或控制台窗口由CSRSS运行

但是,我仍然不明白这个问题。

如果我想要做他所做的事情,那么解决Chris的问题本来是很好的。

请记住 :我的代码已经以pipe理员身份运行。 我右键单击并以pipe理员身份启动

在这里输入图像说明

这并不意味着这个问题不是UAC相关的一些其他微妙的问题,但这不是由于我以标准用户身份运行的事实。

在WinForms应用程序中的代码

 private void button1_Click(object sender, EventArgs e) { RunSfc(); } 

32位失败

结果发现有一个32位版本的cmd.exe和一个32位版本的sfc.exe

  • C:\ WINDOWS \ Syswow64资料\ cmd.exe的
  • C:\ WINDOWS \ Syswow64资料\ SFC.EXE

如果运行提升的32位cmdsfc的32位或64位版本都不起作用。

所以这个难题变成了如何从32位进程启动64位 cmd.exe 。 这可能意味着这个难题变成了如何从32位进程中find 64位版本的cmd.exe

  • 您可能不在64位机器上
  • 您可能已经在运行一个64位进程
  • Windows喜欢根据您的进程的位元来伪造System32文件夹的名称

Solutions Collecting From Web of "如何在Windows Vista / 7/8上以编程方式启动SFC?"

我的实验表明这个问题与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

有了这里的所有帮助,我结束了这一点,它在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!"); }