Renat Tlebaldziyeu

Outlook Security Manager 2010 deployment: Reg Free COM & ClickOnce for Outlook 2010 64-bit, part 5

In this article I am going to explain how to deploy a standalone application that uses the Outlook Security Manager to automate Outlook 32bit and 64bit via ClickOnce.

First off, I advise that you read through Part 1: Outlook Security Manager 2010 deployment: .net, ActiveX and VCL basics. You will learn that for a successful operation of your standalone application on a target PC, you need to register either secman.dll or secman64.dll depending on the bitness of your Outlook. You will also learn that for Outlook 32-bit, your application must be compiled for an x86 platform, and for Outlook 64-bit – for an x64 platform.

How to register the proper COM dll on a target PC with ClickOnce? Outlook Security Manager must be registered as a COM component on the end-user’s PC. This adds some problems to the process of including your add-in in the installer since you need to write pertaining information to the Windows registry during installation. The Reg Free COM technology allows you to avoid such necessity by using the manifest file in the xml format. In this way the installation of your application becomes much simpler. Before using Reg Free COM in your application, I’d recommend that you learn more about the technology from MSDN Magazine, April 2005 and MSDN library’s article.

Basing on the information from those articles, I’ve tried to add a new reference to secman64.dll, set the Isolated property to True for the given reference and … my project stopped compiling… I got this error: “Problem isolating COM reference ‘secman64Lib’: No registered classes were detected for this component”. No wonder, Visual Studio that works as an x86 process cannot see an x64 COM library. What shall we do in this case?

If you do the same with the 32-bit version of secman (secman.dll), you will notice that when setting Isolated to True, the following XML element is included in the manifest file of your application:

<file name="secman.dll" asmv2:size="144664" xmlns="urn:schemas-microsoft-com:asm.v1">
    <typelib tlbid="{11549fe4-7c5a-4c17-9fc3-56fc5162a994}" version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />
   <comClass clsid="{826d7151-8d99-434b-8540-082b8c2ae556}" threadingModel="Apartment" tlbid="{11549fe4-7c5a-4c17-9fc3-56fc5162a994}"
       progid="secman.OutlookSecurityManager" description="OutlookSecurityManager Class" />
</file>

By analogy, I created the same XML element for secman64.dll (I got all necessary information from the Windows registry):

<file name="secman64.dll" asmv2:size="126744" xmlns="urn:schemas-microsoft-com:asm.v1">
    <typelib tlbid"{2C8CCB3A-CE4F-40A2-AA1C-E891338BF189}" version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />
   <comClass clsid="{2F35794D-4574-4BCF-B0A5-3B16AF985788}" threadingModel="Apartment" tlbid="{2C8CCB3A-CE4F-40A2-AA1C-E891338BF189}"
    progid="secman64.OutlookSecurityManager64" description="OutlookSecurityManager64 Class"/>
</file>

So, depending on your Outlook bitness, you need to add one of these elements to the manifest file of your application on a target PC.

Step-by-step instructions:

1. Add 2 dlls (secman.dll and secman64.dll) to your project via Project –> Add Existing Item… (You can find these dlls in the Redistributables subfolder of the Outlook Security Manager installation folder)

2. Set the Copy Local property to True for the SecurityManager.2005 reference. This  reference should be added automatically after you place the Security Manager component onto your form, if not, just add it through Project –> Add reference…

3. You need to modify the manifest file of your application on the target PC accordingly, by correcting or adding the above XML element for secman.dll or secman64.dll.

You’d better do this in the initialization code at the start of your application.  IsNetworkDeployed property and IsFirstRun property will help you in this. They will return True at the first launch of your application on the target PC. Also, please don’t forget that after correcting the manifest file, you will need to restart your application because, as Microsoft states, “Windows builds an internal table that relates each identifier (CLSID) to its corresponding component file early in CreateProcess, before any application code is run”.

I wrote the ManifestFix.exe utility which you can use to perform all needed actions described above. As input arguments, you need to pass ProcessID (ID of your application’s process) and a path to the executable:

ManifestFix.exe {ProcessID} {Path to executable }

You can find the utility and its source files at the end of this article.

In the ManifestFix.exe utility, I allowed for the second condition too – for Outlook 32-bit, your application must be compiled under an x86 platform, for Outlook 64-bit – under x64. I used the CorFlags Conversion Tool for this. We have already used a similar method in part 4 of this series Outlook Security Manager 2010 deployment: compiling a standalone application with “AnyCPU”.

