Deploying a COM Addin in 64-bit Office

Deployment alone is a hassle for VSTO Developers, especially beginners. In this, if one needs to deploy add-in in a 64-bit system is hectic. Here is a simple solution that I have used to debug and deploy add-ins in 64-bit Office.

You just need to follow these steps.
By default, the add-in will be registered with the respective office application. This is enough to run the application in debug mode. If we select ‘my add-in should be available to all users…’ option, it registers the add-in in the 32-bit global registry. This can be seen in RegEdit like this.
HKLM\Software\Wow6432Node\Microsoft\Office\\AddIns\

But, 64-bit Office cannot see registries in this location. For the add-in to load correctly, the registry keys should be moved to the following location.
HKLM\Software\Microsoft\Office\\AddIns\

For deploying the application…

In Visual Studio 2010, you just need to update the TargetPlatform property to x64 in the Setup Project Properties. Your project is ready to be deployed in 64-bit versions of Office now!

If you are working on Visual Studio 2008, there is a bug in setup project which prevents the add-in from registering 64-bit COM components. A work around is suggested for this problem in Cannot load 64-bit self-registering DLL’s section in Troubleshooting Windows Installer Deployments article in MSDN. It describes how to manually write 64-bit registry keys for making your add-in to work in 64-bit Office.

For more details, go through this article: Deploying COM Add-ins for 64-bit Office using Visual Studio

Check for appplication updates programmatically using ClickOnce Deployment

By default, ClickOnce provides two ways to update the application after installed in the client.

  1. Check everytime when the customization runs
  2. Check at regular intevals
ClickOnce Deployment Update Options

Default update types in ClickOnce Deployment

With the above, the user has to wait till it completes checking for the updates every time when the customization is loaded or at some time interval. It will be a waste of time for the users if application does not  update builds frequently.

How it would be if we provide a button for checking for updates when the user wish to do?

Hmm… Do you think that this is a headache process and hard to implement?

But, NO!

Here are the quick and simple steps to do this.

  1. Create a Windows Forms Application
  2. Place a button and call the following code. (It will check for updates and install them for you when the button is clicked)
Private Sub InstallUpdateSyncWithInfo()
    Dim info As UpdateCheckInfo = Nothing

    If (ApplicationDeployment.IsNetworkDeployed) Then
        Dim AD As ApplicationDeployment = ApplicationDeployment.CurrentDeployment

        Try
            info = AD.CheckForDetailedUpdate()
        Catch dde As DeploymentDownloadException
            MessageBox.Show("The new version of the application cannot be downloaded at this time. " + _
                                       ControlChars.Lf & ControlChars.Lf & "Please check your network" + _
                                       "connection, or try again later. Error: " + dde.Message)
            Return
        Catch ioe As InvalidOperationException
            MessageBox.Show("This application cannot be updated. It is likely not a ClickOnce application." + _
                                      "Error: " & ioe.Message)
            Return
        End Try

        If (info.UpdateAvailable) Then
            Dim doUpdate As Boolean = True

            If (Not info.IsUpdateRequired) Then
                Dim dr As DialogResult = MessageBox.Show("An update is available. Would you like to " + _ 
                                                 "update the application now?", "Update Available", 
                                                 MessageBoxButtons.OKCancel)
                If (Not System.Windows.Forms.DialogResult.OK = dr) Then
                    doUpdate = False
                End If
            Else
                ' Display a message that the app MUST reboot. Display the minimum required version.
                MessageBox.Show("This application has detected a mandatory update from your current " & _
                    "version to version " & info.MinimumRequiredVersion.ToString() & _
                    ". The application will now install the update and restart.", _
                    "Update Available", MessageBoxButtons.OK, _
                    MessageBoxIcon.Information)
            End If

            If (doUpdate) Then
                Try
                    AD.Update()
                    MessageBox.Show("The application has been upgraded, and will now restart.")
                    Application.Restart()
                Catch dde As DeploymentDownloadException
                    MessageBox.Show("Cannot install the latest version of the application. " & ControlChars.Lf 
                                              & ControlChars.Lf & "Please check your network connection," + _ 
                                               " or try again later.")
                    Return
                End Try
            End If
        End If
        End If
