VB.NET Installer class for setting Code Access Security with Uninstall

C# Version here: http://weblogs.asp.net/mnissen/articles/427490.aspx

 

 

' Code Access Security configuring installer VB.NET version by Bob_Chauvin@removethisstuffyahoo.com

' Based on C# version by Mads Nissen 2005:

'http://weblogs.asp.net/mnissen/articles/427490.aspx

' Other useful CAS related Articles

' http://blogs.msdn.com/chrsmith/default.aspx

' Note: Add this class to your project in a separate file. Remember to add a reference to System.Configuration.Install. Must reside in your

' main project.

 

Imports System.ComponentModel

Imports System.Configuration.Install

Imports System.Security.Policy

Imports System.Security

 

<System.ComponentModel.RunInstaller(True)> Public Class Installer

 

    Inherits System.Configuration.Install.Installer

    Private ReadOnly installPolicyLevel As String = "Machine"

    Private ReadOnly namedPermissionSet As String = "FullTrust"

    Private ReadOnly codeGroupDescription As String = "VSTO Permissions for "

    Private ReadOnly productName As String = "Your Outlook Add-In"

 

    Private ReadOnly debugBreakOnInstall As Boolean = False

 

    Private _codeGroupName As String = ""

 

    Public Sub New()

    End Sub

 

    '/ <summary>

    '/ Gets a CodeGroup name based on the productname and URL evidence

    '/ </summary>

    Private ReadOnly Property CodeGroupName() As String

        Get

 

            If (debugBreakOnInstall) Then System.Diagnostics.Debugger.Break()

 

            'If (CodeGroupName.Length = 0) Then CodeGroupName = "[" + Me.Context.Parameters("productName") + "] " + InstallDirectory

            _codeGroupName = "[" + productName + "] " + InstallDirectory

 

            Return _codeGroupName

 

        End Get

 

    End Property

 

 

    '/ <summary>

    '/ Gets the installdirectory with a wildcard suffix for use with URL evidence

    '/ </summary>

 

    Private ReadOnly Property InstallDirectory() As String

        Get

 

            ' Get the install directory of the current installer

            'If (debugBreakOnInstall) Then System.Diagnostics.Debugger.Break()

            'If assemblyPath Is Nothing Then assemblyPath = ""

 

            Dim assemblyPath As String = Me.Context.Parameters("assemblypath")

            Dim _installDirectory As String = assemblyPath.Substring(0, assemblyPath.LastIndexOf("\"))

 

            If (Not _installDirectory.EndsWith("\")) Then

 

                _installDirectory += "\"

                _installDirectory += "*"

 

            End If

 

            Return _installDirectory

 

        End Get

    End Property

 

    Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)

 

        MyBase.Install(stateSaver)

 

        Try

 

            ConfigureCodeAccessSecurity()

 

        Catch ex As Exception

 

            System.Windows.Forms.MessageBox.Show(ex.ToString())

            Me.Rollback(stateSaver)

 

        End Try

 

    End Sub

 

    '/ <summary>

    '/ Configures FullTrust for the entire installdirectory

    '/ </summary>

 

    Private Sub ConfigureCodeAccessSecurity()

 

        Dim machinePolicyLevel As PolicyLevel = GetPolicyLevel()

 

        If (GetCodeGroup(machinePolicyLevel) Is Nothing) Then

 

            ' Create a new FullTrust permission set

            Dim permissionSet As PermissionSet = New NamedPermissionSet(Me.namedPermissionSet)

            Dim membershipCondition As IMembershipCondition = New UrlMembershipCondition(InstallDirectory)

 

            ' Create the code group

            Dim policyStatement As PolicyStatement = New PolicyStatement(permissionSet)

            Dim codeGroup As CodeGroup = New UnionCodeGroup(membershipCondition, policyStatement)

 

            codeGroup.Description = Me.codeGroupDescription

            codeGroup.Name = Me.CodeGroupName

 

            ' Add the code group

            machinePolicyLevel.RootCodeGroup.AddChild(codeGroup)

 

            ' Save changes

            SecurityManager.SavePolicy()

        End If

 

    End Sub

 

    '/ <summary>

    '/ Gets the currently defined policylevel

    '/ </summary>

    '/ <returns></returns>

 

    Private Function GetPolicyLevel() As System.Security.Policy.PolicyLevel

 

        ' Find the machine policy level

        Dim machinePolicyLevel As PolicyLevel = Nothing

        Dim policyHierarchy As System.Collections.IEnumerator = SecurityManager.PolicyHierarchy()

 

        While policyHierarchy.MoveNext()

 

            Dim level As PolicyLevel = CType(policyHierarchy.Current, PolicyLevel)

 

            If (level.Label.CompareTo(installPolicyLevel) = 0) Then

 

                machinePolicyLevel = level

 

                Exit While

 

            End If

 

        End While

 

        If (machinePolicyLevel Is Nothing) Then

 

            Throw New ApplicationException("Could not find Machine Policy level. Code Access Security " + "is not configured for this application.")

 

        End If

 

        Return machinePolicyLevel

 

    End Function

 

    '/ <summary>

    '/ Gets current codegroup based on CodeGroupName at the given policylevel

    '/ </summary>

    '/ <param name="policyLevel"></param>

    '/ <returns>null if not found</returns>

 

    Private Function GetCodeGroup(ByVal policyLevel As System.Security.Policy.PolicyLevel) As System.Security.Policy.CodeGroup

 

        Dim codeGroup As System.Security.Policy.CodeGroup

 

        For Each codeGroup In policyLevel.RootCodeGroup.Children

 

            If (codeGroup.Name.CompareTo(CodeGroupName) = 0) Then

 

                Return codeGroup

 

            End If

 

        Next

 

        Return Nothing

 

    End Function

 

    Public Overrides Sub Uninstall(ByVal savedState As System.Collections.IDictionary)

 

        If (debugBreakOnInstall) Then System.Diagnostics.Debugger.Break()

 

        MyBase.Uninstall(savedState)

 

        Try

 

            Me.UninstallCodeAccessSecurity()

 

        Catch ex As Exception

 

            System.Windows.Forms.MessageBox.Show("Unable to uninstall code access security:\n\n" + ex.ToString())

 

        End Try

 

    End Sub

 

    Private Sub UninstallCodeAccessSecurity()

 

        Dim machinePolicyLevel As PolicyLevel = GetPolicyLevel()

        Dim codeGroup As CodeGroup = GetCodeGroup(machinePolicyLevel)

 

        If Not (codeGroup Is Nothing) Then

 

            machinePolicyLevel.RootCodeGroup.RemoveChild(codeGroup)

 

            ' Save changes

 

            SecurityManager.SavePolicy()

 

        End If

 

    End Sub

 

End Class

 

'----------------------------------------------------------------

' Converted from C# to VB .NET using CSharpToVBConverter(1.2).

' Developed by: Kamal Patel (http://www.KamalPatel.net)

'----------------------------------------------------------------

 

Filed under:

Comments

# Rafael said:

Any samples on how to reference this class from the main project? Or is it done automagically?

Thanks,

Rafael

Wednesday, August 22, 2007 8:42 AM
# Before install my setup ofter install frame work said:

My problem is to install my design form after install frame work ofter install my project before setup

Tuesday, February 5, 2008 1:15 AM
# aman said:

hi i m trying to make installer for CAS settings.

i have taken class library and added ur methods.

what will be the next step.

plz respond back

Tuesday, March 4, 2008 6:43 AM
# AD said:

HI ,

i am getting these errors when installing:

object reference not set to an instance of an Object at

ClassInstaller.installer.GetCodeGroup(policylevel policylevel)

Friday, July 4, 2008 3:58 AM
# sdeedsas1 said:

erfdsd redsdreasdsa

Monday, October 6, 2008 12:32 PM
# Deepak said:

How can i use this code in my Application.

Tuesday, October 7, 2008 4:51 AM
# Dave said:

Just create a class file then paste teh code. build your app and then install it with installutil.exe

Friday, October 2, 2009 2:30 PM
# JMP said:

Installutil.exe? Can't you be more specific please?

I created the class within my application. Then what? I normally use a setup project from within VBdotnet.

Monday, November 23, 2009 3:23 AM
# JMP said:

Installutil.exe? Can't you be more specific please?

I created the class within my application. Then what? I normally use a setup project from within VBdotnet.

Monday, November 23, 2009 4:06 AM