7


2

C#.NET-UACの有無にかかわらずディレクトリが書き込み可能かどうかを判断する方法

私は、ファイルシステム上の指定されたディレクトリにファイルをコピーする必要があるソフトウェアに取り組んでいます。 UAC対応OS(Vista、7)とXPの両方で動作する必要があります。 UACの昇格が必要なディレクトリへの書き込みの問題を回避するために、アプリは実際にUACが必要であることを示すマニフェストで別のプロセスを開始します。 これによりプロンプトが生成され、ユーザーが確認するとコピーが実行されます。

私が見ることができるものから、ディレクトリには、UAC昇格なしで書き込み可能、​​UAC昇格で書き込み可能、​​書き込み不可の3つの異なる論理アクセス許可状態を設定できます。

私の質問はこれです:特定のディレクトリについて、現在のユーザーがそのディレクトリにファイルをコピー(および潜在的に上書き)できるかどうかを確実に判断するにはどうすればよいですか?できれば、UAC昇格が必要かどうかをどのように判断しますか?

XPでは、「書き込みを許可する」許可が付与されているかどうかを確認するのと同じくらい簡単ですが、Vista / 7では、この許可が付与されていないディレクトリがありますが、このアクションはUACでも可能です。

2 Answer


11


ファイルのWriteAccessのメソッドがあります。おそらくディレクトリ(Directory.GetAccessControlなど)に適合させることができます。

    ///  Checks for write access for the given file.
    ///
    /// The filename.
    /// true, if write access is allowed, otherwise false
    public static bool WriteAccess(string fileName)
    {
        if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) != 0)
            return false;

        // Get the access rules of the specified files (user groups and user names that have access to the file)
        var rules = File.GetAccessControl(fileName).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));

        // Get the identity of the current user and the groups that the user is in.
        var groups = WindowsIdentity.GetCurrent().Groups;
        string sidCurrentUser = WindowsIdentity.GetCurrent().User.Value;

        // Check if writing to the file is explicitly denied for this user or a group the user is in.
        if (rules.OfType().Any(r => (groups.Contains(r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Deny && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData))
            return false;

        // Check if writing is allowed
        return rules.OfType().Any(r => (groups.Contains(r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Allow && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData);
    }

お役に立てれば。


2


操作を試みるだけで、昇格のない書き込み可能なケースを処理します。 それが失敗したときであり、潜在的に困難なUAC昇格を介して、書き込み不可と書き込み可能を区別する必要があります。

私はプログラムがそれを理解しようとしているとは思わない(彼らは必然的にそれをかなり間違ってしまうので)。

次の前提で設計しても安全だと思います。

  • 管理者は、試用版ソフトウェアの制限付きアカウントとして実行することがあります 彼らは信頼していません→アプリが、昇格ではなく、キャンセルしたいUACを必要とするコンピューターに侵襲的な変更を加える場合。

  • 昇格した管理者はファイルを書き込むことができます(結局管理者です) →実際のACLチェックは不要です。制限されたトークンを検出するだけで十分です。

  • ユーザーは別のアカウントを使用して昇格したり、同僚に UACが必要とするアクションを完了する→制限されたトークンを確認すると、これらのケースを見逃します。

  • 使用中のファイルなど、他の回復可能なものによってアクセスが拒否されます→ 場合によっては、同じ制限されたアクセス許可を使用して再試行することが正しいことです。

ですから、アクセスが拒否された場合、Windowsが操作を拒否したことを説明するプロンプトを表示するAsInvoker操作を試すことをお勧めします。考えられる原因は、使用中のファイル、昇格が必要、管理者の資格情報が必要、ボタン:

  • キャンセル

  • 現在の資格情報で再試行する

  • (シールドアイコン)アクセス許可を上げて再試行する