none
C# 可否不弹出UAC RRS feed

  • 问题

  • 背景是这样的,客户企业给企业员工配备电脑但给予员工个人的帐号权限极低(不能访问注册表,不能安装软件),且员工电脑是Windows 7操作系统且开启UAC.

    我是开发人员,给客户企业开发了一个软件.

    为了安装,客户给了我一个管理员帐号.

    编程语言是:C# /.NET 2.0 / Console Application

    我的解决方案是在代码里用Impersonate Administrator 和Process.Start来执行操作,但是无论如何都无法绕开弹出UAC需要用户确认的对话框.

    代码和功能都没有问题, 想咨询的是如何能够在代码里控制不弹出UAC对话框? 

    过多的UAC弹出窗口让软件很不友好.


    2014年2月20日 9:59

答案

  • 绕不过,你应该想想是否有可能让你的业务逻辑绕过写注册表等需要管理员权限的操作,或者考虑这些操作是否可以通过第一次安装应用程序的时候来执行

    模拟没用,检测的是进程的权限,而不是 Identity,必须以管理员权限运行你的程序。

    在控制面板中调低 UAC 级别也没有用,所有代码会无错的执行,也不会弹出 UAC,但是需要管理员权限的代码不会实际的修改注册表值,但是却会告诉你执行成功。

    你或许可以告之一下你为什么需要在程序运行时修改注册表?

    2014年2月21日 1:20

全部回复

  • 你好,我有這個經驗,我的問題那時候是要regedit加進HKCU裡,但如果直接用regedit,每一個node都要問一次UAC。

    所以我寫了個WinForm Application,直接融入reg檔,再用.net code,便沒有UAC了。

    但如果你是想寫進HKLM,那便要Admin right的人去執行。


    大家一齊探討、學習和研究,謝謝!
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD,
    MCT, Microsoft Community Star(TW & HK),
    Microsoft MVP for VB.NET since 2003
    My MSMVP Blog


    2014年2月20日 11:15
  • 对,就是要写入到HKLM里

    我第一个解决方案是impersonate an administrator,然后在这个 administrator的 windows identity下面操作注册表

    这个测试无论如何调用API来Impersonate Admin都通不过.

    然后我用了第二个方法,我把注册表操作分离出来单独写了个Console Application里头就直接操作注册表HKLM项目

    然后主项目里Process.Start 的时候传入 管理员用户名和密码和域名 然后还是失败 ,虽然进程已经显示是由Admin用户启动执行.

    最后我在注册表Console Application里 自己启动的时候调用runas再调用自己一次,然后就能解决问题.

    问题就出在这一次runas调用自己,会导致弹出可恶 的UAC.

    static void GetAndDisplayRights()
            {
                WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
                bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator);
    
                if (!hasAdministrativeRight)
                {
                    RunElevated();
                }
            }
    
            static void RunElevated()
            {
                ProcessStartInfo processInfo = new ProcessStartInfo();
                processInfo.Verb = "runas";
                processInfo.FileName = Environment.GetCommandLineArgs()[0];
                //processInfo.Arguments = args;
                try
                {
                    Process.Start(processInfo);
    
                    Environment.Exit(0);
                }
                catch (Win32Exception)
                {
                    //Do nothing. Probably the user canceled the UAC window
                }
            }
    
    
            static void Main(string[] args)
            {
                try
                {
                    GetAndDisplayRights();
    
                   // some registry operations here
    
                    Environment.Exit(0);
                }
                catch(Exception ex)
                {
                    Trace.WriteLine(ex.Message);
    
                    ConsoleColor defaultColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Exception occurred. " + ex.Message);
                    Console.ForegroundColor = defaultColor;
                    Environment.Exit(-1);
                }
            }

    如何解决这个呢?


    • 已编辑 Shan Ke 2014年2月20日 15:23
    2014年2月20日 15:20
  • 绕不过,你应该想想是否有可能让你的业务逻辑绕过写注册表等需要管理员权限的操作,或者考虑这些操作是否可以通过第一次安装应用程序的时候来执行

    模拟没用,检测的是进程的权限,而不是 Identity,必须以管理员权限运行你的程序。

    在控制面板中调低 UAC 级别也没有用,所有代码会无错的执行,也不会弹出 UAC,但是需要管理员权限的代码不会实际的修改注册表值,但是却会告诉你执行成功。

    你或许可以告之一下你为什么需要在程序运行时修改注册表?

    2014年2月21日 1:20