Solved

Strange behavior of excel 2010 after installing an add-in developed with Visual Studio 2010

Posted on 2011-09-06
20
854 Views
Last Modified: 2012-05-12
Hello,

I've created an add-in for Microsoft Excel 2010 with several libraries in Visual Studio 2010.
All of these libraries are Visual Studio projects with "Target framework" option defined as ".NET Framework 4 Client Profile" in their properties.

Below are the prerequisites defined in the properties of the setup project:

 Installation prerequisites 1 Installation prerequisites 2 Installation prerequisites 3
I've created some custom actions during the installation to grant full trust permissions to the assemblies so that they can be loaded in Excel. The function SetSecurtity used is attached below:
 
//-----------------------------------------------------------------------
// 
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.IO;

namespace CustomActions
{
    [RunInstaller(true)]
    [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public sealed partial class SetSecurity : Installer
    {
        public SetSecurity()
        {
            InitializeComponent();
        }

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            // Call the base implementation.
            base.Install(stateSaver);

            string allUsersString = this.Context.Parameters["allUsers"];
            string solutionCodeGroupName = this.Context.Parameters["solutionCodeGroupName"];
            string solutionCodeGroupDescription = this.Context.Parameters["solutionCodeGroupDescription"];
            string targetDir = this.Context.Parameters["targetDir"];
            string assemblyName = this.Context.Parameters["assemblyName"];
            string assemblyCodeGroupName = this.Context.Parameters["assemblyCodeGroupName"];
            string assemblyCodeGroupDescription = this.Context.Parameters["assemblyCodeGroupDescription"];

            // Note that a code group with solutionCodeGroupName name is created in the 
            // Install method and removed in the Rollback and Uninstall methods.
            // The solutionCodeGroupName must be a unique name to ensure that the 
            // correct code group is removed during Rollback and Uninstall.

            if (String.IsNullOrEmpty(solutionCodeGroupName))
                throw new InstallException("Cannot set the security policy. The specified solution code group name is not valid.");
            if (String.IsNullOrEmpty(solutionCodeGroupDescription))
                throw new InstallException("Cannot set the security policy. The specified solution code group description is not valid.");
            if (String.IsNullOrEmpty(targetDir))
                throw new InstallException("Cannot set the security policy. The specified target directory is not valid.");
            if (String.IsNullOrEmpty(assemblyName))
                throw new InstallException("Cannot set the security policy. The specified assembly name is not valid.");
            if (String.IsNullOrEmpty(assemblyCodeGroupName))
                throw new InstallException("Cannot set the security policy. The specified assembly code group name is not valid.");
            if (String.IsNullOrEmpty(assemblyCodeGroupDescription))
                throw new InstallException("Cannot set the security policy. The specified assembly code group description is not valid.");
            if (stateSaver == null)
                throw new ArgumentNullException("stateSaver");

            try
            {
                bool allUsers = String.Equals(allUsersString, "1");

                string assemblyPath = Path.Combine(targetDir, assemblyName);

                // Note that Install method may be invoked during Repair mode and the code group 
                // may already exist.
                // To prevent adding of another code group, remove the code group if it exists.
                try
                {
                    // The solutionCodeGroupName must be a unique name; otherwise, the method might delete wrong code group.
                    CaspolSecurityPolicyCreator.RemoveSecurityPolicy(allUsers, solutionCodeGroupName);
                }
                catch {}

                CaspolSecurityPolicyCreator.AddSecurityPolicy(
                    allUsers,
                    solutionCodeGroupName,
                    solutionCodeGroupDescription,
                    assemblyPath,
                    assemblyCodeGroupName,
                    assemblyCodeGroupDescription);
                stateSaver.Add("allUsers", allUsers);

            }
            catch (Exception ex)
            {
                throw new InstallException("Cannot set the security policy.", ex);
            }
        }

        public override void Rollback(System.Collections.IDictionary savedState)
        {
            // Call the base implementation.
            base.Rollback(savedState);

            // Check whether the "allUsers" property is saved.
            // If it is not set, the Install method did not set the security policy.
            if ((savedState == null) || (savedState["allUsers"] == null))
                return;

            // The solutionCodeGroupName must be a unique name; otherwise, the method might delete wrong code group.
            string solutionCodeGroupName = this.Context.Parameters["solutionCodeGroupName"];
            if (String.IsNullOrEmpty(solutionCodeGroupName))
                throw new InstallException("Cannot remove the security policy. The specified solution code group name is not valid.");

            try
            {
                bool allUsers = (bool) savedState["allUsers"];
                CaspolSecurityPolicyCreator.RemoveSecurityPolicy(allUsers, solutionCodeGroupName);
            }
            catch (Exception ex)
            {
                throw new InstallException("Cannot remove the security policy.", ex);
            }
        }


        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            // Call the base implementation.
            base.Uninstall(savedState);

            // Check whether the "allUsers" property is saved.
            // If it is not set, the Install method did not set the security policy.
            if ((savedState == null) || (savedState["allUsers"] == null))
                return;

            // The solutionCodeGroupName must be a unique name; otherwise, the method might delete wrong code group.
            string solutionCodeGroupName = this.Context.Parameters["solutionCodeGroupName"];
            if (String.IsNullOrEmpty(solutionCodeGroupName))
                throw new InstallException("Cannot remove the security policy. The specified solution code group name is not valid.");

            try
            {
                bool allUsers = (bool)savedState["allUsers"];
                CaspolSecurityPolicyCreator.RemoveSecurityPolicy(allUsers, solutionCodeGroupName);
            }
            catch (Exception ex)
            {
                // Note that throwing an exception might stop the uninstall process.
                // To inform the user and stop the uninstall process, throw an exception.
                // To continue the uninstall, do not throw the exception.
                throw new InstallException("Cannot remove the security policy.", ex);
            }
        }
    }
}

