web-dev-qa-db-ja.com

ClickOnceアプリケーションをロールバックするにはどうすればよいですか?

ユーザーが以前のバージョンの ClickOnce ネットワークにデプロイされたアプリケーションに戻ることを許可する方法(ハッキーは行います)はありますか?

私はドキュメントとAPIを調べましたが、方法がないようです。君は できる 更新するかどうかを選択的に選択しますが、更新すると、元に戻す方法がないようです。

47
Jan Bannister

ClickOnceは、送信したバージョンを使用します。古いバージョンを送信すると、古いバージョンにロールバックされます。

5月に、私の仲間のDavidがユーザーごとにこれを行う方法についての記事を書きました。文字通り、すべてのユーザーを異なるバージョンにすることができます。アプリケーションは、ユーザーが必要とするバージョンをデータベースに通知することもできるため、理論的にはユーザーがバージョンを変更してから、アプリケーションを再起動するだけで済みます。

ClickOnceを使用した細かいバージョン管理

18
Jonathan Allen

サーバーマニフェストファイルを変更することにより、サーバー側で以前のバージョンに戻すことができます。クライアントがアプリケーションを再起動すると、サーバーの「現在の」バージョンとは異なるバージョンであることがわかり、新しいバージョンがダウンロードされます。通常、このサーバーマニフェストファイルは常に最新バージョンを指しますが、そうである必要はありません。

これを変更する方法は次のとおりです(Visual Studio 2008を使用して公開しました。他のバージョンでは公開フォルダーの構造が異なる場合があります)。

Publish.htmと同じフォルダーに[appName].applicationと呼ばれる [〜#〜] xml [〜#〜] ドキュメントがあります。これは、クライアントが現在のバージョンと比較するために使用するサーバー側のマニフェストファイルです。このドキュメントには、クライアントが実行する必要がある「現在の」バージョンと、デプロイメントファイルを見つけることができるサーバー上の場所が含まれています。

publish.htmと同じ場所に、「アプリケーションファイル」というフォルダもあります。このフォルダーには、以前の各発行のサブフォルダーが含まれています。これらの各サブフォルダー内には、前述の[appName].applicationと同じ名前の別のXMLドキュメントがあります。このファイルを(元に戻すバージョンが含まれている任意のフォルダーから)コピーし、publish.htmと同じフォルダー(2つ上のレベル)に貼り付けます。クライアントアプリケーションが再起動すると、新しいバージョンが利用できるように表示され、ダウンロードして実行します。クライアントは以前のバージョンを実行します。

84
Jason Hornor

アプリケーションの追加と削除に移動し、アプリケーションを選択して、代わりに最後のインストールを取得することを選択できます。

8

[〜#〜] mageui [〜#〜] を使用して、サーバー上の以前のマニフェストバージョンにロールバックできます。 これをチェックしてください

2
Gulzar Nazim

これを使用して、Visual Studio 2017で開発されたクリックワンスアプリケーションをロールバックしました。私の場合、ルートフォルダーには2つのファイルしかありませんでした。 1つは[applicationName] .manifest、もう1つはsetup.exeです。

[applicationName] .manifestには、現在のバージョン番号への番号参照が含まれていましたが、それぞれがpublicKeyToken値にリンクされていたため、手動で編集するのは嫌でした。

したがって、Application Filesフォルダーで、ロールバックしたいバージョンが含まれているサブフォルダーの下に、別の[applicationName] .manifestが見つかりました。これをルートフォルダーにコピーしました(元のファイルをバックアップしています)。

そして、それはそれでした。それは私にとってはうまくいき、本当に簡単な解決策でした。ただし、最低限必要なバージョンを使用していないため、それが影響するかどうかはわかりません。

1
Jon Roberts

デプロイメントの場所を見ると、バージョン番号が追加された個別のフォルダー内のすべての以前のバージョンと、バージョン番号が追加されたデプロイメントマニフェストが表示されます。

それらのいずれか1つを現在のデプロイメントに名前変更することができ、次にそのアプリケーションを更新するときに、ロールバックしたバージョンがプルされます。

1
rjrapson

ClickOnceバージョンチェックのアルゴリズムを次のように理解しています。

  1. クライアントにインストールされているバージョン=サーバーにデプロイされているバージョンの場合-何もしない
  2. クライアントバージョン<サーバーバージョンの場合-アップグレード
  3. クライアントバージョン>サーバーバージョンの場合:
    1. クライアントで指定されたminimumVersion> =サーバーバージョンの場合-発生したエラーを表示
    2. クライアントで指定されたminimumVersion <サーバーバージョン-ダウングレードの場合
    3. クライアントでminimumVersionが指定されていない場合-ダウングレード
1

これは、発行元 [〜#〜] uri [〜#〜] と、デプロイメントとアプリケーションの両方の名前、バージョン言語の公開鍵トークン、およびプロセッサアーキテクチャがわかっている場合に、リフレクションを介して実行できます。

以下のコードは "coolapp.app" ClickOnce アプリケーションをロールバックしようとします。ロールバックできない場合は、アンインストールを試みます。

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 });
            }
        }
    }
}
0

私はライブの本番サーバーでこれらの1つを実行する必要があり、これらすべてのメモを用意できてよかったです。私のソリューションは少し異なっていたので、これも修正として追加したかったのです。本番環境での展開を行う前に、常に、含まれているフォルダ全体を常に事前にバックアップします。フォルダ構造全体を元の状態にコピーでき、すべてが正常に機能しました。

この方法での注意事項:

  • アプリケーションが非常に大きい場合、またはアプリケーションファイルフォルダーに既に公開されている多くのバージョンがある場合、バックアップは大きくなります。十分なスペースがあることを確認してください(私にとってストレージはオブジェクトではありません)。
  • アクセス許可は、この方法であなたを噛むという厄介な傾向があります。配置場所が外部アクセス用にホストされているかどうかを確認し、復元の前後にすべての権限を確認します。
  • [〜#〜] iis [〜#〜] でアプリケーションプールをリサイクルすると便利でした。
0
Mathew A.