End Sub

Now say, Ain’t this cool? 🙂

Reference: http://msdn.microsoft.com/en-us/library/ms404263.aspx

Hope this helps!

Common mistakes while installation and deployment of PIAs

Have you ever came across this error message while deploying PIAs along with your add-in as prerequisites?

Problem:

Error 1316: Setup cannot read from file {PATH}\PIARedist.MSI. Check your connection to the network, or CD-ROM drive. For other potential solutions, see SETUP.CHM.

Reason:

This error occurs if the PIA’s already installed in the client system. This usually happens with Office 2007 if Outlook is installed with Contact Manager.

Business Contact Manager for Outlook 2007 installs the PIAs by default, and the file name is PIARedist.MSI.  However, the file from the Microsoft Download Center is called o2007pia.msi.  When you install the PIAs from the Microsoft Download Center, this name conflict causes the 1316 error.

Solution:

The simplest solution is to just ignore the error, because this message means that the PIAs are already installed. If you want to correct the error, uninstall the PIAs through the list of installed programs for the specific computer. Then you can reinstall the PIAs with the Primary Interop Assemblies for the 2007 Microsoft Office system from the Microsoft Download Center.

For more details, refer to Misha’s article in her blog.

http://blogs.msdn.com/b/vsto/archive/2008/05/20/common-pitfalls-during-pia-deployment-and-installation.aspx

Setting up bootstrapper package of Microsoft Office Primary Interop Assemblies (PIA) to use as prerequisite for setup project

This is the procedure to set Office Primary Interop Assemblies as prerequisites to your setup project.

First, You need to download the sample of component checker sample (ComponentChecker.cpp) from this MSDN page. http://msdn.microsoft.com/en-us/library/bb332051(office.12).aspx

Please go through “Preparing the Office Component Check” section in this article. Then follow these steps.

  1. Open the Command Prompt window needed to compile the check.If you are using Visual Studio 2008, open the Visual Studio 2008 Command Prompt by clicking Start, and then pointing to Programs, pointing to Microsoft Visual Studio 2008, pointing to Visual Studio Tools, and then clicking Visual Studio 2008 Command Prompt.
  2. At the command prompt, change the directory to {SamplesDir}\projects\Checks

    By default, the SamplesDir directory is C:\Program Files\Microsoft Visual Studio 2005 Tools for Office SE Resources\VSTO2005SE Windows Installer Sample Version 3\.

  3. Compile the component checker by typing the following command
    cl.exe /Oxs /MT /GS ComponentCheck.cpp advapi32.lib
  4. Close the Command Prompt window.
  5. Using Windows Explorer, copy the executable file ComponentCheck.exe into {SamplesDir}\packages\Office2003PIA and {SamplesDir}\packages\Office2007PIA.

To prepare the primary interop assemblies bootstrapper package, follow these steps.

  1. Download Office 2003 Update: Redistributable Primary Interop Assemblies from the Microsoft Download Center.
  2. Run the primary interop assembly installer.
  3. Accept the Microsoft Software License Terms, which gives you the right to package the primary interop assemblies as part of your installer.
  4. In Windows Explorer, open the folder to which the installer extracted the files.
  5. Copy O2003PIA.msi into the directory {SamplesDir}\packages\Office2003PIA

For more details, go through these:

http://msdn.microsoft.com/en-us/library/bb332051(office.12).aspx

http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/cd733f1a-7db3-430d-9700-92dc7bdac077/?prof=required

Hope this helps!

Code Access Security in .NET

Code Access Security is one of the powerful features of .NET but at the same time some confusion exists about its terminology and its usage. With this, I would like to make an attempt to explain some of the terminology with diagrams. This document does not explain all the details related to CAS, as lot of information already exists on the internet and only gives a jump start to Code Access Security.

The basics thing is whenever any code is being executed in managed world the .NET runtime verifies whether that code is allowed or not based on evidence and set of permissions.

Evidence

Where from the code came?

Permissions

What permissions are allowed for the code?

Basics Details

With the above basics let us explore Evidence and Permissions and other Code Access Security terminology.

Evidence

