How do I programmatically find the deployed files for a VSTO Add-In?

You can use ClickOnce deployment to install Office Add-ins for Office 2007 and Office 2010. It is very similar to deploying a desktop application, but not identical. With all types of ClickOnce deployments, you may include resources that you need to access programmatically. Files with a file extension of .xml, .mdf, and .mdb are assumed to be data and are deployed by default to the ApplicationDeployment.CurrentDeployment.DataDirectory, but non-data files will be found in the folder with the deployed assemblies.

With a non-VSTO application, you can programmatically find the location of the deployment by either accessing System.Windows.Forms.Application.StartupPath or by checking the Location of the executing assembly. With a VSTO application, the location of the executing assembly does not match the location of the deployment files.

The dll for a VSTO add-in is copied from the deployment directory into a separate location, and it is loaded by the host application from there. I would guess that this happens whenever you run the host application (such as Outlook), and this is why the Office add-in can be uninstalled, reinstalled, updated, etc., without impacting the host application. The changes don’t take effect until the host application is closed and reopened. So when you retrieve the executing assembly’s location, it points to the dll in the run location, and you can’t use that to track down the deployment files.

So how do you find the location of the deployment? You have to examine the CodeBase property of the executing assembly. This comes across as a URI, so you have to retrieve the LocalPath from the URI. It also includes the file name of the main assembly, so you have to retrieve just the directory name specifically.

Here’s the code in VB:

'Get the assembly information
Dim assemblyInfo As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()

'Location is where the assembly is run from 
Dim assemblyLocation As String = assemblyInfo.Location

'CodeBase is the location of the ClickOnce deployment files
Dim uriCodeBase As Uri = New Uri(assemblyInfo.CodeBase)
Dim ClickOnceLocation As String = Path.GetDirectoryName(uriCodeBase.LocalPath.ToString())

Here’s the code in C#:

//Get the assembly information
  System.Reflection.Assembly assemblyInfo = System.Reflection.Assembly.GetExecutingAssembly();
                    
  //Location is where the assembly is run from 
  string assemblyLocation = assemblyInfo.Location;

  //CodeBase is the location of the ClickOnce deployment files
  Uri uriCodeBase = new Uri(assemblyInfo.CodeBase);
  string ClickOnceLocation = Path.GetDirectoryName(uriCodeBase.LocalPath.ToString());

When you compare these values for a non-VSTO ClickOnce application, the directories are the same. When I run this code for my Outlook Add-In, I get these values:

assemblyLocation =

C:\Users\Robin\AppData\Local\assembly\dl3\VBJZ5WH8.6NJ\HRZA3JXN.LVG\b0520efe\3a5b99ef_2e21cb01\GoldMail Outlook Add-In.DLL

ClickOnceLocation =

C:\Users\Robin\AppData\Local\Apps\2.0\ZMBZ82EH.TDG\WHXVWE4L.GZ7\gold..vsto_7a251ffffc558391_0002.0000_10ff9c34a357cc30

If you’ve ever looked at the ClickOnce cache, the ClickOnceLocation will be familiar to you, being in the same format as and location as other types of ClickOnce applications.

So the assemblyLocation is where the dll is actually being run from by the hosting application (Outlook in this case), and the ClickOnceLocation is the location of the other deployment files. Any files that you deploy with your VSTO add-in and want to access programmatically can be found there.

Tags:

17 Responses to “How do I programmatically find the deployed files for a VSTO Add-In?”

  1. Windows Client Developer Roundup for 7/12/2010 - Pete Brown's 10rem.net Says:

    […] How do I programmatically find hte deployed files for a VSTO Add-in? (RobinDotNet) […]

  2. ClickOnce Guy Says:

    hey, how do I change the add/remove programs icon to be the application icon also?

    • robindotnet Says:

      Hi, I’ll post the code for this tomorrow as a new blog entry. It’s actually quite easy (once you know how!). I have this working on the add-ins I’ve written for my company, as well as our regular desktop application, all of which are ClickOnce deployments.

    • robindotnet Says:

      I haven’t gotten the code posted (working on a huge release going out tonight), but I did post it a while ago in the MSDN ClickOnce forum. Check out this thread. I’ll post it to my blog as soon as I can.

      Robin

  3. eborix13 Says:

    I’ve tried your example. But although the ClickOnce location is:

    C:\Documents and Settings\tester\Local Settings\Apps\2.0\AGEG6YLT.483\P6N6CD4H.7N1\oppp..vsto_bda1d97e335e1232_0001.0000_250747204f70f81e

    the files I’ve deployed with the application are here:
    C:\Documents and Settings\tester\Local Settings\Apps\2.0\Data\O9Z1J4KT.DK0\2VY2K32Q.KYN\oppp..vsto_bda1d97e335e1232_0001.0000_250747204f70f81e\Data\

    which is a totally different path. How can I obtain that path?

    • robindotnet Says:

      Hi,
      If you have a file that ClickOnce thinks is data, it puts it in the data cache, which you can find at ApplicationDeployment.CurrentDeployment.DataDirectory. With VSTO, you have no control over what ClickOnce thinks is data. While database files are obvious, it also thinks XML files are data. (Grrrrrr.) In a non-VSTO ClickOnce deployment, there is an Application Files dialog where the user can override this, but there’s nothing comparable in VSTO. So try this variable, it should be the folder you need.
      Robin

      • Mac Says:

        Didn’t work for me, the CurrentDeployment.DataDirectory is still pointing to the application folder. I’ve tried this with a Windows forms application and it worked. Any suggestions

  4. raghavendra Says:

    Hi robin,

    I wanted to add the Application Files Programatically to have full control i.e Currently I am using the Click Once to deploy some dll’s and Data Files(which depend on the other solution Publishing) which is Working fine. Tommorrow if there are any changes to the Other solution which may create some more Dlls i need to include in Clickonce is there any way to Add programatically based on the Certain Folder since adding each time Manually is a big Pain?

    Thanks in Advance

    • robindotnet Says:

      Not really. The only way is to copy the files to the publish folder and use mage to recreate the application manifest that has a list of the files included in the deployment, and then re-sign both manifests.

  5. Orlando Says:

    Great post, simple and very well explained. You saved my day today .. lol.

    Thanks!

  6. Paul Barcomb Says:

    Robin,

    Awesome tip on locating the VSTO Deployment cache!!! It really helped me on a critical path to delivery..

    Paul B.

  7. MJR Says:

    Thanks for the tip. Worked like a charm…

  8. Liangyi Says:

    Beautiful solution. Thanks a million times.

  9. Andre Frota Says:

    You are The Man! Thanks thanks thanks!

  10. Remove cache from assembly location during uninstall | Ask & Answers Says:

    […] have created an Office addin and windows installer application for it. According to this article, addins dll’a are copied to directory like this […]

Leave a comment