Solved

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

Posted on 2011-09-06
20
876 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 8
20 Comments
 
LVL 6

Assisted Solution

by:xenacode
xenacode earned 375 total points
ID: 36493936
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
ID: 36494170
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
ID: 36494227
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
Office 365 Training for Admins - 7 Day Trial

Learn how to provision tenants, synchronize on-premise Active Directory, implement Single Sign-On, customize Office deployment, and protect your organization with eDiscovery and DLP policies.  Only from Platform Scholar.

 
LVL 2

Author Comment

by:JulienVan
ID: 36494273
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
ID: 36494281
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
ID: 36494326
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 36

Assisted Solution

by:Miguel Oz
Miguel Oz earned 125 total points
ID: 36500039
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
ID: 36500704
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
ID: 36501256
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
ID: 36501422
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
 
LVL 6

Expert Comment

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

Author Comment

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

Expert Comment

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

Author Comment

by:JulienVan
ID: 36501588
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
ID: 36501638
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
ID: 36501774
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
ID: 36501885
@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
ID: 36501939
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
ID: 36501979
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
ID: 36510458
Hi all, I'm closing the question, thanks for your help!
0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Excel can be a tricky bit of software to get your head around. Whilst you’ll be able to eventually get to grips with the basic understanding of how to get by, there are a few Excel tips that not everybody will even know about let alone know how to d…
This article describes a serious pitfall that can happen when deleting shapes using VBA.
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 …
This Micro Tutorial will demonstrate how to use longer labels with horizontal bar charts instead of the vertical column chart.

734 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