如何在Windows Vista/7/8上以编程方式启动SFC? [英] How to launch SFC programatically on Windows Vista/7/8?

查看:52
本文介绍了如何在Windows Vista/7/8上以编程方式启动SFC?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力解决

但是,我还是不明白这个问题.

解决Chris的问题真是太好了,因为我极有可能想做他所做的事情.

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

这并不意味着该问题不是与UAC有关的其他细微问题,但这并不是由于我以标准用户身份运行.

WinForms应用程序中的代码

  private void button1_Click(对象发送者,EventArgs e){RunSfc();} 

32位失败

原来有一个32位版本的 cmd.exe 和一个32位版本的 sfc.exe :

  • C:\ Windows \ SysWOW64 \ cmd.exe
  • C:\ Windows \ SysWOW64 \ sfc.exe

如果运行提升的32位 cmd ,则 sfc 的32位和64位版本均不起作用.

所以难题在于如何从32位进程中启动 64位 cmd.exe .这可能意味着难题在于如何从32位进程中查找 64位版本的 cmd.exe ,如下所示:

  • 您可能不在64位计算机上
  • 您可能已经在运行64位进程
  • Windows喜欢根据进程的位数伪造 System32 文件夹的名称

解决方案

我的实验表明,该问题与WOW64模拟器有关.我在非高架WinForms应用程序中有以下代码:

  ...使用System.Diagnostics;...ProcessStartInfo startInfo =新的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位进程成功执行以下操作:

  ...使用System.Diagnostics;...ProcessStartInfo startInfo =新的ProcessStartInfo("sfc.exe","/scannow");startInfo.UseShellExecute = true;startInfo.Verb ="runas";Process.Start(startInfo); 

所以我想解决您的问题的方法是将主程序切换到64位(可能有点过激),或者将64位进程拼接到链中,以便64位 sfc 可以运行.

I've been trying to solve the problem that Chris Iverson was having in this other Stackoverflow question.

I want to launch SFC (the System File Checker tool) programatically.

It works on Windows XP:

private void RunSfc()
{
    ProcessStartInfo startInfo = new ProcessStartInfo("cmd", "/K sfc.exe /scannow");
    System.Diagnostics.Process.Start(startInfo);
}

Other variants that do work under 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"); 

The same code fails on Windows 7 (with the launching program running as an administrator). The console window appears, but SFC gives the error:

Windows Resource Protection could not start the repair service.

But if i manually run sfc /scannow from a separate elevated command prompt, it works:

So there is obviously something strange happening with Windows Vista/7/8. i don't know what, exactly. But it's likely related to UAC, UIPI, session 0 isoloation, or the fact that console windows were run by CSRSS

But still, i don't understand the issue.

It would have been nice to solve Chris's issue, in the off chance that i want to do what he did.

And remember: My code already is running as an administrator. I right-click and Launch as administrator:

That doesn't mean the issue is not some other subtle issue related to UAC, but it's not due to the fact that i'm running as a standard user.

Code in WinForms application

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

32-bit fails

Turns out there is a 32-bit version of cmd.exe and a 32-bit version of sfc.exe:

  • C:\Windows\SysWOW64\cmd.exe
  • C:\Windows\SysWOW64\sfc.exe

If you run an elevated 32-bit cmd, neither the 32-bit nor 64-bit version of sfc will work.

So the conundrum becomes how to launch the 64-bit cmd.exe from a 32-bit process. Which probably means the conundrum becomes how to find the the 64-bit version of cmd.exe from a 32-bit process, given:

  • you may not be on a 64-bit machine
  • you might already be running a 64-bit process
  • Windows likes to fake the names of the System32 folder based on the bit-ness of your process

解决方案

My experiments suggest that the issue is related to the WOW64 emulator. I have this code in a non-elevated WinForms app:

...
using System.Diagnostics;
...

ProcessStartInfo startInfo = new ProcessStartInfo("cmd", "/K sfc.exe /scannow");
  startInfo.UseShellExecute = true;
  startInfo.Verb = "runas";
Process.Start(startInfo);

From a 32 bit WOW64 process this fails with this message in the console window:

Windows Resource Protection could not start the repair service.

From a 64 bit process, the above code succeeds.

Indeed, I don't think .net or WinForms are relevant here at all. If I run 32 bit cmd.exe from the SysWOW64 folder, and then call sfc, I experience failure. But I am successful with the 64 bit cmd.exe.

And there's not even any need to bring cmd.exe into this at all. From a 64 bit process, running without elevation, the following succeeds:

...
using System.Diagnostics;
...

ProcessStartInfo startInfo = new ProcessStartInfo("sfc.exe", "/scannow");
startInfo.UseShellExecute = true;
startInfo.Verb = "runas";
Process.Start(startInfo);

So I guess the solution to your problem will involve either switching your main program to 64 bit (probably a little drastic), or splicing a 64 bit process into the chain so that the 64 bit sfc can be run.

这篇关于如何在Windows Vista/7/8上以编程方式启动SFC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