How can I roll-back a ClickOnce application?

2019-01-16 05:06发布

Is there a way (hacky will do) to allow a user to go back to a previous version of a ClickOnce network deployed application?

I've looked in the docs and API and there seems to be no way. You can selectively choose if you would like to update, but once updated there is, seemingly, no way back.

标签: clickonce
9条回答
劳资没心,怎么记你
2楼-- · 2019-01-16 05:43

If you look at your deployment location, you'll see every previous version, in a separate folder with the version number appended, as well as the deployment manifest, also with the version number appended.

You can rename any one of them to be the current deployment, and the next time you update that application, it'll pull in the version you rolled-back to.

查看更多
我只想做你的唯一
3楼-- · 2019-01-16 05:44

You can go in Add/Remove application and select your application and choose to get the last installation instead.

查看更多
唯我独甜
4楼-- · 2019-01-16 05:44

This can be done via reflection if you know the publisher URI and the name, version language public key token and processor architecture of both the deployment and the application.

The below code will try to rollback the "coolapp.app" ClickOnce application. If it can't roll back, it will try to uninstall it.

using System;
using System.Deployment.Application;
using System.Reflection;

namespace ClickOnceAppRollback
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            string appId = string.Format("{0}#{1}, Version={2}, Culture={3}, PublicKeyToken={4}, processorArchitecture={5}/{6}, Version={7}, Culture={8}, PublicKeyToken={9}, processorArchitecture={10}, type={11}",
                /*The URI location of the app*/@"http://www.microsoft.com/coolapp.exe.application",
                /*The application's assemblyIdentity name*/"coolapp.app",
                /*The application's assemblyIdentity version*/"10.8.62.17109",
                /*The application's assemblyIdentity language*/"neutral",
                /*The application's assemblyIdentity public Key Token*/"0000000000000000",
                /*The application's assemblyIdentity processor architecture*/"msil",
                /*The deployment's dependentAssembly name*/"coolapp.exe",
                /*The deployment's dependentAssembly version*/"10.8.62.17109",
                /*The deployment's dependentAssembly language*/"neutral",
                /*The deployment's dependentAssembly public Key Token*/"0000000000000000",
                /*The deployment's dependentAssembly processor architecture*/"msil",
                /*The deployment's dependentAssembly type*/"win32");

            var ctor = typeof(ApplicationDeployment).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(string) }, null);
            var appDeployment = ctor.Invoke(new object[] { appId });

            var subState = appDeployment.GetType().GetField("_subState", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(appDeployment);
            var subStore = appDeployment.GetType().GetField("_subStore", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(appDeployment);
            try
            {
                subStore.GetType().GetMethod("RollbackSubscription").Invoke(subStore, new object[] { subState });
            }
            catch
            {
                subStore.GetType().GetMethod("UninstallSubscription").Invoke(subStore, new object[] { subState });
            }
        }
    }
}
查看更多
登录 后发表回答