zoukankan      html  css  js  c++  java
  • ClickOnce管理员启动并且支持ClickOnce更新

    ClickOnce管理员启动并且支持ClickOnce更新

    开发需求:WPF应用通过ClickOnce发布应用,且必须通过管理员权限启动应用,提供手动检测更新功能。

    在做WPF开发的时候,我们知道使用ClickOnce打包发布应用,方便应用更新管理,ClickOnce在打包时只要设置更新策略就可以正常使用更新功能。但是加上管理员权限这样就行不通了,有什么解决方案呢?

    经过多番资料查询,终于在一个帖子中找到了解决方案。

    首先,我们来看看通过管理员启动的代码。在Application的OnStartup方法中调用如下代码即可管理员权限启动ClickOnce应用。

    private void CheckAdministrator()
    {
        var wi = WindowsIdentity.GetCurrent();
        var wp = new WindowsPrincipal(wi);
        bool runAsAdmin = wp.IsInRole(WindowsBuiltInRole.Administrator);
        if (!runAsAdmin)
        {
            var processInfo = new ProcessStartInfo(Assembly.GetExecutingAssembly().CodeBase)
            {
                UseShellExecute = true,
                Verb = "runas",
                Arguments = StartFlag
            };
            try
            {
                Process.Start(processInfo);
            }
            catch (Exception ex)
            {}
            Environment.Exit(0);
        }
    }
    

    但是为什么ClickOnce更新功能会失效呢?

    看Assembly.GetExecutingAssembly().CodeBase这段代码,实际上是获取了ClickOnce应用的exe文件地址,这样直接启动exe就会导致ApplicationDeployment.IsNetworkDeployed=false,认为应用不是ClicKOnce应用,故而ClickOnce更新功能失效。

    接下来,就解决更新失效的问题。根据上面的blog得知,在使用管理员权限启动应用后,再通过appref-ms启动即可兼得管理员权限和ClickOnce更新功能。

    实际上App会启动三次,第一次用户点击快捷方式进入应用,此时会进行管理员权限启动应用(即第二次启动),看CheckAdministrator代码中ProcessInfo参数,其中Arguments设置了一个Flag标识,第二次启动后由于StartupEventArgs参数中Args包含了Flag标识,那么此时通过appref-ms进行第三次启动,并退出当前进程。

    经过如上操作,第三次启动的应用同时兼具了管理员权限和ClickOnce的功能。

    private void App_Startup(object sender, StartupEventArgs e)
    {
        if (e.Args != null && e.Args.Length > 0 && (e.Args[0].Equals(StartFlag)))
        {
            var flag = e.Args[0];
            if(StartFlag.Equals(flag))
            {
                StartAppAgain();
            }
            Environment.Exit(0);
        }
        else
        {
            CheckAdministrator();
        }
    }
    

    通过appref-ms启动代码如下,重点是如何得到appref-ms的路径。

    private void StartAppAgain()
    {
        string publisherName = System.Windows.Forms.Application.CompanyName;
        string productName = System.Windows.Forms.Application.ProductName;
        string allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
        string shortcutPath = Path.Combine(allProgramsPath, publisherName);
        shortcutPath = Path.Combine(shortcutPath, productName) + ".appref-ms";
        try
        {
            Process.Start(shortcutPath);
        }
        catch (Exception ex)
        {}
    }
    
  • 相关阅读:
    JAVASCRIPT首页广告轮流显示
    ASP.NET (C#) 面试笔试题目收集
    ASP 按修改时间读取文件夹中文件并且排序
    CSS Body宽度和高度
    ASP.NET页面间的传值的几种方法(总结)
    IFRAME高度自适应——框架高度等于其页面高度
    ActionScript 3.0 Step By Step系列(八):动态的数据展现源于灵活的数据绑定
    ActionScript 3.0 Step By Step系列(五):走在面向对象开发的路上,以类为基础去思考编程问题
    ActionScript 3.0 Step By Step系列(四):来自面向对象开发之前的呐喊:“学会写可重用的代码”
    ActionScript 3.0 Step By Step系列(九):使用样式(style)和皮肤(Skin)两大画笔为应用程序界面画妆
  • 原文地址:https://www.cnblogs.com/devin_zhou/p/9804987.html
Copyright © 2011-2022 走看看