天天看點

RunAsAdmin解決方案 提供regedit的管理者權限讀寫

 HelpViewerUIFramework.RunAsAdmin AdminRun = new RunAsAdmin(this.TestContext);

AdminRun.ExeCode = "HelpViewerUIFramework.RunAsAdminStaticMethod.ReadWriteRegedit.WriteRegistryValueEx(Microsoft.Win32.Registry.LocalMachine, HelpViewerUIFramework.HelpViewerSettings.DefaultStoreRegistryLocation, HelpViewerUIFramework.HelpViewerSettings.LocalStoreRegistryKey, @\"" + LocalStoreDefaultPath + "temp\");";

AdminRun.RunProcess();

--------------------------------------------------------

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Diagnostics;

using System.Runtime.InteropServices;

using System.CodeDom.Compiler;

using Microsoft.CSharp;

using Microsoft.Win32;

namespace HelpViewerUIFramework

{

    public class RunAsAdmin

    {

        #region Fields

        private string m_AddUsing = "";

        private string m_PreClassCode = "";

        private string m_PreMainCode = "";

        private string m_ExeCode = "";

        private const string m_RunAsAdminExeName = "RunAsAdmin.exe";

        SHELLEXECUTEINFO m_lpExecInfo = new SHELLEXECUTEINFO();

        private Microsoft.VisualStudio.TestTools.UnitTesting.TestContext m_testContext;

        #endregion

        #region Constructors

        public RunAsAdmin(Microsoft.VisualStudio.TestTools.UnitTesting.TestContext testContext)

        {

            this.m_testContext = testContext;

        }

        #region proerpties

        public string AddUsing

            get { return m_AddUsing; }

            set { m_AddUsing = value; }

        public string PreClassCode

            get { return m_PreClassCode; }

            set { m_PreClassCode = value; }

        public string PreMainCode

            get { return m_PreMainCode; }

            set { m_PreMainCode = value; }

        public string ExeCode

            get { return m_ExeCode; }

            set { m_ExeCode = value; }

        #region ImportAPI

        [StructLayout(LayoutKind.Sequential)]

        private struct SHELLEXECUTEINFO //using in ShellExecuteEx

            public int cbSize;

            public uint fMask;

            public IntPtr hwnd;

            [MarshalAs(UnmanagedType.LPWStr)]

            public string lpVerb;

            public string lpFile;

            public string lpParameters;

            public string lpDirectory;

            public int nShow;

            public IntPtr hInstApp;

            public IntPtr lpIDList;

            public string lpClass;

            public IntPtr hkeyClass;

            public uint dwHotKey;

            public IntPtr DUMMYUNIONNAME;

            public IntPtr hProcess;

