web-dev-qa-db-ja.com

.NETを使用してインストール中にフォルダーに読み取り/書き込み権限を付与する方法

Visual Studio 2010を使用してビルドしたセットアッププロジェクトがあります。

インストーラーは、アプリケーションとそのすべての依存関係を適切なサブディレクトリとプログラムデータディレクトリにインストールするという点でうまく機能します。

ただし、インストーラが作成した各ディレクトリ(ルートフォルダとそのすべてのサブディレクトリ)が「書き込み」権限を付与していないことに気付きました。 「ユーザー」グループのディレクトリに追加される権限は次のとおりです。

  • 読み取りと実行
  • フォルダーの内容を一覧表示する
  • 読む

これは、ユーザーがアプリケーションを「管理者」としてインストールするかどうかに関係なく、明らかにデフォルトのパーミッション設定になります。

インストーラーは、インストールされているアプリケーションが使用しているフォルダーに「書き込み」権限を与えないのは奇妙に思えます-インストーラーがProgramDataに作成するフォルダーはさらに混乱しますアプリケーションのデータベースのフォルダに「書き込み」権限が付与されません。

私の質問は、セットアッププロジェクトを構成して、フォルダーを作成するときに、どの種類のアクセス許可を誰に与えるかを指定できるようにする方法があるかどうかです。私の場合、(アプリケーションの)ルートディレクトリとそのすべてのサブディレクトリ、およびProgramDataフォルダーに配置されたフォルダーに「ユーザーグループ」の「読み取り/書き込み」権限を与える必要があります。技術的には、「ユーザーグループ」に「フルコントロール」のディレクトリを提供するのはクールです。

28
Jed

デフォルトでは、UsersグループにはProgram Filesなどのマシンごとの場所への書き込みアクセス権はありません。これは、インストールに関連しないWindows標準です。ただし、インストール中に必要な権限を設定できます。

Windowsインストーラーはカスタムアクセス許可をサポートしますが、Visual Studioはそれらを設定する方法を提供しません。したがって、Visual Studioでの唯一のソリューションはカスタムアクションです。

残念ながら、Visual Studioはアタッチされたカスタムアクションをサポートしていません。そのため、 XCACLS.EXE を使用してアクセス許可を設定すると、パッケージに含める場合にのみ機能します(ファイルと共にターゲットマシンにインストールされます)。

よりクリーンで複雑なソリューションは、カスタムアクションを(カスタムコードを使用して)自分で記述して、必要なアクセス許可を設定することです。

最速かつ最もクリーンなソリューションは、アクセス許可をより詳細に制御できる別のセットアップオーサリングツールを使用することです。

11
Cosmin Pirvu

私の他の投稿は少し一般的すぎるため削除されたと思いますので、以下に改良しました:

行うべきことは、カスタムアクションを作成することです。 C#カスタムアクション here を記述するためのMSDNチュートリアルをご覧ください。 Installメソッド内にアクセス許可を変更するコードを配置します。

リンクの最初のいくつかの手順に従って、インストーラーソリューションから参照される新しいインストーラープロジェクトを取得します。この方法で行う必要があるため、インストールの最後に呼び出されるdllをビルドできます。

実際にユーザーの読み取り/書き込み特権を設定するのは少し面倒で、私が取得できる最も近い方法は認証済みユーザーの設定でした。私はこれを思い付くためにインターネットで見つけた他のいくつかのソリューションをまとめました:

public override void Install(IDictionary stateSaver)
{
    // This gets the named parameters passed in from your custom action
    string folder = Context.Parameters["folder"];

    // This gets the "Authenticated Users" group, no matter what it's called
    SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);

    // Create the rules
    FileSystemAccessRule writerule = new FileSystemAccessRule(sid, FileSystemRights.Write, AccessControlType.Allow);

    if (!string.IsNullOrEmpty(folder) && Directory.Exists(folder))
    {
        // Get your file's ACL
        DirectorySecurity fsecurity = Directory.GetAccessControl(folder);

        // Add the new rule to the ACL
        fsecurity.AddAccessRule(writerule);

        // Set the ACL back to the file
        Directory.SetAccessControl(folder, fsecurity);
    }

    // Explicitly call the overriden method to properly return control to the installer
    base.Install(stateSaver);
}

次に、カスタムアクションを作成し、そのプロパティを編集し、CustomActionDataプロパティの下に次のようなものを追加します。

/folder="[CommonAppDataFolder][ProductName]"
36
ACK_stoverflow
private static void GrantAccess(string file)
        {
            bool exists = System.IO.Directory.Exists(file);
            if (!exists)
            {
                DirectoryInfo di = System.IO.Directory.CreateDirectory(file);
                Console.WriteLine("The Folder is created Sucessfully");
            }
            else
            {
                Console.WriteLine("The Folder already exists");
            }
            DirectoryInfo dInfo = new DirectoryInfo(file);
            DirectorySecurity dSecurity = dInfo.GetAccessControl();
            dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
            dInfo.SetAccessControl(dSecurity);

        }

上記のコードは、フォルダのアクセス権をすべてのユーザー(全員)にフルコントロール/読み取り/書き込みに設定します。

動作は仕様です。プログラムは、更新(Windowsインストーラーでも問題なく実行できます)以外の目的で、プログラム自体を(したがってインストールディレクトリを)変更しないでください。 .NETを使用している場合、 isolated storage はユーザーデータを保存するのに最適な場所です。

3
Teoman Soygul
DirectoryInfo info = new DirectoryInfo(path[x]);

DirectorySecurity security = info.GetAccessControl();

security.AddAccessRule(new FileSystemAccessRule(logonName, FileSystemRights.Modify, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));

security.AddAccessRule(new FileSystemAccessRule(logonName, FileSystemRights.Modify, InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));

info.SetAccessControl(security); 

ProgramDataフォルダーに複数のファイルを保存してアクセスする場合は、継承部分を設定することも重要です。

3

前述したように、ユーザーグループにはプログラムファイルへの書き込み権限がありません。インストーラークラスやWix(単純なプログラムの場合)を扱いたくない場合は、Windowsボリュームにソフトウェアをインストールすることをお勧めします。

Visual Studioセットアップウィザード:アプリケーションフォルダーの変更 'DefaultLocation'ターゲットマシンのファイルシステムの[ProgramFilesFolder]から[WindowsVolume] [Manufacturer] [ProductName]へのプロパティ。

1
depicci