Не удается экспортировать ключ реестра HKLM в C # /. NET - PullRequest
0 голосов
/ 15 июня 2019

Мне нужно экспортировать ключ реестра из куста HKLM в файл.Это ключ, который я успешно создал всего несколько строк назад в той же программе.Я использую объект Process, чтобы моя программа на C # выполнила команду оболочки:

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 напрямую через командное окно, он отлично работает!

1 Ответ

1 голос
/ 15 июня 2019

Если 32-разрядный процесс выполняется в 64-разрядной ОС, необходимо отключить перенаправление файловой системы 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...