        [System.Runtime.InteropServices.DllImport("Shell32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]

        private static extern uint ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);

        [System.Runtime.InteropServices.DllImport("Kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]

        private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

        private static extern uint TerminateProcess(IntPtr hHandle, uint uExitCode);

        #region Method

        private uint RunAdminProcess()

            int SW_HIDE = 0;

            uint SEE_MASK_NOCLOSEPROCESS = (0x00000040);

            m_lpExecInfo.cbSize = Marshal.SizeOf(m_lpExecInfo);

            m_lpExecInfo.lpVerb = "runas";

            m_lpExecInfo.lpFile = this.m_testContext.DeploymentDirectory + "\\" + m_RunAsAdminExeName;

            m_lpExecInfo.lpParameters = "";

            m_lpExecInfo.nShow = SW_HIDE;

            m_lpExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;

            return ShellExecuteEx(ref m_lpExecInfo);

        private void CreateAdminProcess()

            string code = "using System;" + System.Environment.NewLine +

                m_AddUsing + System.Environment.NewLine +

                "namespace RunAsAdmin" + System.Environment.NewLine +

                "{" + System.Environment.NewLine +

                "    " + m_PreClassCode + System.Environment.NewLine +

                "    class Program" + System.Environment.NewLine +

                "    {" + System.Environment.NewLine +

                "        " + m_PreMainCode + System.Environment.NewLine +

                "        static void Main()" + System.Environment.NewLine +

                "        {" + System.Environment.NewLine +

                "            " + m_ExeCode + System.Environment.NewLine +

                "        }" + System.Environment.NewLine +

                "    }" + System.Environment.NewLine +

                "}" + System.Environment.NewLine;

            CompileCode(code, System.IO.Path.Combine(this.m_testContext.DeploymentDirectory, m_RunAsAdminExeName));

            return;

        private void CompileCode(string SourceCode, string ExeuteFileName)

            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

            CompilerParameters cp = new CompilerParameters(new string[] { "System.dll", System.IO.Path.Combine(this.m_testContext.DeploymentDirectory, "HelpViewerUIFramework.dll") }, ExeuteFileName, false);

            cp.CompilerOptions = "/target:exe";

            cp.IncludeDebugInformation = true;

            cp.GenerateExecutable = true;

            CompilerResults cr = provider.CompileAssemblyFromSource(cp, SourceCode);

            if (cr.Errors.HasErrors)

            {

                StringBuilder error = new StringBuilder();

                error.AppendLine("building error:");

                foreach (CompilerError err in cr.Errors)

                {

                    error.AppendFormat("{0}\n",err.ErrorText);

                }

                throw new Exception(error.ToString());

            }

        public void RunProcess()

            CreateAdminProcess();

            if (RunAdminProcess() != 1)//TRUE

                throw new Exception("RunProcess Error.");

            if (WaitForSingleObject(m_lpExecInfo.hProcess, 30000) == 258L)//WAIT_TIMEOUT

                TerminateProcess(m_lpExecInfo.hProcess, 0);

                throw new Exception("RunProcess Timeout then be killed.");

    }

    public static class RunAsAdminStaticMethod

        public static class ReadWriteRegedit

            /// <summary>

            /// WinAPI extend for Regedit

            /// </summary>

            /// <history>create by hc 20101217</history>

            [System.Runtime.InteropServices.DllImport("Advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]

            private static extern uint RegOpenKeyEx(IntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult);

            private static extern uint RegQueryValueEx(IntPtr hKey, string lpValueName, IntPtr lpReserved, IntPtr lpType, Byte[] pvData, ref UInt32 lpcbData);

            private static extern uint RegSetValueEx(IntPtr hKey, string lpValueName, uint Reserved, uint dwType, IntPtr lpData, uint cbData);

            private static extern uint RegDeleteValue(IntPtr hKey, string lpValueName);

            private static extern uint RegCloseKey(IntPtr hKey);

            /// check if the system is a 64bit system

            /// <returns></returns>

            private static bool Is32BitOperatingSystem()

                Microsoft.Win32.RegistryKey localEnvironment = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment");

                String processorArchitecture = (String)localEnvironment.GetValue("PROCESSOR_ARCHITECTURE");

                return processorArchitecture.Equals("x86");

            public static string ReadRegistryValueEx(Microsoft.Win32.RegistryKey baseKeyName, string subKey, string KeyName)

                const long ERROR_SUCCESS = 0L;

                const int KEY_QUERY_VALUE = (0x0001);

                const int KEY_READ = (0x20019);

                const int KEY_WOW64_64KEY = (0x0100);

                int KEY_VALUE = 0;

                IntPtr REGISTRYKEY = new IntPtr(0x0000);

                IntPtr hKey = new IntPtr(0x0000);

                long ERROR_CODE = 0;

                if (baseKeyName == Microsoft.Win32.Registry.ClassesRoot)

                    REGISTRYKEY = (IntPtr)(-2147483648);

                else if (baseKeyName == Microsoft.Win32.Registry.CurrentUser)

                    REGISTRYKEY = (IntPtr)(-2147483647);

                else if (baseKeyName == Microsoft.Win32.Registry.LocalMachine)

                    REGISTRYKEY = (IntPtr)(-2147483646);

                else if (baseKeyName == Microsoft.Win32.Registry.Users)

                    REGISTRYKEY = (IntPtr)(-2147483645);

                if (Is32BitOperatingSystem())//32bit

                    KEY_VALUE = KEY_QUERY_VALUE | KEY_READ;

                else//64bit

                    KEY_VALUE = (KEY_QUERY_VALUE | KEY_READ | KEY_WOW64_64KEY);

                ERROR_CODE = RegOpenKeyEx(REGISTRYKEY, subKey, 0, KEY_VALUE, out hKey);

                if (ERROR_SUCCESS != ERROR_CODE)

                    throw new System.Exception(String.Format("Open Regedit Error:{0}", ERROR_CODE));

                UInt32 size = 0;

                ERROR_CODE = RegQueryValueEx(hKey, KeyName, IntPtr.Zero, IntPtr.Zero, null, ref size);

                    throw new System.Exception(String.Format("Get Regedit Value Error:{0}", ERROR_CODE));

                Byte[] value = new Byte[size];

                ERROR_CODE = RegQueryValueEx(hKey, KeyName, IntPtr.Zero, IntPtr.Zero, value, ref size);

                ERROR_CODE = RegCloseKey(REGISTRYKEY);

                    throw new System.Exception(String.Format("Close Regedit Error:{0}", ERROR_CODE));

                return Encoding.Unicode.GetString(value).TrimEnd('\0');

            public static bool WriteRegistryValueEx(Microsoft.Win32.RegistryKey baseKeyName, string subKey, string KeyName, string KeyValue)

                const int KEY_SET_VALUE = (0x0002);

                uint REG_SZ = 1;

                    KEY_VALUE = KEY_SET_VALUE;

                    KEY_VALUE = (KEY_SET_VALUE | KEY_WOW64_64KEY);

                ERROR_CODE = RegSetValueEx(hKey, KeyName, 0, REG_SZ, System.Runtime.InteropServices.Marshal.StringToHGlobalAuto(KeyValue), (uint)(KeyValue.Length * 2));

                    throw new System.Exception(String.Format("Set Regedit Value Error:{0}", ERROR_CODE));

                return true;

            public static string ReadRegistryValue(RegistryKey baseKeyName, string subKey, string KeyName)

                RegistryKey rk = baseKeyName;

                RegistryKey sk = rk.OpenSubKey(subKey);

                if (sk == null)

                    return "";

                else

                    string val = (string)sk.GetValue(KeyName);

                    return val == null ? "" : val;

            public static int ReadRegistryIntValue(RegistryKey baseKeyName, string subKey, string KeyName)

                    return -1;

                    int val = (int)sk.GetValue(KeyName);

                    return val == null ? -1 : val;

            public static bool WriteRegistryValue(RegistryKey baseKeyName, string subKey, string KeyName, string KeyValue)

                RegistryKey sk = rk.OpenSubKey(subKey, true);

                    return false;

                sk.SetValue(KeyName, KeyValue, RegistryValueKind.String);

            public static bool WriteRegistryIntValue(RegistryKey baseKeyName, string subKey, string KeyName, int KeyValue)

                sk.SetValue(KeyName, KeyValue, RegistryValueKind.DWord);

繼續閱讀