针对Windows 7中的注册表操作限制的解决方法?

leo*_*leo 0 .net windows security uac windows-7

好的,因为在xp中大多数人都是以管理员身份登录的 - 程序员很容易使程序与注册表一起工作.我想要做的是这样的:

软件启动并作为启动过程添加到注册表中 - 但是这应该仅在应用程序关闭时才进行 - 而不是之前.

然而,当用户受限并且在vista,7,2008中同样的事情时,这在xp中不起作用.

解决方法有哪些?我想让程序创建一个计划任务或附加到具有更高权限的进程?任何工作方式?我将它标记为.net,因为我的软件是.net相关的 - 实际上同样的事情发生在c ++中 - 但我暗地希望网络提供更简单的方法来解决它.提前10倍!

Cod*_*ray 6

嗯,这不是Windows 7 的限制 ; 它实际上是按设计的.有关详情,请参阅我的回答.

您需要的是进程提升.这是处理此问题的标准方法,UAC内置的一种机制允许用户将自己身份验证为管理员,并暂时获得此标题带来的所有特权和职责.Windows本身在整个地方使用它:

Windows UI中显示的高程屏蔽示例

这里有一篇精彩的how-to文章: .NET中的Shield图标,UAC和进程提升.
但只是总结链接腐烂的情况,这里是步骤:

  1. 确定用户是否已具有适当的权限.最简单的方法是调用IsUserAnAdminAPI函数.

  2. 使用"屏蔽"图标通知用户需要提升.在WinForms中,您需要将按钮的FlatStyle属性设置为"System",并使用P/Invoke显示屏蔽.示例代码:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, int Msg,
                                            IntPtr wParam, IntPtr lParam);
    
    public const int BCM_SETSHIELD = 0x0000160C;
    
    public static void SetButtonShield(Button btn, bool showShield)
    {
        // Verify that we're running on Vista or later
        if ((Environment.OSVersion.Platform == PlatformID.Win32NT) &&
            (Environment.OSVersion.Version.Major >= 6))
        {
            SendMessage(btn.Handle, BCM_SETSHIELD, IntPtr.Zero,
                        showShield ? new IntPtr(1) : IntPtr.Zero);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用管理员权限重新启动该进程.这涉及显示提升对话框以允许用户提升程序.示例代码:

    ProcessStartInfo psi = new ProcessStartInfo
                               {
                                   Arguments = "-justelevated",
                                   ErrorDialog = true,
    
                                   // Handle is the handle for your form
                                   ErrorDialogParentHandle = Handle,
                                   FileName = Application.ExecutablePath,
                                   Verb = "runas"
                               };
    try
    {
        Process.Start(psi);
        Close();
    }
    catch (Exception ex)
    {
        // the process couldn't be started. This happens for 1 of 3 reasons:
    
        // 1. The user cancelled the UAC box
        // 2. The limited user tried to elevate to an Admin that has a blank password
        // 3. The limited user tries to elevate as a Guest account
        MessageBox.Show(ex.Message);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. [可选] 代码在您的应用程序中签名,以使用更令人愉悦的灰色或蓝色升级框来替换看起来像敌对的黄色UAC高程框.