zoukankan      html  css  js  c++  java
  • Unity中对注册表进行修改

    问题背景:

    PC端软件开发,当我在Unity中的PlayerSetting中设置好分辨率,每次打包运行后会记忆上次退出时窗口的分辨率(记忆窗口状态),导致下次打开时不是PlayerSetting中的初始设置,而是读取注册表记录的数据。而我的需求时必须每次进去时都是指定的那个分辨率。

    问题纠结点:

    1.注册表信息是否可删,怎么获取到删除

    2.也不能直接删除整个项目的注册表信息,因为有些数据我们必须记录,所以必须找到具体的KEY.

    解决方案:

    在软件退出时我们清除注册表中分辨率的指定KEY。

    具体过程:

    1.查找操作目标:

    我们的应用程序记录在: 注册表 ”计算机“ 中的HKEY_CURRENT_USERSoftware中,是这样的结构:

    HKEY_CURRENT_USERSoftwareCompany NameProduct Name

    通过查找,最后确定在这四项与Screen有关系。我们目标已经找到了,就是操作这四项。

    2.获取到该四项,退出时删除该四项。

     1  //注册表中屏幕相关Key
     2         private readonly string regeditScreenFullscreenModeKey = "Screenmanager Fullscreen mode_h3630240806";
     3         private readonly string regeditScreenResolutionHeightKey = "Screenmanager Resolution Height_h2627697771";
     4         private readonly string regeditScreenResolutionUseNativeKey = "Screenmanager Resolution Use Native_h1405027254";
     5         private readonly string regeditScreenResolutionWidthKey = "Screenmanager Resolution Width_h182942802";
     6 
     7     //注册表当前工程项
     8         private StringBuilder regeditPathNode = new StringBuilder();
     9 
    10         /// <summary>
    11         /// 初始化
    12         /// </summary>
    13         public void OnSingletonInit()
    14         {
    15             regeditPathNode = regeditPathNode.Append("Software\").Append(Application.companyName).Append("\").Append(Application.productName);
    16         }
    17 
    18  //清空注册表数据
    19             if (Utils.IsJudgeNode(regeditPathNode.ToString()))
    20             {
    21                 if (Utils.IsJudgeNodeKey(regeditPathNode.ToString(), regeditScreenFullscreenModeKey))
    22                 {
    23                     Utils.DeleteNodeKey(regeditPathNode.ToString(), regeditScreenFullscreenModeKey);
    24                 }
    25                 if (Utils.IsJudgeNodeKey(regeditPathNode.ToString(), regeditScreenResolutionHeightKey))
    26                 {
    27                     Utils.DeleteNodeKey(regeditPathNode.ToString(), regeditScreenResolutionHeightKey);
    28                 }
    29                 if (Utils.IsJudgeNodeKey(regeditPathNode.ToString(), regeditScreenResolutionUseNativeKey))
    30                 {
    31                     Utils.DeleteNodeKey(regeditPathNode.ToString(), regeditScreenResolutionUseNativeKey);
    32                 }
    33                 if (Utils.IsJudgeNodeKey(regeditPathNode.ToString(), regeditScreenResolutionWidthKey))
    34                 {
    35                     Utils.DeleteNodeKey(regeditPathNode.ToString(), regeditScreenResolutionWidthKey);
    36                 }
    37             }

           using Microsoft.Win32;
           using System.Collections.Generic;
           using UnityEngine;

    /// <summary>
     2     /// 工具类
     3     /// </summary>
     4     public class Utils
     5     {
     6         #region 公有方法
     7 
     8         /// <summary>
     9         /// 判断注册信息节点是否存在
    10         /// </summary>
    11         /// <param name="key">"SOFTWARE\Microsoft"格式</param>
    12         /// <returns></returns>
    13         public static bool IsJudgeNode(string key)
    14         {
    15             return (Registry.CurrentUser.OpenSubKey(key) != null);
    16         }
    17 
    18         /// <summary>
    19         /// 判断注册表节点内是否有某个KEY
    20         /// </summary>
    21         /// <param name="key">"SOFTWARE\Microsoft"格式</param>
    22         /// <param name="prop">传入属性的键值</param>
    23         /// <returns></returns>
    24         public static bool IsJudgeNodeKey(string key, string prop)
    25         {
    26             RegistryKey rsg = Registry.CurrentUser.OpenSubKey(key, true);
    27             if (rsg != null)
    28             {
    29                 var obj = rsg.GetValue(prop);
    30                 if (obj != null)
    31                 {
    32                     return true;
    33                 }
    34             }
    35             return false;
    36         }
    37 
    38         /// <summary>
    39         /// 删除指定节点指定键值
    40         /// </summary>
    41         /// <param name="key"></param>
    42         /// <param name="prop"></param>
    43         public static void DeleteNodeKey(string key, string prop)
    44         {
    45             RegistryKey rKey = Registry.CurrentUser;
    46             RegistryKey software = rKey.OpenSubKey(key, true);
    47             //删除
    48             software.DeleteValue(prop);
    49             //完成读取和修改数据后,应关闭该键
    50             software.Close();
    51         }
    52 
    53         #endregion
    54     }

    这个地方使用Registry和 RegistryKey类,这两个类在 using Microsoft.Win32(命名空间提供两种类型的类:处理由操作系统引发的事件的类和操作系统注册表的类。)下,RegistryKey类可以用于完成对注册表的所有操作,Registry是不能实例化的一个类。它的作用只是提供表示顶级键的RegistryKey实例,以便开始在注册表中浏览。Registry是通过静态属性来提供这些实例的,这些属性共有7个,分别是ClassesRoot、CurrentConfig、CurrentUser、DynData、LocalMachine、PerformanceData和 Users。

    如何在注册表的给定位置上打开一个注册表项?Registry类没有用户可以使用的公共构造函数,也没有任何可以直接通过键的名称来访问键的方法。但可以在相关的巢中从上至下浏览该键。如果要实例化一个RegistryKey对象,惟一的方式是从Registry的静态属性开始,向下浏览。例如,要读取HKLM/Software/Microsoft键中的一些数据,可以使用下面的代码获得它的一个引用:

    1 RegistryKey hklm = Registry.LocalMachine;
    2 RegistryKey hkSoftware = hklm.OpenSubKey("Software");
    3 RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft");
    View Code

    以上述方式访问注册表项是只读访问。如果要写入该键(包括写入其值,或创建和删除其子键),就需要使用OpenSubKey的另一个重写方法,该方法的第二个参数是bool类型,表示是否要对该键进行读写访问。例如,如果要修改Microsoft键(并假定用户是一个系统管理员,有修改该键的许可),就应编写如下代码:

    1 RegistryKey hklm = Registry.LocalMachine;
    2 RegistryKey hkSoftware = hklm.OpenSubKey("Software");
    3 RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft", true);
    4 
    5 
    6 //创建Key
    7 RegistryKey hkMine = hkSoftware.CreateSubKey("MyOwnSoftware");

    CreateSubKey()工作的方式:如果键不存在,它就创建这个键。但如果键已经存在,它就会返回一个表示该键的RegistryKey实例。这个方法采用这样的工作方式的原因是用户总是可以使用这个键。注册表包含长期数据,例如Windows和各种应用程序的配置信息。因此用户并不需要经常显式地创建键。

    更常见的是,应用程序需要确保某些数据在注册表中是存在的。换言之,如果这些数据不存在,就要创建相关的键,但如果它们存在,就不需要做任何事。CreateSubKey()就可以完成这项任务。CreateSubKey()不会删除任何数据。如果要删除注册表项,就需要显式调用RegistryKey.Delete()方法,因此注册表对于Windows是非常重要的。如果删除了一些重要的键,就会中断Windows的执行,此时就需要调试C#注册表调用了

    定位了要读取或修改的注册表项后,就可以使用SetValue() 或 GetValue()方法设置或获取该键中的值。这两个方法的参数都是一个字符串,其中字符串给出了值的名称,SetValue()还需要一个包含值的信息的对象引用。这个参数定义为对象引用,实际上可以是任何一个类的引用。SetValue()根据所提供的类的类型,确定把值设置为REG_SZ、REG_DWORD,还是 REG_BINARY。例如:

    1 RegistryKey hkMine = HkSoftware.CreateSubKey("MyOwnSoftware");
    2 hkMine.SetValue("MyStringValue", "Hello World");
    3 hkMine.SetValue("MyIntValue", 20);

    这段代码设置键包含两个值:MyStringValue的类型是REG_SZ,而MyIntValue的类型是REG_DWORD,这里只考虑这两种类型,在后面的示例中会使用它们。

    RegistryKey.GetValue()的工作方式也是这样。它返回一个对象引用,如果该方法检测到值的类型为REG_SZ,就返回一个字符串引用,如果值的类型为REG_DWORD,就返回一个int型值。

    但是注意:Unity中写using Microsoft.Win32空间后,如果提示Win32API不存在。

    解决方案:

    1.右击资源管理器窗口中项目的引用文件夹,选择添加引用,选择.Net选项卡

    2.新建VS文件,以DLL库的形式使用。

    我这就是使用的dll库形式引用的。到这就解决了上述问题。

    ok,欢迎交流指正。

  • 相关阅读:
    向MyEclipse添加Oracle数据库
    如何让搜索引擎抓取AJAX内容?
    XCode常用快捷键
    VMware Workstation 9上安装Mac OS X 10.8
    IOS学习第一篇——利用Xcode中的Interface Builder创建Hello World示例
    FM 101.7
    SqlServer游标操作
    添加COOKIE
    c#活动目录操作
    WCF服务调用方式
  • 原文地址:https://www.cnblogs.com/answer-yj/p/11654918.html
Copyright © 2011-2022 走看看