hi,
this is part of an msi installer project - and should get you started...don't
forget the uninstall action :)
// this code will run when the MSI file is installed
public override void Install(IDictionary stateSaver) {
// first need to find the machine policy,
// which is where we'll make our changes
PolicyLevel machinePolicy = _findPolicyLevel("Machine");
if (null == machinePolicy) {
// sanity check - this should never happen
throw new ApplicationException("Failed to find the machine policy
in the PolicyHierarchy");
}
// we need to add a named permission set
// that includes whatever permissions we're granting
NamedPermissionSet nps = new NamedPermissionSet(permissionSetName,
PermissionState.None);
nps.Description = permissionSetDesc;
// TODO: add the permissions AcmeExpense needs
nps.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read,
@"c:\acme\expenses"));
nps.AddPermission(new EnvironmentPermission(EnvironmentPermissionAccess.Read,
"EXPENSE"));
nps.AddPermission(new SqlClientPermission(PermissionState.Unrestricted));
nps.AddPermission(new DataProtectionPermission(PermissionState.Unrestricted));
// add our named permission set to the machine policy level
// note that nothing is saved yet (we'll save at the end)
try {
machinePolicy.AddNamedPermissionSet(nps);
}
catch {
// duplicate name - update the existing one with the same name
machinePolicy.ChangeNamedPermissionSet(nps.Name, nps);
}
// now we need to create a code group that matches all assemblies
// that we ship with AcmeExpense - one way of doing this is to
// match the strong name we assign to that application (although
// depending on how you manage strong names, this might cover
// a wider set of assemblies)
CodeGroup cg = new UnionCodeGroup(
new StrongNameMembershipCondition(
new StrongNamePublicKeyBlob(acmePublicKey),
null, // match regardless of assembly's simple name
null), // match regardless of assembly's version
new PolicyStatement(nps,
PolicyStatementAttribute.Nothing) // no LevelFinal or Exclusive
attribute on this code group
);
cg.Name = codeGroupName;
cg.Description = codeGroupDesc;
// code groups with duplicate names are legal, but messy and confusing,
// so we make sure to first remove any existing code groups with
our name
_removeCodeGroupsByName(machinePolicy.RootCodeGroup, cg.Name);
// add our new code group (note we've not saved yet).
machinePolicy.RootCodeGroup.AddChild(cg);
// finally, save all changes atomically.
SecurityManager.SavePolicyLevel(machinePolicy);
}
PolicyLevel _findPolicyLevel(string labelWeWant) {
IEnumerator policyLevelEnumerator = SecurityManager.PolicyHierarchy();
PolicyLevel found = null;
while (policyLevelEnumerator.MoveNext()) {
PolicyLevel lvl = (PolicyLevel)policyLevelEnumerator.Current;
if (labelWeWant == lvl.Label) {
found = lvl;
}
}
return found;
}
---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
> Hey,
>
[quoted text clipped - 34 lines]
> Cheers!
> Nick
Nick - 20 Feb 2006 10:12 GMT
Hey Dominick,
I did indeed get this code running and was able to create the desired code
groups and perm sets. Thanks a ton!
However, I couldn't quite figure out exactly where to get this Install
method that is overridden. All that I have worked with Setup projects, I have
purely done with the GUI. I'm not sure where I can fit this code in the
project. I believe I'll have to create an exe for this and put it in as a
custom action during install, and put the code for removing it in a similar
action during uninstall. Am I correct in this assumption?
> hi,
>
[quoted text clipped - 121 lines]
> > Cheers!
> > Nick
Dominick Baier [DevelopMentor] - 20 Feb 2006 16:18 GMT
hi,
add a class lib to the installer project - and include its primary output
add a class to that project:
[RunInstaller(true)]
public class MyInstaller : System.Configuration.Install.Installer
and override the install/unistall methods.
---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
> Hey Dominick,
>
[quoted text clipped - 132 lines]
>>> Cheers!
>>> Nick
Nick - 21 Feb 2006 06:19 GMT
Thanks a ton Dominick!
I finally got the entire bit working.
However, was just wondering if you do not mind sharing the code for the
_removeCodeGroupsByName method too! Guess you missed it in the initial
response.
Cheers!
Nick
> hi,
>
[quoted text clipped - 147 lines]
> >>> Cheers!
> >>> Nick
Dominick Baier [DevelopMentor] - 21 Feb 2006 07:38 GMT
:) this is a challenge :)
void _removeCodeGroupsByName(CodeGroup parent, string childName) {
ArrayList codeGroupsToRemove = new ArrayList();
foreach (CodeGroup existingCodeGroup in parent.Children) {
if (childName == existingCodeGroup.Name) {
codeGroupsToRemove.Add(existingCodeGroup);
}
}
foreach (CodeGroup cg in codeGroupsToRemove) {
parent.RemoveChild(cg);
}
}
---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
> Thanks a ton Dominick!
> I finally got the entire bit working.
[quoted text clipped - 156 lines]
>>>>> Cheers!
>>>>> Nick