Shelf Life(使用期限)チェックは、アプリケーションが特定の日付より後も実行されていないかどうかを検出するタイプのチェックです。 このチェックにより、アプリケーションは Shelf Life、つまり限られた期間のみ実行できるようになります。
Shelf Life チェックはベータ版、つまり評価版のソフトウェアで特に役立ちます。 ユーザーが有効期限を過ぎてアプリケーションを実行しようとした場合、Shelf Life チェックはこれを検出し、アプリケーションに通知したり、アプリケーションを終了したりして対応することができます。 つまり、Shelf Life チェックは現在の日付に基づいて、アプリケーションの不正な使用を検出して対応します。
Shelf Life チェックの構成
Dotfuscator Professional でアプリケーションに Shelf Life チェックを差し込むには、まず PreEmptive Solutions から Shelf Life Activation Key を入手する必要があります。
アクティブ化キーを入手したら、チェックを有効にします。 次に、構成エディターを使用するか、ShelfLifeCheckAttribute
を使ってソース コードにアノテーションを付けることにより、チェックを構成します。 これらのどちらの方法でも、チェックの動作を決めるさまざまなプロパティを指定できます。詳細な一覧については、「チェック属性」ページの ShelfLifeCheckAttribute
セクションを参照してください。
アクティブ化キー
Shelf Life Activation Key は、Shelf Life チェックを差し込むために必要なデータ ファイルです。 アクティブ化キーを入手するには、PreEmptive Solutions にご連絡ください。
アクティブ化キーが発行されたら、そのキー ファイルのパスを各 Shelf Life チェックの ActivationKeyFile プロパティに指定する必要があります。 アクティブ化キーのコピーを各ビルド マシンに保管することをお勧めします。
アクティブ化キーは、アプリケーションが Dotfuscator で処理されるときにのみ必要となります。 アプリケーションは実行時にアクティブ化キーにアクセスする必要はないため、アクティブ化キーを開発組織外に配布しないでください。
トークン
Shelf Life トークンは、有効期限など、アプリケーションの使用期限に関する情報を含んでいるファイルです。 Dotfuscator は、期限切れ情報をアプリケーションに直接埋め込むのではなく、この情報を含むトークンを生成します。 Shelf Life チェックは、実行時にこのトークンを使用して、アプリケーションの有効期限が切れているかどうかを判断します。
Dotfuscator Professional では、Shelf Life チェックにトークンを提供する方法は 2 つあります。
-
チェックを使ってトークンをアプリケーションに埋め込む。 こちらの方法は他の方法より便利ですが、アプリケーションの出荷後にトークン(したがって有効期限)を変更、カスタマイズすることはできません。
-
独立したトークンを生成し、それを実行時にチェックに提供する。 たとえば、Web サービスを使ってトークンをアプリケーションに提供する場合は、アプリケーションを再配布せずにトークンを変更できるので、有効期限を延長したりユーザー別の有効期限を作成したりすることができます。
どちらの方法を使用する場合でも、公開/秘密キー ペアを使うことで、トークンの信頼性を保証することもできます。 トークンには公開キーが含まれます。トークンは生成された後に秘密キーで署名されます。 Shelf Life チェックは実行時に、この署名が公開キーと一致するかどうかを検証します。 これにより、ある種の有効期限操作が防止され、トークンが変更されていないことが保証されます。
チェックによるトークンの埋め込み
Dotfuscator は Shelf Life チェックを使って、自動的にトークンを生成して埋め込むことができます。 2 つのオプションのうち、簡単なのはこちらの方法です。
これを実行するには、チェックを構成する際に、チェックの ExpirationDate プロパティと WarningDate プロパティ(任意)に値を指定します。 生成されたトークンに署名したい場合は、PrivateKeyFile プロパティと、必要に応じて PrivateKeyFilePassword プロパティにも値を指定します。 Shelf Life チェックのこれらのプロパティと他のプロパティの詳細については、「チェック属性」ページの ShelfLifeCheckAttribute
セクションを参照してください。
独立したトークンの生成
先のオプションとは対照的に、トークンを手動で生成し、アプリケーションを実行することで Shelf Life チェックにそのトークンを提供することもできます。 こうすることで、たとえば、アプリケーションでアクセスするデータベースや Web サービスにトークンを格納できます。 アプリケーションを再配布せずに提供されたトークンを変更できるので、有効期限を延長したりユーザー別の有効期限を作成したりすることができます。
手動でトークンを生成する手順の詳細については、新しい Shelf Life トークンの生成セクションを参照してください。
実行時に、チェックにトークンを動的に取得させるようにするには、チェックの構成時に ShelfLifeTokenSource プロパティの値を指定します。 これらの値は、トークンを文字列
として提供する、アプリケーション コード内のソースを指定するものです。 Shelf Life チェックのこれらのプロパティと他のプロパティの詳細については、「チェック属性」ページの ShelfLifeCheckAttribute
セクションを参照してください。
有効期限と警告日付
各 Shelf Life トークンは、関連する有効期限を持っています。 トークンを使用する Shelf Life チェックの実行では、(単にシステム時間をチェックするより複雑なアルゴリズムを使って)有効期限と現在の日時を比較します。 有効期限が過去の日付になっていたら、アプリケーションは期限切れであると判断されます。 アプリケーションが期限切れの場合に行われる動作は、アプリケーション通知のプロパティによって異なります。
各 Shelf Life トークンには、任意で警告日付を指定することもできます。 トークンを使用する Shelf Life チェックの実行では、警告日付が過去の日付になっていたら、アプリケーションは警告期間に入っていると判断されます。 アプリケーションが警告期間内にある場合に行われる動作は、アプリケーション通知のプロパティによって異なります。
Shelf Life チェックにより埋め込まれるトークンの場合、有効期限と警告日付はそれぞれ、チェックの ExpirationDate および WarningDate プロパティで指定されます。 実行時に提供されるトークンの場合、有効期限と警告日付は、トークンの生成時に指定されます。
Shelf Life トークンの日付は文字列として、次の 2 つの書式のいずれかで設定されます。
-
絶対日付。
YYYY-MM-DD
書式の日付 -
相対日付。Dotfuscator によりトークンが生成された日付からその日付までの日数を表す整数
たとえば、Dotfuscator によりトークンが生成された日付が 2017 年 8 月 1 日で、アプリケーションの有効期限を 2017 年 8 月 31 日とする場合には、有効期限は 2017-08-31
または 30
と記述することができます。
アプリケーション通知
Shelf Life チェックに関するアプリケーション通知は、他の種類のチェックに関するアプリケーション通知とはやや異なっています。
通知の種類
Shelf Life チェック以外のチェックでは、不正なアプリケーションの状態が検出されたかどうかを示す 1 つの通知のみが提供されるのに対し、Shelf Life チェックでは次の 2 つの通知を行うことができます。
-
期限切れ通知:アプリケーションが期限切れである(つまり、有効期限後も実行されている)かどうかをアプリケーション コードに通知します。
-
この通知は、チェックが実行されるたびに、アプリケーションの期限が切れている場合も、警告期間に入っている場合も、そのどちらでもない場合も、常に使用されます。
-
Shelf Life チェックの以下のプロパティは、期限切れであるかどうかをアプリケーションに通知する方法を設定するものです。
- ExpirationNotificationSinkElement
- ExpirationNotificationSinkName
- ExpirationNotificationSinkOwner
-
これらのプロパティは、
ブール
値を受け取るアプリケーション コード内のシンクを指定します。アプリケーションが期限切れの場合にはtrue
、期限切れでない場合にはfalse
を受け取ります。
-
-
警告通知:アプリケーションが警告期間に入っている(つまり、警告日付後に実行されている)かどうかをアプリケーション コードに通知します。
-
この通知は、チェックに警告日付が指定されていない場合にはスキップされますが、指定されている場合には、期限切れ通知と同様に、チェックが実行されるたびに使用されます。
-
Shelf Life チェックの以下のプロパティは、警告期間に入っているかどうかをアプリケーションに通知する方法を設定するものです。
- WarningNotificationSinkElement
- WarningNotificationSinkName
- WarningNotificationSinkOwner
-
これらのプロパティは、
ブール
値を受け取るアプリケーション コード内のシンクを指定します。アプリケーションが警告期間に入っている場合にはtrue
、入っていない場合にはfalse
を受け取ります。
-
文字列シンクの使用
通知では、前のサブセクションで指定したブール
シンクの代わりに、void(string, string)
署名付きのメソッドまたはデリゲートの Method、Delegate、または MethodArgument シンクを使用することもできます。 このような場合、Shelf Life チェックは次の 2 つのパラメーターを指定してメソッドまたはデリゲートを呼び出します。
- 警告日付(警告日付を指定しない場合は、
Null
) - 有効期限
これにより、アプリケーション コードで、有効期限をユーザーに表示するなど、より具体的に対応できるようになります。
文字列
シンクはブール
シンクと同様に、アプリケーションが警告期間内でなくても、期限切れでなくても呼び出されます。 ただし、警告通知のシンクは、警告日付が指定されていなければ呼び出されません。
期限切れ通知と警告通知はどちらも同じ引数を指定して文字列
シンクを呼び出すため、両方の通知を文字列
シンクとして指定する必要はありません。 2 つの通知のうち、一方で文字列
シンクを使用し、もう一方でブール
シンクを使用することができます。
たとえば、次のような Shelf Life チェックおよびコードの一部が含まれている評価版ソフトウェアについて考えます。
internal class ShelfLifeApplicationNotificationExample
{
private bool applicationHasExpired; // set by Shelf Life Check
internal void SetupApplication()
{
LoadDataFiles();
EnableFreeFeatures();
if (!applicationHasExpired)
{
EnablePaidFeatures();
}
}
private void LoadDataFiles() // location of Shelf Life Check
{
Console.WriteLine("Simulating startup logic...");
}
// EnableFreeFeatures() and EnablePaidFeatures() omitted for brevity
// called by Shelf Life Check
private void LogEvaluationNotice(string warnDateString, string expireDateString)
{
// Use arguments directly as strings...
Console.WriteLine($"This evaluation software has an expiration date of {expireDateString}.");
Console.WriteLine("To purchase the full version, please contact <sales@example.com>.");
// ...or parse to DateTime objects for calculations.
DateTime warnDate = DateTime.Parse(warnDateString);
DateTime expireDate = DateTime.Parse(expireDateString);
int daysUntilWarn = warnDate.Subtract(DateTime.Today).Days;
int daysUntilExpire = expireDate.Subtract(DateTime.Today).Days;
if (daysUntilExpire <= 0)
{
Console.WriteLine("WARNING: The software has expired.Paid features are no longer available.");
}
else if (daysUntilWarn <= 0)
{
Console.WriteLine($"WARNING: The software will expire in {daysUntilExpire} days.");
}
}
}
Dotfuscator による差し込みの後、別のアプリケーション コードによって SetupApplication()
が呼び出されると、以下の処理が行われます。
-
SetupApplication()
がLoadDataFiles()
を呼び出します。 -
LoadDataFiles()
が実行される前に、Shelf Life チェックは以下のことを行います。-
アプリケーションは期限切れになったか、警告期間に入ったか、またはそのいずれでもないかどうかを判断します。
-
警告通知として
LogEvaluationNotice(string, string)
メソッドを呼び出し、2 つの string(文字列)として警告日付と有効期限を渡します。 -
LogEvaluationNotice(string, string)
は、評価版ソフトウェアに関する情報をコンソールに書き込み、チェックに制御を返します。 -
期限切れ通知として
applicationHasExpired
フィールドを設定します。アプリケーションの期限が切れていればtrue
に、切れていなければfalse
に設定します。 -
チェックの実行を終了し、
LoadDataFiles()
メソッドに制御を返します。
-
-
LoadDataFiles()
メソッドが実行され、SetupApplication()
に制御を返します。 -
SetupApplication()
がEnableFreeFeatures()
を呼び出し、後者からSetupApplication()
に制御が返されます。 -
applicationHasExpired
がfalse
である(つまり、評価版ソフトウェアの期限が切れている)場合は、SetupApplication()
がEnablePaidFeatures()
を呼び出し、後者からSetupApplication()
に制御が返されます。 -
SetupApplication()
が呼び出し元に制御を返します。
終了の動作
Shelf Life チェックでは、チェック操作はサポートされていません。 Shelf Life チェックの ExpirationNotificationSinkElement プロパティを DefaultAction に設定することで、"Exit" 操作を使用するのと同等の構成を行うことができます。
このように構成された Shelf Life チェックが期限切れのアプリケーションの使用を検出した場合、アプリケーションは終了コード 0 で直ちに終了します。
サポートされないアプリケーションの種類
Dotfuscator は、以下に挙げる .NET アセンブリ以外のすべての .NET アセンブリに Shelf Life チェックを差し込むことができます。
- ネイティブ コードおよびマネージ コードを含んでいる Managed C++ アセンブリ
- マルチ モジュール アセンブリ
- .NET Core アセンブリ
- .NET 5 アセンブリ
- UWP アセンブリ
- Xamarin アセンブリ
- MAUI アセンブリ
テスト
アプリケーションに差し込まれた Shelf Life チェックが、アプリケーションの期限切れ後の使用や警告期間中の使用に対応する動作をテストするためのもっとも簡単な方法は、過去の有効期限や警告日付を使ってそのチェックを一時的に構成することです。 必ず Shelf Life チェックのすべての場所を試してください。 テストの結果、アプリケーションが期限切れになったり警告期間に入っている場合に予期したとおりに動作していることを確認できたら、有効期限または警告日付を必要な値に変更したうえでアプリケーションをビルドして配布する必要があります。