سؤال

I'm trying to use ShellExecute to open the 64 bit Regedit from my 32 bit application.

I noticed in Process Explorer that if I open Regedit normally, it says the image is 64 bit, but if I open C:\Windows\Regedit.exe from my 32 bit application with ShellExecute, Process Explorer says the image is 32 bit.

(and it does open the regedit in the Windows directory, not in SysWOW64)

I've found that if I use the Wow64DisableWow64FsRedirection function before calling ShellExecute, it opens the 64 bit image of it. But my application won't run on 32 bit XP.

What puzzles me is regardless of which way I open regedit, they both reside in C:\Windows, and are both the same executable. How can the same executable have 2 different image types? And how can I open the 64 bit one without Wow64DisableWow64FsRedirection?

هل كانت مفيدة؟

المحلول

You need to detect if you are in a 64 bit process with Is64BitProcess, if so, access %windir%\Sysnative as that points to the "Real" System32 folder for when 32 bit applications need to access the 64 bit System32 folder.

string system32Directory = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32");
if(Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
    // For 32-bit processes on 64-bit systems, %windir%\system32 folder
    // can only be accessed by specifying %windir%\sysnative folder.
    system32Directory = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "sysnative");

}

نصائح أخرى

This is the code i used to launch regedit in 64 bits from a 32 bits application:

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);

    internal int ExecuteCommand64(string Command, string Parameters)
    {

        IntPtr ptr = new IntPtr();
        bool isWow64FsRedirectionDisabled = Wow64DisableWow64FsRedirection(ref ptr);
        if (isWow64FsRedirectionDisabled)
        {

            //Set up a ProcessStartInfo using your path to the executable (Command) and the command line arguments (Parameters).
            ProcessStartInfo ProcessInfo = new ProcessStartInfo(Command, Parameters);
            ProcessInfo.CreateNoWindow = true;
            ProcessInfo.UseShellExecute = false;
            ProcessInfo.RedirectStandardOutput = true;

            //Invoke the process.
            Process Process = Process.Start(ProcessInfo);
            Process.WaitForExit();

            //Finish.
            // this.Context.LogMessage(Process.StandardOutput.ReadToEnd());
            int ExitCode = Process.ExitCode;
            Process.Close();
            bool isWow64FsRedirectionOK = Wow64RevertWow64FsRedirection(ptr);
            if (!isWow64FsRedirectionOK)
            {
                throw new Exception("Le retour en 32 bits a échoué.");
            }
            return ExitCode;
        }

        else
        {
            throw new Exception("Impossible de passer en 64 bits");
        }

    }

And i call it with the following line:

ExecuteCommand64(@"c:\windows\regedit", string.Format("\"{0}\"", regFileName));

Where regFilename is the registry file i want to add to the registry.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top