我需要将注册表项从HKLM配置单元导出到文件中。这是我在同一程序中成功创建的几行代码。我正在使用一个Process对象让我的C#程序执行shell命令:
cmd.exe / c regedit.exe / e C:\ temp \ CDPRegExport.txt HKEY_LOCAL_MACHINE \ SOFTWARE \ NPTMigration
如果我执行程序,则不会创建文件 C:\ temp \ CDPRegExport.txt 。但是,如果我直接在同一管理控制台窗口中运行上面的命令,它将正常工作!
我尝试添加应用程序清单以确保.NET程序以管理员身份运行。
我尝试调用reg.exe导出而不是regedit.exe / e,但是结果是相同的(我猜这两个程序最终将使用相同的DLL)。
这是主要的注册表导出方法:
static bool RegistryExport(string regKey, string destFile)
{
Cmd cmd = new Cmd()
{
CreateNoWindow = true
};
cmd.Exec(@"regedit.exe", @"/e", destFile, regKey);
Console.WriteLine("Standard Out:\r\n" + cmd.StandardOut);
Console.WriteLine("Standard Error:\r\n" + cmd.StandardErr);
if (!File.Exists(destFile))
{
AppContext.log.Critical(@"Registry export file ({0}) not found!", destFile);
return false;
}
return true;
}
...这是Cmd.Exe():
public void Exec(string command, params string[] Parameters)
{
string fullyQualifiedCommand = @"/c " + command + GetParameters(Parameters);
Console.WriteLine(fullyQualifiedCommand);
try
{
psi = new ProcessStartInfo(@"cmd", fullyQualifiedCommand)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
};
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
using (Process process = new Process())
{
process.StartInfo = psi;
process.Start();
if (RedirectIOStreams)
{
StandardOut = process.StandardOutput.ReadToEnd();
StandardErr = process.StandardError.ReadToEnd();
}
process.WaitForExit();
}
NormalExit = true;
}
catch (Exception ex)
{
StandardOut = string.Empty;
StandardErr = ex.ToString();
}
}
private static string GetParameters(string[] Parameters)
{
string expression = string.Empty;
if (Parameters.Length == 0)
return string.Empty;
for (int index=0; index<Parameters.Length; index++)
{
if (Parameters[index].Contains(" "))
expression += " \"" + Parameters[index] + "\"";
else
expression += " " + Parameters[index];
}
return expression;
}
当程序使用regedit.exe时,标准输出和标准错误都只是空白。
当它使用 reg.exe 导出时,标准错误显示: “错误:系统无法找到指定的注册表项或值。”
再次,这很奇怪,因为如果我直接通过命令窗口调用完全相同的 reg.exe或regedit.exe语法,它就可以正常工作!
答案 0 :(得分:1)
如果在64位操作系统上使用32位进程,则必须禁用WOW64文件系统重定向
该测试对我有效(Windows 10,VS 2015)=>
bool bWow64 = false;
IsWow64Process(Process.GetCurrentProcess().Handle, out bWow64);
if (bWow64)
{
IntPtr OldValue = IntPtr.Zero;
bool bRet = Wow64DisableWow64FsRedirection(out OldValue);
}
string sKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\NPTMigration";
string sFile = @"C:\temp\CDPRegExport.txt";
using (Process process = new Process())
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.FileName = "reg";
psi.Arguments = "export " + "" + sKey + "" + " " + "" + sFile + "";
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
process.StartInfo = psi;
process.Start();
using (StreamReader reader = process.StandardOutput)
{
string sResult = reader.ReadToEnd();
Console.Write(sResult);
}
}
带有声明:
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool IsWow64Process(IntPtr hProcess, out bool Wow64Process);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool Wow64DisableWow64FsRedirection(out IntPtr OldValue);