使用.netFx4.0提供的方法解決32位程序訪問64位系統的64位注冊表


 

我們知道目標平台是32位的程序運行在64位的系統上,去訪問部分注冊表的時候系統自動重定向到win32node節點對應的項去了。但是做過安裝程序開發人員可能遇到過“需要去掉重定向”的問題,即直接訪問64位程序的注冊表。

網上有很多winAPI的方法,關閉注冊表的重定向稍微復雜。(關閉文件系統的重定向稍微簡單些,搬過來就可以用;關閉注冊表的重定向我現在沒看懂。)

我這里提供的方法不需要關閉重定向,也不需要用winAPI,操作起來方便了許多。具體如下:

    第一個方法是獲得根節點的句柄,常數是固定的。

 

     static IntPtr GetHiveHandle(RegistryHive hive)
        {
            IntPtr preexistingHandle = IntPtr.Zero;

            IntPtr HKEY_CLASSES_ROOT = new IntPtr(-2147483648);
            IntPtr HKEY_CURRENT_USER = new IntPtr(-2147483647);
            IntPtr HKEY_LOCAL_MACHINE = new IntPtr(-2147483646);
            IntPtr HKEY_USERS = new IntPtr(-2147483645);
            IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(-2147483644);
            IntPtr HKEY_CURRENT_CONFIG = new IntPtr(-2147483643);
            IntPtr HKEY_DYN_DATA = new IntPtr(-2147483642);
            switch (hive)
            {
                case RegistryHive.ClassesRoot: preexistingHandle = HKEY_CLASSES_ROOT; break;
                case RegistryHive.CurrentUser: preexistingHandle = HKEY_CURRENT_USER; break;
                case RegistryHive.LocalMachine: preexistingHandle = HKEY_LOCAL_MACHINE; break;
                case RegistryHive.Users: preexistingHandle = HKEY_USERS; break;
                case RegistryHive.PerformanceData: preexistingHandle = HKEY_PERFORMANCE_DATA; break;
                case RegistryHive.CurrentConfig: preexistingHandle = HKEY_CURRENT_CONFIG; break;
                case RegistryHive.DynData: preexistingHandle = HKEY_DYN_DATA; break;
            }
            return preexistingHandle;
        }

        /// <summary>
        /// 用於32位程序訪問64位注冊表
        /// </summary>
        /// <param name="hive">根級別的名稱</param>
        /// <param name="keyName">不包括根級別的名稱</param>
        /// <param name="valueName">項名稱</param>
        /// <param name="view">注冊表視圖</param>
        /// <returns></returns>
        static object GetValueWithRegView(RegistryHive hive, string keyName, string valueName, RegistryView view)
        {

            SafeRegistryHandle handle = new SafeRegistryHandle(GetHiveHandle(hive), true);//獲得根節點的安全句柄

            RegistryKey subkey = RegistryKey.FromHandle(handle, view).OpenSubKey(keyName);//獲得要訪問的鍵

            RegistryKey key = RegistryKey.FromHandle(subkey.Handle, view);//根據鍵的句柄和視圖獲得要訪問的鍵

            return key.GetValue(valueName);//獲得鍵下指定項的值
        }
        /// <summary>
        /// 用於32位的程序設置64位的注冊表
        /// </summary>
        /// <param name="hive">根級別的名稱</param>
        /// <param name="keyName">不包括根級別的名稱</param>
        /// <param name="valueName">項名稱</param>
        /// <param name="value"></param>
        /// <param name="kind">值類型</param>
        /// <param name="view">注冊表視圖</param>
        static void SetValueWithRegView(RegistryHive hive, string keyName, string valueName, object value, RegistryValueKind kind, RegistryView view)
        {
            SafeRegistryHandle handle = new SafeRegistryHandle(GetHiveHandle(hive), true);

            RegistryKey subkey = RegistryKey.FromHandle(handle, view).OpenSubKey(keyName, true);//需要寫的權限,這里的true是關鍵。0227更新

            RegistryKey key = RegistryKey.FromHandle(subkey.Handle, view);

            key.SetValue(valueName, value, kind);
        }

       使用這些方法需要引入Microsoft.Win32.SafeHandles;Microsoft.Win32;system;這三個命名空間。方法只提供了主干,沒有異常處理。望大家及時交流實際使用情況,不足之處請及時指出。

關於winAPI的方法可以訪問http://home.cnblogs.com/u/xuguilin/相應的文章,同時也感謝xuguilin對我的指導。據介紹dotNet框架可能需要4.0版本以上


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM