Make VSTO for Outlook solutions run right off the MSI
UPDATE: Installer class with uninstall logic here.
There are a couple of things you've got to do manually to make a Visual Studio Tools for Office 2005 application run straight off the MSI. I'm talking about the Outlook add-in project here, and there is no ClickOnce around.
With the standard setup for Outlook add-in projects in Visual Studio 2005 there are two things missing after you've run the MSI from the included setup project on the client machine:
- A couple of VSTO and Office related dlls (Should have been loaded from shared but for some reason they need to be in the local dir)
- Code Access Security settings granting your VSTO for Outlook addin rights to do what it wants
The first one is easy. Simply add a reference to Microsoft.Office.Tools.Common.dll to the Outlook project and it will be included in the setup. Also enable the files Microsoft.Office.Tools.Outlook.dll and Microsoft.VisualStudio.Tools.Applications.Runtime.dll in the Setup project so it is included with the MSI and placed in the target application directory on the client machine.
Then you'll need to handle CAS. You need to create a custom Installer class to do this work. Based on this article I've created the following installer class and added it as a custom action in my Installer.
[RunInstaller(true)]
public class Installer : System.Configuration.Install.Installer
{
public Installer()
{
}
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
try
{
// Find the machine policy level
PolicyLevel machinePolicyLevel = null;
System.Collections.IEnumerator policyHierarchy = SecurityManager.PolicyHierarchy();
while (policyHierarchy.MoveNext())
{
PolicyLevel level = (PolicyLevel)policyHierarchy.Current;
if (level.Label == "Machine")
{
machinePolicyLevel = level;
break;
}
}
if (machinePolicyLevel == null)
{
throw new ApplicationException(
"Could not find Machine Policy level. Code Access Security "+
"is not configured for this application."
);
}
// Create a new FullTrust permission set
PermissionSet permissionSet = new NamedPermissionSet("FullTrust");
// Get the install directory of the current installer
string assemblyPath = this.Context.Parameters["assemblypath"];
string installDirectory =
assemblyPath.Substring(0, assemblyPath.LastIndexOf("\\"));
if (!installDirectory.EndsWith(@"\"))
installDirectory += @"\";
installDirectory += "*";
IMembershipCondition membershipCondition =
new UrlMembershipCondition(installDirectory);
// Create the code group
PolicyStatement policyStatement = new PolicyStatement(permissionSet);
CodeGroup codeGroup = new UnionCodeGroup(membershipCondition, policyStatement);
codeGroup.Description = "VSTO Permissions for Objectware AS Plugins";
codeGroup.Name = "Objectware AS";
// Add the code group
machinePolicyLevel.RootCodeGroup.AddChild(codeGroup);
// Save changes
SecurityManager.SavePolicy();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}
}