CAS

A

Andreas

Hi,

I#ve developed a Com-Addin with VS2005 and VSTO for Outlook.
On my development machine, everything works fine.
But when I am installing it via the created msi package, nothing works.
I've narrowed the cause down to problems with Code Access Security.
How do I set up my add-in on the clients machine with the correct security
settings?

thanks for your help
Andy
 
M

Michael

I found this Codelines in the Web, dont remeber the link right now...


' Code Access Security configuring installer
Imports System.ComponentModel
Imports System.Configuration.Install
Imports System.Security.Policy
Imports System.Security

<System.ComponentModel.RunInstaller(True)> Partial Class Installer1
Inherits System.Configuration.Install.Installer
Private ReadOnly installPolicyLevel As String = "Machine"
Private ReadOnly namedPermissionSet As String = "FullTrust"
Private ReadOnly codeGroupDescription As String = "MyAdd-In blah.."
Private ReadOnly productName As String = "iWannaBeAaddIn"
Private ReadOnly debugBreakOnInstall As Boolean = False
Private _codeGroupName As String = ""


'/ Gets a CodeGroup name based on the productname and URL evidence
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

'/ Gets the installdirectory with a wildcard suffix for use with
URL evidence
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

'/ Configures FullTrust for the entire installdirectory
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

'/ Gets the currently defined policylevel
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

'/ Gets current codegroup based on CodeGroupName at the given
policylevel
'/ <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

'Installer overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Component
Designer
'It can be modified using the Component Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub

End Class




this should set your addin to FullTrust.

dont no if it help u, but i hope so :)

Greets Mitch
 
A

Andreas

Hi Michael,

I got this code too but cant get it to work.
I create a new installer class and paste this code, but I get an error
message:
Error 3 Attribute 'RunInstallerAttribute' cannot be applied multiple
times. D:\DWH\Installer1.vb 7 2 DWH

I don't know how to solve this

Michael said:
I found this Codelines in the Web, dont remeber the link right now...


' Code Access Security configuring installer
Imports System.ComponentModel
Imports System.Configuration.Install
Imports System.Security.Policy
Imports System.Security

<System.ComponentModel.RunInstaller(True)> Partial Class Installer1
Inherits System.Configuration.Install.Installer
Private ReadOnly installPolicyLevel As String = "Machine"
Private ReadOnly namedPermissionSet As String = "FullTrust"
Private ReadOnly codeGroupDescription As String = "MyAdd-In blah.."
Private ReadOnly productName As String = "iWannaBeAaddIn"
Private ReadOnly debugBreakOnInstall As Boolean = False
Private _codeGroupName As String = ""


'/ Gets a CodeGroup name based on the productname and URL evidence
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

'/ Gets the installdirectory with a wildcard suffix for use with
URL evidence
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

'/ Configures FullTrust for the entire installdirectory
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

'/ Gets the currently defined policylevel
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

'/ Gets current codegroup based on CodeGroupName at the given
policylevel
'/ <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

'Installer overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Component
Designer
'It can be modified using the Component Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub

End Class




this should set your addin to FullTrust.

dont no if it help u, but i hope so :)

Greets Mitch
 
M

Michael

Andreas said:
Hi Michael,

I got this code too but cant get it to work.
I create a new installer class and paste this code, but I get an error
message:
Error 3 Attribute 'RunInstallerAttribute' cannot be applied multiple
times. D:\DWH\Installer1.vb 7 2 DWH

I don't know how to solve this


Oh, i know this problem.. had this too..

You have to add a new "Class Library" project to your solution, and
then add a new "Install Class" to this project.

So, now click "Show all Files" in your solution Pane.. the trick is,
your code have not to be in the "Installer1.vb"... the code must be in
"Installer1.Designer.vb" this file is the codebehind file of the
"installer1.vb"...

hope it works for your


greets
mitch
 
M

Michael

sorry for me poor english and the typing errors... it's to hot in
here.. :)

greets from swizerland
mitch
 
A

Andreas

thank you for your help Michael,
I will try what you suggested and get back to you later.
and yes, its extremely hot at the moment, here in Vienna too :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top