Evidence of an assembly is about its identity who it is and where it came from.

  • From where the assembly is being loaded?
  • If the assembly is downloaded from the web, what is the URL of the source directory?
  • What is Strong Name (if any)?
  • Who is the publisher (if digitally signed)?

How does System find out about this?
Codebase property of an assembly determines about its location which will result in either local directory, intranet/internet.One can get strong name and publisher details from the assembly manifest.
Once the Evidence of the assembly is gathered, the system grants some permission to this assembly.

How does System find out what permissions an assembly can have?
Time to explain some more terms. Let’s try to understand the following.

Policy Levels

.NET runtime security has 4 policy levels viz., Enterprise, Machine, User, and AppDomain. (which can be done programmatically).

Each policy has multiple code groups and multiple permission sets.

Code groups

Code group is a group of assemblies which satisfies the same condition. A code group will have one member condition which decides about particular assembly can be a member of this (group) or not.

Permissions and Permission Sets

Permission is what the code can do with a particular resource like File, Registry etc., and Permission Set is collection of permission.

.NET Default Policies will be

Now, we understood Policy Levels, Code Groups and their Permissions. It is time to find out how the system assigns the permissions to the loaded assembly.

Below is pseudo code how .NET Security system grants the permission to the assembly (Assumes no programmatic security)

public PermissionSet GetPermission(Assembly asm )

{

foreach( PolicyLevel pl in System.Security.Configuration.PolicyLevels )

{

foreach( CodeGroup cg in pl.CodeGroups )

{

if( cg.MembershipCondition exists in asm.Evidence )

{

// In given level it is the UNION of permissions across code groups

permissionSet[pl] = permissionSet[pl] Union cg.PermissionSet;

}

}

}

// Across levels it is intersecion of permissions

finalPermissionSet = permissionSet[“Enterprise”] Intersecion permissionSet[“Machine”]  Intersecion permissionSet[“User”];

return finalPermissionSet;

// Assume Exclusive and LevelFinal are not set

}

From above the .NET Security system assigns the permission set to the assembly.

At this point system has assigned the permission to the assembly

How does it get enforced?

The .NET classes ( System.IO.File , Microsoft.Win32.Registry classes will do the rest ) will enforce this by calling to appropriate security class.

Lets’ see how the File.OpenText code does this.

Pseudo code for OpenText()

{

string[] pathList = new string[1];

pathList[0] = pathToOpenFile;

new FileIOPermission( FileIOPermissionAccess.Read,pathList).Demand();

}

The call to .Demand will check the permission and throw an exception if it is not permitted to open the file.

If you have call to unmanaged dll where you open the text file the .NET will not be able to check whether you have permission to open or not.

Exclusive

Each code group in a policy consists of one property called Exclusive which means don’t consider any other permissions in that policy.

Lets’ walk through this…

Suppose your assembly belongs to Code group A, Code Group B and Code group C in Machine Policy.

Machine Policy

Code Group A

Permission Set A

Code Group B

Permission Set B

Code Group C

Permission Set C

And ‘Assembly Z’ falls in all code groups. Then permission set in this policy will be

Machine Level Policy for Assembly Z = (Permission Set A)   U (Permission Set B)  U (Permission Set C)  

But if set Exclusive property True in Code Group B then permission set in Machine Policy will be

MacineLevel Policy for Assembly Z =  ( Permission Set B )

Note: Still the final permission set will be intersection of Enterprise, Machine and User.

The exclusive property in .NET Configuration tool will be having check mark as

Level Final

There is another property called Level Final when checked, On Code Group, the policy in the next level will not considered.

Lets’ walk through this…

Enterprise Policy

Code Group

All_Code

Permission E

Machine Policy

Code Group

All_Code

Code Group A

Permission Set_A

Code Group B

Permission Set_B

Code Group C

Permission Set_C

User Policy

Code Group

Code Group 1

Permission Set_1

Code Group 2

Permission Set_2

Code Group 3

Permission Set_3

Suppose if an assembly belongs to All_Code in Enterprise, Code Group A,B,C in Machine and Code Group 1,2,3 in User then

Final Permission set = (Permision E) Intersection (Permision_A U Permission_B U Permission_C) Intersection (PermissionSet_1 U PermissionSet_2 U PermissionSet_3)