Open in new window


All is working fine but after installing the add-in and running Excel, it seems that Microsoft Office  is configuring something (I think it is related to the .NET 4 Framework Client):
 Office configuration after installation
I've got also following message in Excel asking me if I want to install the add-in:
After installing add-in in excel
When I uninstall the add-in I've got a message about the .NET framework 4 client profile which seems to have been modified:
Error uninstall
And if I install the add-in again, I also have the configuration window, an I then have to activate manually the add-in in the options of Excel.

I'm working with Visual Studio 2010, Windows XP Pro, and Office 2010.

Would you have any idea about how fixing these problems?
0
Comment
Question by:JulienVan
  • 11
  • 8
20 Comments
 
LVL 6

Assisted Solution

by:xenacode
xenacode earned 375 total points
Comment Utility
The recommended installation method for Office 2007 & 2010 add-ins is ClickOnce. Are you creating an MSI instead? ClickOnce removes the necessity for the custom action to set up CAS and makes things a whole lot simpler (although it does have its own problems). Is this an option for you?

Pete
Xenacode Ltd
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
Hi xenacode, thank you for your message,  I don't know ClickOnce very well, is it possible to define custom entries in the start menu (shortcuts, uninstaller, etc), banner in installer, and additional files in installation folder (user guides, etc)?
0
 
LVL 6

Expert Comment

by:xenacode
Comment Utility
You can't add entries to the start menu for an office add-in anyway because the add-in will only start when the Office app starts. The ClickOnce installer window will be the default "Office Customization Installer" window. You can add files to the installation folder but the installation folder will be in the user's application files folder not C:\Program Files so you may need to modify your code. Also installation is per user not per machine.

If you really do need to do a MSI installation instead then you should read this article:

http://blogs.msdn.com/b/mshneer/archive/2007/09/04/deploying-your-vsto-add-in-to-all-users-part-i.aspx

This article was written for VS2008 but has been updated this year for VS2010.

Pete
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
Hi xenacode, thank you I'll take a look at it. I need to add entries in the start menu, as shortcuts to our website, to the user guide, or to uninstall the product.
0
 
LVL 6

Expert Comment

by:xenacode
Comment Utility
OK then hopefully that article (there are 3 parts, the link above is part 1) will help you resolve your installation problems.

Pete
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
OK I'm going to make a new setup project from scratch by following these instructions:
http://msdn.microsoft.com/en-us/library/cc563937.aspx
http://msdn.microsoft.com/en-us/library/cc616991.aspx

Maybe this will fix my problem...
0
 
LVL 35

Assisted Solution

by:Miguel Oz
Miguel Oz earned 125 total points
Comment Utility
What version of office are you using on the client PC?
VSTO based add-in are only supported for Office Standard and above in 2007, but that may change for 2010... better ask Microsoft about it.

If your office app is supported, then you need to use this link for VS2010:
http://msdn.microsoft.com/en-us/vsto/ff937654.aspx

