Hi,
He's the code I settled on. The AddDirectorySecurity and RemoveDirectorySecurity functions are very similar to the examples on MSDN. This code gives the ASPNET or NETWORK SERVICE account all permissions except full control to the App_Data folder.
I set the CustomActionData in the installer to /TheInstallFolder="[TARGETDIR]\"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Security.AccessControl;
using System.Windows.Forms;
using System.IO;
namespace CustomInstallAction
{
[RunInstaller(true)]
public partial class MyCustomInstaller : Installer
{
public MyCustomInstaller()
{
InitializeComponent();
}
/// <summary>
/// When installing set the permissions on the App_Data directory
/// </summary>
/// <param name="stateSaver"></param>
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
Boolean addedSecurity = false;
string directoryName = string.Empty;
try
{
directoryName = Path.Combine(this.Context.Parameters["TheInstallFolder"].ToString(), "App_Data");
}
catch
{
//TODO log these issues
}
if (directoryName.Length > 0)
{
// Try add access to the App_Data folder for the ASPNET user
try
{
// Add the access control entry to the directory.
AddDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Modify, AccessControlType.Allow);
AddDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Write, AccessControlType.Allow);
RemoveDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Delete, AccessControlType.Deny);
addedSecurity = true;
}
catch (Exception ex)
{
//TODO log these issues
//MessageBox.Show(System.Environment.MachineName + @"\ASPNET" + ex.ToString());
}
// If adding the ASPNET user failed try the NetworkService user
if (!addedSecurity)
{
try
{
// Add the access control entry to the directory.
AddDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Modify, AccessControlType.Allow);
AddDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Write, AccessControlType.Allow);
RemoveDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Delete, AccessControlType.Deny);
addedSecurity = true;
}
catch (Exception ex)
{
//TODO log these issues
//MessageBox.Show("NT AUTHORITY\\LOCAL SERVICE" + ex.ToString());
}
}
}
}
public override void Commit(System.Collections.IDictionary savedState)
{
base.Commit(savedState);
}
public override void Rollback(System.Collections.IDictionary savedState)
{
base.Rollback(savedState);
}
public override void Uninstall(System.Collections.IDictionary savedState)
{
base.Uninstall(savedState);
}
public static void Main()
{
}
/// <summary>
/// Adds an ACL entry on the specified directory for the specified account.
/// </summary>
/// <param name="dirName">Folder path to add the permissions to</param>
/// <param name="Account"></param>
/// <param name="Rights"></param>
/// <param name="ControlType"></param>
private static void AddDirectorySecurity(string folderName, string account, FileSystemRights rights, AccessControlType controlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(folderName);
// Get a DirectorySecurity object that represents the current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(account, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, controlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
/// <summary>
/// Removes an ACL entry on the specified directory for the specified account.
/// </summary>
/// <param name="FileName"></param>
/// <param name="Account"></param>
/// <param name="Rights"></param>
/// <param name="ControlType"></param>
public static void RemoveDirectorySecurity(string folderName, string account, FileSystemRights rights, AccessControlType controlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(folderName);
// Get a DirectorySecurity object that represents the current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.RemoveAccessRule(new FileSystemAccessRule(account, rights, controlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
}
}