With Final Property set on Code Group B in Machine Policy then User Policy will not be evaluated and hence.

Final Permission set = (Permision E) Intersection ( Permision_A U Permission_B U Permission_C )

In .Net Security Configuration tool the Level Final property will be shown like below

With Exclusive and Level Final property one can precisely control the permission set applied to an assembly.

Deployment Image Servicing Management (DISM)

DISM is a new command line tool which was introduced in Windows 7 for deployment. DISM can be used to service a Window image or to prepare a Windows Pre-installation Environment (Windows PE) image. DISM also supports more features and functionality than the other tools (Package Manager) supported in Windows Vista, including logging, inventory commands with parse-able output, detailed help, offline INF driver package installation, direct application of MS update packages, and integration of international settings.

  1. Introduction to Deployment Image Servicing & Management (DISM)
    Deployment has a new tool in Windows 7: DISM (Deployment Image Servicing and Management). DISM is a command line tool which can be used to service a Windows® image or to prepare a Windows Preinstallation Environment (Windows PE) image. It replaces Package Manager (pkgmgr.exe), PEimg, and Intlcfg that were included in Windows Vista®. Read More
  2. Mounting a Wim Image for Offline Servicing
    Deployment Image Servicing and Management (DISM) is a tool which allows you to service your images offline. It supports both .wim and .vhd formats. In this article, we will look at how do you mount an Wim Image using this tool! Read More
  3. Adding or Removing Drivers from an offline Image
    You can offline service an image using DISM and add drivers to the mounted ones. You will need to download driver packages from OEM’s and ISV’s. These packages need to be INF-based packages (.exe or .msi driver installation is not available offline). Read More
  4. Enable/Disable Features using DISM on an offline Image
    You can offline service an image using DISM and enable/disable a feature on the mounted ones. In this short article, let us see on how we can do the same. Read More
  5. Unmount and clean a Wim Image using DISM Commands
    DISM provides you an option to load Wim images onto your local drive and the service it offline. You can either add/remove a driver, enable/disable features, perform other customizations.. without even installing them on a physical box. Now when you have mounted a Wim image, its really necessary to check if the image is mounted correctly. you can do that by running the command, dism /get-MountedWiminfo. Read More

Deploying VSTO 2005 Solutions

Back to (g)olden days… Here are some links which helps in deploying VSTO 2005 Add-ins. If you know some more, please add them in the comments. Thanks!

Whitepapers

Deploying Visual Studio 2005 Tools for Office Solutions Using Windows Installer (Part 1 of 2)

http://msdn.microsoft.com/office/default.aspx?pull=/library/en-us/odc_vsto2005_ta/html/OfficeVSTOWindowsInstallerOverview.asp

Deploying Visual Studio 2005 Tools for Office Solutions Using Windows Installer: Walkthroughs (Part 2 of 2)

http://msdn.microsoft.com/office/default.aspx?pull=/library/en-us/odc_vsto2005_ta/html/OfficeVSTOWindowsInstallerWalkthrough.asp

Documentation

VSTO Security MSDN documentation

http://msdn2.microsoft.com/en-us/k64zb6we(VS.80).aspx

VSTO Deployment MSDN documentation

http://msdn2.microsoft.com/en-us/hesc2788(VS.80).aspx

Security and Deployment walkthroughs

http://msdn2.microsoft.com/en-us/library/ms404813.aspx

Visual Studio 2005 Bootstrapper

http://msdn.microsoft.com/msdnmag/issues/04/10/Bootstrapper/

VSTO Outlook add-in architecture

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odc_vsto2005_ta/html/Office_VSTOOutlookAdd-inArchitecture.asp

Tools

PSS VSTO Client Troubleshooter

http://go.microsoft.com/fwlink/?LinkId=68531

Manifest Generation and Editing Tool (Mage.exe)

http://msdn2.microsoft.com/en-us/library/acz3y3te.aspx

VSTO Application Manifest Editor Sample

http://msdn.microsoft.com/office/default.aspx?pull=/library/en-us/odc_vsto2005_ta/html/Office_vstoApplicationManifestEditor.asp