アプリケーション自体がファイルの読み取り/書き込みを試行する場所を変更できないと仮定すると、次のオプションがあります。
- アプリケーションのインストーラーのデフォルトのインストール ディレクトリを変更して、C:\ProgramFiles 内ではなく、より緩いアクセス許可を持つ C:\ ドライブのすぐそばのフォルダーに移動します。これは、Windows 3.1 や Windows 95 でさえ標準的な方法でしたが、最近では、適切な Program Files ディレクトリにインストールしない限り、サポートされている Windows バージョンと互換性があるとして Microsoft によって "認定" されたプログラムを取得することはできません。これらの最新の OS では、C:\ ドライブのルートもかなり厳重にロックされているため、アプリをインストールするには管理者のアクセス許可が必要です (ただし、実行するには必要ありません)。
- インストール中にプログラム サブフォルダーのアクセス権を増加させるインストーラーのカスタム アクションを作成します。繰り返しますが、これを行った場合、Microsoft がアプリを認定する可能性は低く、これにはアプリをインストールするための管理者権限も必要です。つまり、ネットワーク上の平均的なユーザーは、アプリをダウンロードして実行することはできません。
- 「適切な」場所に変更する必要があるファイル (ユーザー固有のファイルの場合はアプリケーション データ、ソフトウェア全体に関連するファイルの場合はプログラム データ) をインストールし、メイン アプリケーション フォルダー内のファイルを指すショートカットを作成します。アクセス可能な場所。レガシ アプリは違いを認識できません。
編集:これは、アプリの「ホーム」ディレクトリのサブフォルダーにある構成ファイルからデータを読み書きする必要がある、同様の「レガシー」アプリを持つ、私が作成したアプリのインストーラーのカスタム アクションから直接抽出した方法です。渡された IDictionary は、さまざまなカスタム アクション メソッド (OnBeforeInstall、OnAfterInstall、OnCommit など) から取得したものであるため、これをインストーラー クラスにドロップし、選択したインストール イベントのハンドラーから呼び出します (これは必須です)。インストーラーがファイルシステムの変更を行った後)、次のように呼び出します。
private void SetEditablePermissionOnConfigFilesFolder(IDictionary savedState)
{
if (!Context.Parameters.ContainsKey("installpath")) return;
//Get the "home" directory of the application
var path = Path.GetFullPath(Context.Parameters["installpath"]);
//in my case the necessary files are under a ConfigFiles folder;
//you can do something similar with individual files
path = Path.Combine(path, "ConfigFiles");
var dirInfo = new DirectoryInfo(path);
var accessControl = dirInfo.GetAccessControl();
//Give every user of the local machine rights to modify all files
//and subfolders in the directory
var userGroup = new NTAccount("BUILTIN\\Users");
var userIdentityReference = userGroup.Translate(typeof(SecurityIdentifier));
accessControl.SetAccessRule(
new FileSystemAccessRule(userIdentityReference,
FileSystemRights.Modify,
InheritanceFlags.ObjectInherit
| InheritanceFlags.ContainerInherit,
PropagationFlags.None,
AccessControlType.Allow));
//Commit the changes.
dirInfo.SetAccessControl(accessControl);
}