So, add 2 files to your project – CorFlags.exe (you can find it in the {SDK}\v2.0\Bin directory) and ManifestFix.exe. Add the following code to the initialization code of your application:

C#:

using System.IO;
using System.Diagnostics;
using System.Reflection;
...
 
try
{
    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed &&
        System.Deployment.Application.ApplicationDeployment.CurrentDeployment.IsFirstRun)
    {
        string ManifestFixPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ManifestFix.exe");
        Process ManifestFixProc = null;
        try
        {
            ManifestFixProc = new Process();
            ManifestFixProc.StartInfo.FileName = "\"" + ManifestFixPath + "\"";
            ManifestFixProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            ManifestFixProc.StartInfo.Arguments = Process.GetCurrentProcess().Id + " \"" + Assembly.GetExecutingAssembly().Location + "\"";
            ManifestFixProc.Start();
            Process.GetCurrentProcess().Kill();
        }
        catch { }
    }
}
catch { }

VB.NET:

Imports System.IO
Imports System.Diagnostics
Imports System.Reflection
...
 
Try
    If (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed And _
        System.Deployment.Application.ApplicationDeployment.CurrentDeployment.IsFirstRun) _
    Then
        Dim ManifestFixPath As String = _
            Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ManifestFix.exe")
        Dim ManifestFixProc As Process = Nothing
        Try
            ManifestFixProc = New Process()
            ManifestFixProc.StartInfo.FileName = """" + ManifestFixPath + """"
            ManifestFixProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
            ManifestFixProc.StartInfo.Arguments = Process.GetCurrentProcess().Id.ToString() + " """ + _
               Assembly.GetExecutingAssembly().Location + """"
            ManifestFixProc.Start()
            Process.GetCurrentProcess().Kill()
        Catch
        End Try
    End If
Catch
End Try

The code launches the ManifestFix.exe utility with parameters: Process.GetCurrentProcess().Id (ID of the current process) and a path to the executable file.

4. Now you can publish your application (Solution Properties –> Publish).

How does ManifestFix.exe work?

As input parameters, the following ones are accepted: 

  • ID of the current process of your standalone application
  • path to the executable file of your standalone application

First, the utility waits for the completion of the process with the ID that was passed as an input parameter. After the process is completed, a corresponding manifest file is opened and required XML elements are added into it (the XML elements are replaced if they already exist). After that, the CorFlags Conversion Tool is run, if needed. And finally, your standalone application is launched using the path passed in the second parameter.

In the code of my ManifestFix.exe utility, I used the Is64BitOutlook() function, you can find more information about it in Outlook Security Manager 2010 deployment: bitness and regsvr32 utility, part 2. Also I rely on IntPtr.Size – the value of this property is 4 on a 32-bit platform, and 8 on a 64-bit platform.

Available downloads:

ManifestFix.zip
ManifestFix source (C# solution)
ManifestFix source (VB solution)

13 Comments

  • Ryan Farley says:

    Thanks. This is a very useful article. I do want to clarify one thing. You mention the following:

    “In the ManifestFix.exe utility, I allowed for the second condition too – for Outlook 32-bit, your application must be compiled under an x86 platform, for Outlook 64-bit – under x64. I used the CorFlags Conversion Tool for this.”

    Are you saying that we DO have to target the addin for a specific CPU or that you are flipping the bit using CorFlags (and we can still build for AnyCPU, is this right?)

    Can you clarify this?

    Thanks!

  • Renat Tlebaldziyeu (Add-in Express Team) says:

    Thanks, Ryan!

    Yes, you are right, if you deploy a standalone application, you can still build for AnyCPU using the CorFlags Conversion Tool to configure the bitness flag depending on the Outlook bitness. If you do not use the CorFlags Conversion Tool, then you should build your application with “x64” for Outlook 64-bit and with “x86” for Outlook 32-bit.

    But if you deploy an add-in (not a standalone application), you needn’t use CorFlags, you can always build your add-in for AnyCPU.

  • Ryan Farley says:

    Got it. What I am trying to do is use Reg-Free COM with Outlook Security Manager (secman.dll and secman64.dll) with a ClickOnce deployed ADX Outlook addin.

    I am trying to follow the series of posts regarding using RegFree COM with Outlook Security Manager but getting lost along the way somewhere. I don’t suppose you have some complete list of steps somewhere or demo project I could download that covers how to do this for a ClickOnce deployed Outlook addin that needs to target Outlook 2010 32 and 64 bit?

    Thanks

  • Ryan Farley says:

    Also, when I attempt to use the code above to use the ManifestFix.exe, these lines:

    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed && System.Deployment.Application.ApplicationDeployment.CurrentDeployment.IsFirstRun)

    throw an error that “Application identity is not set”. I am deploying the addin via ClickOnce.

  • Renat Tlebaldziyeu (Add-in Express Team) says:

    Ryan,

    If you deploy an ADX-based add-in via ClickOnce with Add-in Express 2010 for Office and .net, you needn’t use ManifestFix.exe or register dlls manually.
    If you have a SecurityManager.2005.dll reference in your project, then after selecting “Publish ADX Project” from the Build menu and clicking the Populate button in the “Publish” dialog window, you will see that the secman.dll and secman64.dll files were added automatically to the Files list for publishing. They will also get registered automatically when your add-in is installed on the end-user PC. It’s a feature of Add-in Express 2010 :)

  • Ryan Farley says:

    Yes, I am using it that way now. The problem is that the registration fails on occasion, so I was wanting to use reg-free COM for these and avoid the registration, but getting lost trying to piece together the relevant parts from the various articles in this series.

  • Renat Tlebaldziyeu (Add-in Express Team) says:

    Could you please send a sample addin project that can reproduce the issue to the support e-mail address (see readme.txt in the Add-in Express installation folder)? Please make sure your e-mail contains a link to this article. Also, please specify what versions (and bitness) of OS and Outlook you use on the problematic PC.

  • Mike VE says:

    Hi

    Like Ryan I want to deploy an add-in with both secman and secman64 but via an MSI. (A lot of my clients use proxy server which obstruct Click-Once). If I do it the way described in your very useful articles it all works fine but the resulting MSI fails if run ny a non admin user – there is a warning that secman has failed to register and although the setup completes the addin is not loaded by Outlook.

    If I could find a way to use registration free COM for both secman and secman64 then an ordinary user could install the add-in

  • Renat Tlebaldziyeu (Add-in Express Team) says:

    Hello Mike,

    Yes, you need to have the administrative permissions to register “secman.dll” or “secman64.dll”. Sorry, I don’t know any way to use registration free COM. You can try using Outlook Security Manager without registration, it’s a new feature introduced in the latest build of Security Manager 2010 (2010.6.1.3016) and it is still on the testing stage; but possibly, it will work for you.You can download the latest build from the Outlook Security Manager download page.

    To deploy your project without registering Security Manager dlls, please execute the following steps:

    1. Include the SecurityManager.2005.dll assembly in your setup package. This assembly should be placed into a folder where all your deployed assemblies are located.
    2. Include two redistributable libraries – secman.dll and secman64.dll – put them either into the shared folder of Windows, “[Common Files Folder]\Outlook Security Manager” or into your application folder.
    3. That’s all. You don’t need to register any dlls.

  • Doron says:

    Hello

    You are checking System.Deployment.Application.ApplicationDeployment.CurrentDeployment.IsFirstRun

    But how can I deploy update (new version) of secman.dll and secman64.dll ?

    Now it is note deploying the new version because IsFirstRun is true after installing ClickOne the first time

    Please Advise

  • Andrei Smolin (Add-in Express Team) says:

    Doron,

    At https://msdn.microsoft.com/en-us/library/system.deployment.application.applicationdeployment.isfirstrun%28v=vs.110%29.aspx, they say this: The value of this property is reset whenever the user upgrades from one version to the next.

    The article above describes installing/uninstalling secman.dll (secman64.dll) using RegFree COM and ClickOnce. That is, you register the corresponding DLL by deploying the application and unregister the DLL by uninstalling the application.

  • Chris Dewar-English says:

    I notice above that in your response to Mike that it is possible to use the security manager without registering the COM DLLs. If this is the case (using the version specified from 2010) doesn’t that feature make the entire blog post irrelevant? Why would using ClickOnce be necessary at all?

  • Andrei Smolin (Add-in Express Team) says:

    Hello Chris,

    You are almost right. You’ll need to register the DLLs if you use the ActiveX technology. As to ClickOnce, this is one of deployment technologies that a developer can use. You can find its description on the web, see e.g. https://msdn.microsoft.com/en-us/library/t71a733d%28v=vs.90%29.aspx.

Post a comment

Have any questions? Ask us right now!