views:

389

answers:

1

I have written a few Excel 2003/2007 add-ins using VSTO, and I usually end up referencing .NET dll's in the VSTO project (usually code I reuse across projects).
I ran into the following issue. While the calls to the dll work perfectly in debug mode or on the development machine, when I deploy the add-in through a msi installer, the dll is added to the folder of the add-in, but the add-in doesn't seem to be able to call the dll.
After some struggles, I figured out a way around this: on top of the Custom Action in the installer granting security to the add-in, I add another Custom Action granting security to each individual dll referenced by the add-in, following the steps described in
http://msdn.microsoft.com/en-us/library/bb332052.aspx

My issue is that while it works, I am not convinced I am doing it right. It is super-tedious, and I also get a warning when I build, which from what I can make is actually pointing at the fact that the security is granted twice in the same location.
Anyone here can tell me whether I am doing it right or not, and what the better way is, if there is one?

+1  A: 

In my case, I have a suite of add-ins under MyCompany.Office.

I have a shared library of core functionality called MyCompany.Office.dll, which is referenced by MyCompany.Office.Word.dll and MyCompany.Office.Excel.dll, which are both add-ins (you could easily have multiple add-ins for Excel rather than one for Word and one for Excel, or whatever you want).

What I did was create a strong name keyfile for the solution and linked it in all three projects. I then signed all three libraries with the same strong name keyfile.

I then created an Installer Action that adds a CAS entry using the public key as evidence, rather than the file location. so, my custom action ultimately invokes caspol.exe -m -q -ag "My_Computer_Zone" -strong -hex <my public key> -noname -noversion FullTrust -n "MyCompany_Office" -d "Code group for MyCompany.Office add-ins.". This gives FullTrust to all libraries with that public key.

You can view the public key by opening a command prompt, navigating to the keyfile location and typing sn -Tp mykeyfile.snk. If you want to get the public key pro grammatically (like extending SetSecurity), you could use code like this:

private static String GetPublicKeyHexString(String assemblyPath)
{
    AssemblyName assmName = Assembly.LoadFile(assemblyPath).GetName();
    StringBuilder output = new StringBuilder();
    Byte[] publicKey = assmName.GetPublicKey();

    foreach(Byte byte in publicKey) 
    {
       output.Append(byte.ToString("x").PadLeft(2, '0'));
    }

    return output.ToString();
}
HackedByChinese
I need to try that out before marking this as a valid answer, but this looks sensible.
Mathias
You could also use a URL as evidence, and set the URL to your installation directory. Thereby giving all assemblies in that folder FullTrust. I don't recommend this though. Someone could drop a malicious assembly in your install folder, giving it full trust, and then someone could blame you for creating a vulnerability. I only mention this in case someone suggests it, so that you can see why that's not a good idea.
HackedByChinese
Thanks, I believe it works. I actually found this post on the msdn forum, which proposes a small modification of the SetSecurity project, allowing to add a comma-separated list of dlls instead of a single dll (Lex007 post in the thread). That way, you don't have to share the same key.http://social.msdn.microsoft.com/forums/en-US/vsto/thread/cec6abb6-4716-4bde-91f2-25fb68abd54e/
Mathias