Office Development with Visual Studio

Develop Office Business Applications using Visual Studio

March, 2010

Posts
  • Office Development with Visual Studio

    Show and Hide Context Menu Items in Outlook 2010 (Norm Estabrook)

    • 0 Comments

    If you have written code that shows and hides context menu items in Outlook 2007, that code might not behave well in Outlook 2010. That is exactly what happened to this individual who recently posted to the VSTO forum.

    The command bar object model (which most folks use to muck around with menus) has been deprecated in Outlook 2010. You can see a list of deprecated objects here - Outlook 2010 Object Model Changes Since Earlier Versions. Note that you can still use command bars, but be warned that “mileage may vary” and “objects in the mirror are closer than they appear”. etc. etc. You get the point.

    Nice, so if not the command bar object model, then what? Well, for Outlook 2010 anyway, the answer is Ribbon XML.

    In this post, I will show you how to show and hide items in a context menu by using Ribbon XML. The context menu appears when a user right-clicks an Outlook folder.

    First, add a Ribbon XML item to your Outlook 2010 project.

    image

    Then add the following code to your ThisAddIn class. This example assumes that your Ribbon is called Ribbon1 and that you are using C#:

    protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()

    {

        return new Ribbon1();

    }

    Next, replace the contents of the Ribbon1.xml file with the following:

    <?xml version="1.0" encoding="UTF-8"?>

    <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">

        <contextMenus>

            <contextMenu idMso="ContextMenuFolder">

                <button idMso="FolderPropertiesContext" getVisible="IsVisible" />

            </contextMenu>

        </contextMenus>

    </customUI>

    Just to clarify, "FolderPropertiesContext" is the control identifier of the Properties command in the context menu.  You can obtain the complete list of control identifiers here - Office 2010 Help Files: Office Fluent User Interface Control Identifiers. So you can show/hide/enable/disable just about anything you want.

    When Outlook is about to display the Properties command, Outlook first consults a cool method that you are going to write called "IsVisible".  You can name your method anything you want. You could name it "ShouldIShowThisMethodOrShouldINotShowThisMethod" or "NormsExamplesAreAlwaysVeryCoolandUseful“.  Totally up to you. It’s only important that you use the correct method signature.

    So let’s write the ”IsVisible” method. Add the following method to the Ribbon1.xml file.

    public bool IsVisible(Office.IRibbonControl control)
    {
        string foldername = ((Microsoft.Office.Interop.Outlook.Folder)control.Context).Name;
        if (foldername == "Inbox")
        {
            return false;
        }
        return true;
    }

    This code grabs the context of the control that is passed into the method. In this case, the context is the currently selected folder.

    If the user right-clicks the Inbox folder, then we tell Outlook to not show the command by returning false. Otherwise, we tell Outlook to go ahead and make the command visible by returning true.

    But wait. There’s more!

    After the first couple of times that you right-click a folder, Outlook takes a coffee brake and stops calling your method.  Actually, Outlook just caches the state of each control. If you want Outlook to call this method again, you have to “clear” that cache by “invalidating” the control.  Here is what I did to make that happen:

    First, provide access to the RibbonUI object in your ThisAddIn class. The RibbonUI object enables you to “invalidate” the Properties command of the folder context menu. Add the following code to the ThisAddIn class of your project:

    Office.IRibbonUI ribbonUI;
           
    public Office.IRibbonUI RibbonUI
    {
        get { return ribbonUI; }
        set { ribbonUI = value; }
    }

    Next, set the RibbonUI property of your ThisAddIn class within the Ribbon_Load event of the Ribbon code file as follows:

    public void Ribbon_Load(Office.IRibbonUI ribbonUI)
    {
        this.ribbon = ribbonUI;
        Globals.ThisAddIn.RibbonUI = ribbonUI;
    }

    Finally, in the ThisAddIn class, handle the FolderContextMenuDisplay event of the Application object.

    In the event handler of this event, “invalidate” the “FolderPropertiesContext” control.

    Outlook.Application app;
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        app = this.Application;
        app.FolderContextMenuDisplay += new Outlook.ApplicationEvents_11_FolderContextMenuDisplayEventHandler(app_FolderContextMenuDisplay);
     
    }
    
    void app_FolderContextMenuDisplay(Office.CommandBar CommandBar, Outlook.MAPIFolder Folder)
    {
        RibbonUI.InvalidateControlMso("FolderPropertiesContext");
    }    

    You can find other useful info about how to extend the Outlook user interface here Extending the User Interface in Outlook 2010.

  • Office Development with Visual Studio

    Changes in the Security Model for Office Solutions (Mary Lee)

    • 3 Comments

    You can use two methods to trust an Office solution created in Visual Studio and not show a trust prompt to the end-user.

    1. Sign your Office solution with certificate that chains to a trusted root authority and is in the Trusted Publisher list.
    2. Sign your Office solution with a certificate and trust that certificate by using the inclusion list.

    (There is a third option to use the ClickOnce trust prompt and allow the end-user to choose whether to trust and install the Office solution.)

    The first option is still the same: sign Office solutions with a certificate from a certificate authority and then add the certificate to the Trusted Publisher list.

    The second option has changed slightly in Visual Studio 2010 and the VSTO 2010 runtime. You can still use the inclusion list for Office 2007 and Office 2010 solutions, but you must target the .NET Framework 3.5 and reference the Microsoft.VisualStudio.Tools.Office.Runtime.v10.0 assembly.

    For .NET Framework 4 developers, you can deploy your solutions by using Windows Installer (MSI) into the Program Files directory. Office solutions installed to the Program Files directory are now considered to be already trusted because installing to the Program Files directory requires administrator rights. As a result, the Microsoft Office application loads the Office solution without checking the inclusion list. In addition, eliminating the inclusion list check may reduce the loading time.

    How does this affect me?

    If you deploy an Office 2007 solution by using Windows Installer (MSI) on a computer with Office 2010 and the VSTO 2010 runtime, your installer may show the following error: Error 1001. Could not load file or assembly 'Microsoft.VisualStudio.Tools.Office.Runtime.v9.0, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

    This error appears because the Microsoft.VisualStudio.Tools.Office.Runtime.v9.0.dll assembly is not in the VSTO 2010 runtime. To work around this issue, you can complete one of the following steps:

    1. Update the inclusion list custom action to reference the Microsoft.VisualStudio.Tools.Office.Runtime.v10.0 assembly. At this point, you may have one installer for computers with Office 2007 and the VSTO 3 runtime, and a second installer for computers with Office 2010 and the VSTO 2010 runtime.
    2. Remove the inclusion list custom action from your MSI and install to the Program Files directory. The VSTO 2010 runtime considers all Office solutions installed to the Program Files directory to be trusted already, so the ClickOnce trust prompt does not appear.
    3. Install both the VSTO 3 runtime and VSTO 2010 runtime on the computer. This way, the correct assembly is located on the end-user computer, and the installer can create the inclusion list entry for the certificate.

    Happy deployment!

    Mary Lee, Programming Writer.

  • Office Development with Visual Studio

    Tricks with app.config and ClickOnce deployment (Saurabh Bhatia)

    • 3 Comments
    Storing settings in the config File

    The app.config file is used for many purposes and one of common uses is for storing application settings like connection strings. For example, you can store a string to the web service reference used by your application in the app.config file.

    The idea behind storing the string in the app.config is that you could simply replace the file and change the value of the string. Thus, if you change the web service URL, you could simply replace the app.config and pick up the new URL without recompiling your application.

    This is also useful in scenarios where you have a test or development environment where you test your application in a controlled environment before deploying it to a production environment where it connects to a live server. For the development environment, the web service could be running on http://localhost. However when you go live, it could be on a machine like http://mysite.com/

     

    Deploying through ClickOnce

    Typically, it should be easy to swap out the config file such and replace the string value with the one for the live site when you are deploying to a live environment. However, things get interesting if you are using ClickOnce to deploy your application.

    ClickOnce uses manifests that contain hashes to all the files that are being deployed as part of the application. If you change any of the files, the hashes would break and the installation is stopped. So replacing the file after you have published the solution and generated ClickOnce manifests does not succeed. If you replace a file, you must also update the ClickOnce manifests to point to the updated version of the file and re-sign both manifests. This is true for any scenario where you change a file that is going to be published.

     

    Updating the app.config manually

    You can manually change the app.config file and then update the manifests with the new hash. Then, you must re-sign the manifests before re-publishing your ClickOnce application or solution. The updating and re-signing process for the ClickOnce manifests are explained in more detail here in this post.

    One benefit of this option is that an IT administrator can use this process to update a ClickOnce solution without using Visual Studio.

    Updating the app.config by using the the Settings Designer

    An alternative to doing the file replacement after publishing is to change the file before the publishing step in Visual Studio. This ensures that the correct file gets picked up when you are generating the manifest in the first place. The most obvious manual way to do this is to change the setting value in the Settings Designer, which in turn updates the app.config with the string value for the production environment.

    Updating the app.config by using build configurations

    There are some tricks you could use so that a different file with the values to the production server get picked up during publish.

    You can have two separate config files one for local deployment/debugging and one for a real published or production version of the application. The debugging config file could point to the localhost server whereas the real published config file could point to the real server. You can then configure the build configurations such that the appropriate config file is picked up depending on the Active build configuration.

    To add two different app.config files to the project, you can update the reference to app.config in your project file. The app.config is defined in the project file (vbproj or csproj) with the following xml:

    <ItemGroup>

    <None Include="app.config" />

    </ItemGroup>

    There may be other nodes in the ItemGroup along with the app.config node. Delete the just app.config from this ItemGroup node and create a new ItemGroup under the <Project> node with the following xml:

      <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

        <None Include="app.config" />

      </ItemGroup>

      <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

        <None Include="published\app.config" />

      </ItemGroup>

    This basically means that the regular app.config file will be used when the Active configuration is set to Debug and the modified app.config with the real production variables stored in the “published\” subfolder of the project is used when the active configuration is set to “Release”.

    You can change the ItemGroup conditions to match other build configurations that you may have defined. One possibility is to have a separate “Publish” configuration defined based on the “Release” configuration but only used when you are actually going to publish an application. 

    An additional disclaimer with this process is that the VS project system itself and the designers are not aware of the additional app.config file; Visual Studio is only aware of the original file. The modified app.config with values for a production environment is only used by the msbuild process. So if you update the main app.config through the Settings Designer, the modified app.config will not be updated and you have to manually update the file.

    Once you have configured your project appropriately you can simply switch between the different build configurations to change the config file and publish the application from Visual Studio without having to go through the update and re-sign process.

    Conclusion

    ClickOnce uses hashes to detect changes in the files (including the app.config file), and the hashes are stored in the manifests. If you need to update a ClickOnce application and the app.config file to say change a web service URL while moving from a test server to a production server, you can use three different ways to update the manifests and app.config file.

    1. Manually edit the manifests to point to the app.config file and update the hash. Then, re-sign the manifests.

    2. Use the Settings Designer to select the correct app.config file and republish the solution by using Visual Studio.

    3. Create a build configuration for each app.config file and include the correct app.config file.

  • Office Development with Visual Studio

    Deploying your VSTO add-ins to All Users (Saurabh Bhatia)

    • 50 Comments

    An often-requested feature for VSTO add-ins is the ability to install an add-in for all users of a machine. Misha Shneerson had blogged about a workaround to enable this scenario here. This workaround is not recommended. Now, deploying an add-in to All Users is supported for both Microsoft Office 2007 (through a hotfix) and Microsoft Office 2010.

    Office 2010

    With Office 2010, it is possible to directly register a VSTO add-in under the HKLM Office add-ins registry hive such that the add-in gets installed machine wide for all users of the machine.

    The registry keys under HKLM are very similar to the registry keys for the current user as described in this MSDN topic. Each Office application has its own node at the following location where it will try to load add-ins that are installed machine wide:

    e.g. HKEY_LOCAL_MACHINE\Software\Microsoft\Office\application name\Addins\add-in ID

    These machine wide add-ins load and behave similar to add-ins that are installed per user, However, there are some important differences you should remember when deploying such add-ins.

    1) You need administrative privilege on the machine in order to install an All User add-in.

    End users running with current user privilege cannot install/uninstall or disable an add-in. This could potentially lead to a worst case scenario where an add-in fails unexpectedly resulting in the host Office application crashing, and the end user cannot do anything to stop the Office application from crashing because they cannot disable the add-in causing the crash. So, make sure your add-in is thoroughly tested before deploying to it to all users of a machine.

    2) An all user add-in cannot be deployed through ClickOnce and must be deployed through a Windows Installer MSI.

    Writing to HKLM requires administrative privileges, so you cannot use ClickOnce to deploy your add-in because ClickOnce only works with current user privileges. This means that you need to create your own MSI package that registers the add-in under HKLM and installs it for all users. This whitepaper and MSDN topic should give you the necessary background information to create a MSI package for your VSTO solution. The most important thing to remember while creating this all user installation is to always append a “|vstolocal” to the manifest registry value pointing to the add-ins deployment manifest location.

    e.g. manifest = “C:\Program Files\MyVSTOAddIn\MyVSTOAddIn.vsto|vstolocal“

    Appending the “|vstolocal” tells VSTO to run the solution from the installation folder (like C:\Program Files\MyVSTOAddIn) instead of installing and running it from the ClickOnce cache.

    3) Trusting the Add-In for all users

    To trust an add-in for all users of a machine, it must be signed with a Trusted Publisher’s Certificate (See Authenticode Certificates in Granting Trust to Office Solutions and How to: Add a Trusted Publisher to a Client Computer for ClickOnce Applications for more information). If the add-in is not signed with a trusted publisher’s certificate, each individual user sees the Microsoft Office Customization Installer dialog box (aka trust prompt) asking them whether they want to install the add-in the very first time the add-in is loaded for them. If they choose to install the add-in, the add-in will run and they will not be prompted again. However ,if they choose to not install the add-in, the add-in will not load and they will continue to see this trust prompt every time they open up the Office application and the add-in tries to load. If you are developing your solution with Visual Studio 2010 and targeting .NET 4, an alternative to signing with a Trusted Publisher certificate is to install the add-in into the machine Program Files location. This location also needs administrative privilege to write to and will be inherently trusted by VSTO, so there will be no trust prompt even if the solution is not signed with a Trusted Publisher certificate.

    4) Installing on 64-bit Operating Systems

    Unlike the HKCU registry hive, the HKLM registry hive for Office add-ins is redirected on a 64-bit Windows OS. So if you are trying to register an add-in with 32-bit version of Office running on a 64-bit OS, the add-ins registry will be under the WOW6432Node. The 32-bit Office running on 64-bit OS will always load the add-ins listed under this key.

    e.g. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\application name\Addins\add-in ID

    A 64-bit version of Office 2010 on 64-bit OS will always load the add-ins under this key:

    e.g. HKEY_LOCAL_MACHINE\Software\Microsoft\Office\application name\Addins\add-in ID

    With the ability to directly register and load VSTO add-ins from the HKLM hive on Office 2010, you can easily deploy VSTO add-ins to all users of a machine and no longer need to follow the steps outlined in Misha’s blog

    Update for Office 2007
    A recent hotfix (KB976811 available through KB976477) for Office 2007 also makes it possible to register and load VSTO add-ins under HKLM for Office 2007. The process works exactly like Office 2010 but to make this work for Office 2007 you will have to download and install the hotfix on every machine where you want to deploy the all user add-in.

    In conclusion, you can install an Office2007 or Office 2010 add-in to All Users if you use Windows installer to deploy your add-in and the add-in is installed with administrative privileges. To secure your All Users add-in, sign your Office add-in with a certificate that is in the Trusted Publisher list or install the add-in to the Program Files directory.

  • Office Development with Visual Studio

    Office Development with Visual Studio Tutorial Series – Part 4 (Beth Massi)

    • 0 Comments

    A couple months ago Robert Green, VSTO MVP, started a series of step-by-step tutorials on building on Office 2007. Part 4 is now published. Thanks Robert!

    In this fourth part of the series of tutorials on Office Business Applications, learn how to create an Excel 2007 solution using Visual Studio 2008 that generates reports from a database and allows you to take those reports offline. This tutorial shows you how to cache the set of data directly in the Excel workbook and also shows you how to easily print the data as a PDF. This step-by-step tutorial also includes full source code in Visual Basic & C#. Check out the tutorial on the VSTO Developer Center:

    Building an Office Business Application Part 4 – Generating Reports

    And if you missed the previous tutorials:

    These tutorials are pretty popular so if you’re just getting started with Office development in Visual Studio, this is a great place to start.

    Enjoy,
    -Beth Massi, Visual Studio Community

  • Office Development with Visual Studio

    Taking COM Shim Wizards to 64-bit (Beth Massi)

    • 0 Comments

    When you build a managed Office extension of any kind, you should ensure that your extension is isolated from other extensions that might be loaded into the application. You do this by creating a custom shim. VSTO solutions do not require custom shims because the VSTO runtime includes default shim functionality. However, if you are writing your own managed shared add-in you will need to write your own shim.

    The COM Shim Wizards automate the generation of COM shims for managed shared add-ins. Now that Office 2010 ships with a 64-bit version you’re probably wondering how to support it in your shared add-ins. If you’re using these wizards then you’ll want to read Misha’s latest post on how to get a working 32-bit shim wizard to work with 64-bit of Office. Thanks Misha!

    Enjoy,
    -Beth Massi, Visual Studio Community

Page 1 of 1 (6 items)