2つの異なる場所に展開されているWindowsフォームアプリケーションがあります。
クリックワンスでデプロイされたバージョンApplicationDeployment.IsNetworkDeployed
のClickOnceバージョン番号を表示します。
if (ApplicationDeployment.IsNetworkDeployed)
return ApplicationDeployment.CurrentDeployment.CurrentVersion;
しかし、非クリックアプリケーションの場合、アセンブリ情報でバージョン番号をハードコーディングしない限り、clickonceバージョンを取得する方法がわかりません。
Clickonce以外のデプロイ済みバージョンのClickOnceバージョン番号を自動的に取得する方法はありますか?
いいえ、方法があるとは思いません。 ClickOnce情報は、ClickOnce展開でのみ使用できるマニフェストから取得されると考えています。バージョン番号をハードコーディングするのが最善の選択肢だと思います。
System.Deployment
へのアセンブリ参照をプロジェクトに追加します。
クラスファイルに名前空間をインポートします:
VB.NET:
Imports System.Deployment
C#:
using System.Deployment;
CurrentVersion
プロパティからClickOnceバージョンを取得します。
ApplicationDeployment.CurrentDeployment.CurrentVersion
プロパティから現在のバージョンを取得できます。これは System.Version
オブジェクトを返します。
注(MSDNから):
CurrentVersion
は、新しいアップデートがインストールされているが、UpdatedVersion
をまだ呼び出していない場合、Restart
とは異なります。展開マニフェストが自動更新を実行するように構成されている場合、これら2つの値を比較して、アプリケーションを再起動する必要があるかどうかを判断できます。
注:CurrentDeployment
静的プロパティは、アプリケーションがClickOnceで展開されている場合にのみ有効です。したがって、このプロパティにアクセスする前に、最初にApplicationDeployment.IsNetworkDeployed
プロパティを確認する必要があります。デバッグ環境では常にfalseを返します。
VB.NET:
Dim myVersion as Version
If ApplicationDeployment.IsNetworkDeployed Then
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion
End If
C#:
Version myVersion;
if (ApplicationDeployment.IsNetworkDeployed)
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
Version
オブジェクトを使用:
ここから、ラベル内のバージョン情報を、「About」フォームで次のように使用できます。
VB.NET:
versionLabel.Text = String.Concat("ClickOnce published Version: v", myVersion)
C#:
versionLabel.Text = string.Concat("ClickOnce published Version: v", myVersion);
(Version
オブジェクトは4部構成の数値(major.minor.build.revision)としてフォーマットされます。)
新しいバージョンを出すたびに、メインアセンブリのアセンブリバージョンをCLickOnceバージョンと同じにします。次に、clickonce以外のアプリケーションとして実行する場合は、Reflectionを使用してAssemblyバージョンを取得します。
スレッド検証を試してください:
if (ApplicationDeployment.IsNetworkDeployed)
{
if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion)
{
Application.ExitThread();
Application.Restart();
}
}
3年後に問題になるわけではありませんが、XMLリーダーでマニフェストファイルを解析するだけになりました。
ハードコード、または...データベース内のバージョン(ファイル、アセンブリ、デプロイ)を追跡します。アセンブリを使用してデータベースを呼び出し、Deployバージョンを取得します。
これは、各バージョンタイプに関係があるように、論理的な方法でバージョンを増やしていることを前提としています。このような小さな問題には多くの作業が必要です。私は個人的にJaredのソリューションを使います。ハードコーディングは嫌いですが。
RobinDotNetのソリューションを拡張するには:
ヒント:ビルドするたびに、.csprojファイルのMSBuild構成内からプログラムまたはスクリプトを自動的に実行してこれを行うことができます。私が現在管理している1つのWebアプリケーションでこれを行い、Cygwin bashシェルスクリプトを実行してバージョン管理h4xを実行し、Git履歴からバージョン番号を計算し、ビルド出力にコンパイルされたアセンブリ情報ソースファイルを前処理します。
プロジェクトファイルからClickOnceバージョン番号、つまりProject.PropertyGroup.ApplicationRevision
およびProject.PropertyGroup.ApplicationVersion
を解析するために同様のことができます(バージョン文字列の意味はわかりませんが、壊れて修正するまで推測できます)。そのバージョン情報をアセンブリ情報に追加します。
ClickOnceバージョンがいつバンプされるかはわかりませんが、おそらくビルドプロセスの後です。新しいソリューションをコンパイルするには、このソリューションをいじる必要があるかもしれません。I常に/*h4x*/ +1
があると思います。
Cygwinを使用したのは、* nixスクリプトがWindowsよりもはるかに優れており、コードを解釈することで、ビルド前にビルド前のプログラムをビルドする手間が省けるためですが、何でもプログラムを記述できます必要なテクノロジー(C#/。NETを含む)。プリプロセッサのコマンドラインはPreBuildEvent
内にあります。
<PropertyGroup>
<PreBuildEvent>
$(CYGWIN_ROOT)bin\bash.exe --login -c refresh-version
</PreBuildEvent>
</PropertyGroup>
ご想像のとおり、これはビルド段階の前に行われるため、ソースコードをコンパイルする直前に効果的に前処理できます。 Properties\AssemblyInfo.cs
ファイルを自動的に編集したくないので、安全にプレイするために、バージョン情報を持つクラスのテキストテンプレートを含み、プロジェクト設定でProperties\VersionInfo.base.cs
としてマークされたBuildAction=None
ファイルを作成しました。プロジェクトでコンパイルされたt:
using System.Reflection;
using EngiCan.Common.Properties;
[Assembly: AssemblyVersion("0.$REVNUM_DIV(100)$.$REVNUM_MOD(100)$.$DIRTY$")]
[Assembly: AssemblyRevisionIdentifier("$REVID$")]
(いくつかの追加のh4xがスローされたWindowsの環境変数に似た非常に汚い、貧乏人のプレースホルダー構文が、単純さ/複雑さのために使用されました)
AssemblyRevisionIdentifierAttribute
は、a.b.c.dよりも開発者にとってはるかに意味があるため、Git SHA1を保持するために作成したカスタム属性でした。
私のrefresh-version
プログラムは、そのファイルをProperties\VersionInfo.cs
にコピーし、既に計算/解析されたバージョン情報の置換を行います(置換にsed(1)
を使用しました。これはCygwinを使用する別の利点でした)。 Properties\VersionInfo.cs
がプログラムにコンパイルされました。このファイルは空で開始できますが、バージョン管理システムでは無視する必要があります。ファイルは自動的に変更され、生成する情報はすでに他の場所に保存されているためです。
スレッド検証を行い、ハードコードを挿入...
ビルドコンポーネントを使用すると、プロジェクトファイルからワンクリックバージョンを読み取り、アセンブリ情報に自動的に書き込むことができるため、両方が同期します。