Note: 1) Your links are for Office 2007 VS2008, the procedure is far more simple now.
2) Also in you prerequisites: Check "Download prereq from the same location as my application"
and follow the steps in the link above. I built a msi installer for Excel 2010 based on the link but I have only tested in Office Excel profesional.
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
Hi mas_oz2003, thank you for your comment and this very interesting link.

I don't have selected the Office 2010 Primary Interop Assemblies (PIA2010) in my installer prerequisites, but it seems to work fine after the installation, do you know if it is a requirement or if it can be avoided (the references used in my projects are Microsoft.Interop.Excel, Microsoft.Interop.Word, Office, and Microsoft.Interop.Vbe)?

I don't know if I have to choose .Net Framework 4 or .NET Framework 4 Client Profile as the version to use in the project properties. The Client Profile version seems lighter and with enough functionalities, what do you think?

The version of Office on client computers might be Professional or Home & Business (I'm testing the add-in on both versions).
0
 
LVL 6

Accepted Solution

by:
xenacode earned 375 total points
Comment Utility
If you are using VS2010 & .NET 4, you can use embedded interops so you don't have to specify the PIA as a pre-requisite. It is better to target .NET 4 Client Profile unless you need the libraries from the full profile as not all users will have the full version of .NET 4 installed. Try compiling against the client profile and if it succeeds, use that.

Pete
Xenacode Ltd
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
Ok thank you I've tried and the build succeeded.

For the PIA, I can't embed the Microsoft.Interop.Excel library because one of my functions uses the Excel.ApplicationClass object and it seems that it cannot be embedded.

So do you think that I must select the OPIA2010 in the pre-requisites? It seems to work fine without it but I don't know if it will work on every client computer...
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 6

Expert Comment

by:xenacode
Comment Utility
Why do you say that using the ApplicationClass prevents you from using embedded interops?
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
It's Visual Studio which displays me an error message:
 Error when embedding interop assemblies
0
 
LVL 6

Expert Comment

by:xenacode
Comment Utility
can you use Excel.Application instead of Excel.ApplicationClass?
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
I tried it but it doesn't work then when I execute the functionality. :(
0
 
LVL 6

Assisted Solution

by:xenacode
xenacode earned 375 total points
Comment Utility
I would be tempted to try to get your functionality working with the Excel.Application class. I always use this class rather than the ApplicationClass class. That way you can avoid creating an additional dependency. If you really must create a dependency on the PIA then add it as you describe above.
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
Xenacode, I managed to replace the reference to the Excel.AplicationClass class by the Excel.Application class, so now I can embed the Interop assemblies, thank you!
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
@xenacode: my Excel 2010 add-in project is referencing following assemblies:

 - C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.Office.Tools.dll
 - C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.Office.Tools.Common.dll
 - C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.Office.Tools.Common.v4.0.Utilities.dll
 - C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.Office.Tools.Excel.dll
 - C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.Office.Tools.v4.0.Framework.dll
 - C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.VisualStudio.Tools.Applications.Runtime.dll

Knowing that "Visual Studio Tools for Office 2010 Runtime" is a prerequisite of my setup project, but not the OPIA2010, do you think that I have to enable the option "Copy Local" for these references?

Thanks in advance for your reply!
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
I've set the "Copy Local" property to True for all these assemblies because I've got an error message in Excel if I don't do it for Microsoft.Office.Tools.v4.0.Framework.
0
 
LVL 6

Expert Comment

by:xenacode
Comment Utility
The CopyLocal setting determines whether an assembly is marked as a prerequisite or for installation in the manifest. If you are doing an MSI installation, you will need to ensure that any assemblies marked as for install (i.e. Copy Local in VS) are present in the application folder after installation. I think you can set Copy Local to False for the VSTO and PIA assemblies because these are prerequisites. That said, if it ain't broke don't fix it.
0
 
LVL 2

Author Comment

by:JulienVan
Comment Utility
Hi all, I'm closing the question, thanks for your help!
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

A little background as to how I came to I design this code: Around 5 years ago I designed an add-in that formatted Excel files to a corporate standard, applying different cell colours and font type depending on whether the cells contained inputs,…
My experience with Windows 10 over a one year period and suggestions for smooth operation
The viewer will learn how to create a normally distributed random variable in Excel, use a normal distribution to simulate the return on an investment over a period of years, Create a Monte Carlo simulation using a normal random variable, and calcul…
Learn how to make your own table of contents in Microsoft Word using paragraph styles and the automatic table of contents tool. We'll be using the paragraph styles in Word’s Home toolbar to help you create a table of contents. Type out your initial …

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now