views:

2141

answers:

2

Hi All,

My environment is VS2005 C# targetting Excel 2003. I gave myself a small dose of over confidence with the installer of this add-in when I saw that an .msi project was created just for me :) within the solution. Needless to say, this has been the trickiest part of the whole project and I am completely stuck on how to deploy and set Full Trust to my add-in as part of the installation.

I followed the very helpful example from http://msdn.microsoft.com/en-us/library/aa537179(office.11).aspx -- "Deploying Visual Studio 2005 Tools for Office Solutions Using Windows Installer: Walkthroughs (Part 2 of 2)".

There seemed to be some inaccuracies in that doc but really minor things. I am using a VSTO 2005 tools sample project for setting the .net security as a custom action of the .msi. This seems to work but is not currently allowing my plugin to load unless I manually change a few things with the .Net Framwork Configuration tool. After the installation is complete, I see the appropriate registry entries for Excel Addins and the appropriate LoadBehavior of 0x03. From the .Net 2.0 Framework Configuration applet in Control Panel, I see 2 nodes added to my Runtime Security Policy.

Runtime Security Policy-->User-->Code Groups-->All_Code-->MyCodeGroup-->MyCodeGroupChild.

The MyCodeGroup settings are set to URL validation and policylevel of NONE. The MyCodeGroup child settings are STRONG NAME and match what I set for my add-in dll.

In this setup, the plugin will not load. IF I change the "MyCodeGroup" Policy from None to Full Trust, it works. (after i reset my registry Load Behavior from 0x02 back to 0x03).

Any ideas on this. I have not found much on the web to indicate where I am going wrong.

Thanks for any guidance.

-Dan

+1  A: 

Dan,

In my experience I've found using CASPOL.exe to be the easiest way to set security policy.

For example you can grant full trust to all DLLs in a folder using this command: caspol -u -ag All_Code -url C:\FolderName\FolderName* FullTrust -n"Name" -d"Description"

Check out this MSDN Article: http://msdn.microsoft.com/en-us/library/zdc263t0.aspx

Or this one on CASPOL specifically: http://msdn.microsoft.com/en-us/library/cb6t8dtz.aspx

Or you can roll your own c# project to do it using this code as a basis: http://www.koders.com/csharp/fidDC5A2D42FE98AD20FFC65C4435785CDFE3CB5B10.aspx

thats what we did.

Also as per comments: exclude the PIA and VSTO Runtime from your msi build (go to references in the msi project, right click them and select 'exclude') and install them separately. Just google for 'Excel 2003 PIA Download' and 'VSTO Runtime download' to get the installers. Get all your clients to install those before your application.

That way you only have to worry about security for your plugin.

Matthew Rathbone
A: 

You only need setsecurity if you have custom assemblies. You are right the sample code does not work, but it needs a small change. let me know if this code change for CaspolSecurityPolicyCreator will fix it. (else need to compare my originals and find out what the difference is) internal static void AddSecurityPolicy( bool machinePolicyLevel, string solutionCodeGroupName, string solutionCodeGroupDescription, string assemblyPath, string assemblyCodeGroupName, string assemblyCodeGroupDescription) { string frameworkFolder = GetFrameworkFolder();

        string solutionInstallationLocation = Path.GetDirectoryName(assemblyPath);
        string solutionInstallationUrl = Path.Combine(solutionInstallationLocation, "*");

        string policyLevel;
        string parentCodeGroup;
        if (machinePolicyLevel)
        {
            policyLevel = "-m"; // Use Machine-level policy.
            parentCodeGroup = "My_Computer_Zone"; // Use My_Computer_Zone for assemblies installed on the computer.
        }
        else
        {
            policyLevel = "-u"; // Use User-level policy.
            parentCodeGroup = "All_Code";
        }

        // Add the solution code group. Grant no permission at this level.
        string arguments = policyLevel + " -q -ag " + parentCodeGroup + " -url \"" + solutionInstallationUrl + "\" Nothing -n \"" + solutionCodeGroupName + "\" -d \"" + solutionCodeGroupDescription + "\"";
        try
        {
            RunCaspolCommand(frameworkFolder, arguments);
        }
        catch (Exception ex)
        {
            string error = String.Format("Cannot create the security code group '{0}'.", solutionCodeGroupName);
            throw new Exception(error, ex);
        }

        // Add the assembly code group. Grant FullTrust permissions to the main assembly.
        try
        {
            // Use the assembly strong name as the membership condition.
            // Ensure that the assembly is strong-named to give it full trust.
            //AssemblyName assemblyName = Assembly.LoadFile(assemblyPath).GetName();
            //arguments = policyLevel + " -q -ag \"" + solutionCodeGroupName + "\" -strong -file \"" + assemblyPath + "\" \"" + assemblyName.Name + "\" \"" + assemblyName.Version.ToString(4) + "\" FullTrust -n \"" + assemblyCodeGroupName + "\" -d \"" + assemblyCodeGroupDescription + "\"";

            //RunCaspolCommand(frameworkFolder, arguments);
            //TODO- MS Hardcoded for now (better at assembly dll level use todo 1)
            arguments = policyLevel + " -q -ag \"" + solutionCodeGroupName + "\" -url \"" + solutionInstallationUrl + "\" FullTrust -n \"" + assemblyCodeGroupName + "\" -d \"" + assemblyCodeGroupDescription + "\"";
            RunCaspolCommand(frameworkFolder, arguments);
            //TODO: 1 code below will create a separate group per assembly path, also need to check if AcnUI assembly is installed in GAC.
            //AddFullTrust(frameworkFolder, assemblyPath, policyLevel, solutionCodeGroupName, assemblyCodeGroupName, assemblyCodeGroupDescription);
        }
        catch (Exception ex)
        {
            try
            {
                // Clean the solutionCodeGroupName.
                RemoveSecurityPolicy(machinePolicyLevel, solutionCodeGroupName);
            }
            catch {}

            string error = String.Format("Cannot create the security code group '{0}'.", assemblyCodeGroupName);
            throw new Exception(error, ex);
        }
    }

    internal static void RemoveSecurityPolicy(
        bool   machinePolicyLevel,
        string solutionCodeGroupName)
    {
        string frameworkFolder = GetFrameworkFolder();
        string policyLevel;
        if (machinePolicyLevel)
            policyLevel = "-m"; // Use Machine-level policy.
        else
            policyLevel = "-u"; // Use User-level policy.

        string arguments = policyLevel + " -q -rg \"" + solutionCodeGroupName + "\"";
        RunCaspolCommand(frameworkFolder, arguments);
    }

    private static string GetFrameworkFolder()
    {
        // Get the targeted Framework folder.
        Version version = new Version(2, 0, 50727);
        return GetRuntimeInstallationDirectory(version, true);
    }
mas_oz2k1