Geert Bellekens

Freelance UML and Enterprise Architect consultant

Posts Tagged ‘sharpdevelop’

Tutorial: Deploy your Enterprise Architect C# add-in with an MSI package

Posted by Geert Bellekens on 23/02/2011

In previous posts I talked about Creating and Testing your Enterprise Architect C# add-in, and how to use the C# add-in template to speed up the development process.

Once created and tested you’ll probably want to install and use the add-in on other computers then your development machine. This tutorial explains how to create an MSI installer package using the open source SharpDevelop and WiX software.

The reason I’m using SharpDevelop as opposed to Visual Studio C# Express is because SharpDevelop is free and open source, and Visual Studio C# Express doesn’t allow to create setup projects, or attach to a running process to debug your add-in.

Requirements

The plan

As explained in Tutorial: Create your first C# Enterprise Architect addin in 10 minutes we need our installer to do three things for us:

  1. Copy the dll’s to a program folder.
  2. Register the add-in dll for COM Interop so Windows knows where to find the add-in dll.
  3. Create the registry key so EA knows about our add-in.

Step 1: Create a setup project

  • Open the solution for your add-in in SharpDevelop. If you have developed the add-in with Visual Studio, that fine. Sharpdevelop uses the exact same project setup as Visual Studio, with the .sln and .csproj files
  • Add a new project and choose for Setup Project – WixUI Minimal
    You can of course choose for another template, but for the purpose of this tutorial the WixUI Minimal is enough.

New WiX Setup Project

  • SharpDevelop will now have created a new Setup project in your solution containing three files:
    • Files.wxs
      This is were we define wich files and registry keys the installer needs to install
    • license.rtf
      Contains the license for your software
    • Setup.wxs
      Where we define the general setup of the installer like the name, and the components to install.MyAddinProject

Step 2: Edit Setup.wxs

Next we’re going to tell the installer about the application it will install. The .wxs files are actually XML files, and you can edit them directly in SharpDevelop.

  • Open Setup.wxs and edit the highlighted parts
    Setup.wxs
    Notice that we also added a ComponentRef for MyAddinRegEntries.

Step 3: Add the program files

  • Open up the setup files view with View|Setup|Files
  • Rename the installation folder to something sensible
  • Add a component for each ComponentRef we added in the Setup.wxs
  • Right-click on the MyAddinFiles component and choose Add Files…
    MyAddinAddFiles
  •  Now browse to the MyAddin project folder and select all files in the MyAddin\bin\debug or MyAddin\bin\release folder, depending on how you last built your project.
    Not all of these files might be necessary, but I can’t be bothered to figure out exactly which files we need to install the add-in on another computer.
  • This should now have created a line in the files.wxs for each binary file similar to
    <File Id="EAAddinFramework.dll" Name="EAAddinFramework.dll" Source="..\MyAddin\bin\Debug\EAAddinFramework.dll" />
    <File Id="UMLToolingFramework.dll" Name="UMLToolingFramework.dll" Source="..\MyAddin\bin\Debug\UMLToolingFramework.dll" />
    <File Id="EAAddinFramework.pdb" Name="EAAddinFramework.pdb" Source="..\MyAddin\bin\Debug\EAAddinFramework.pdb" />
    <File Id="Interop.EA.dll" Name="Interop.EA.dll" Source="..\MyAddin\bin\Debug\Interop.EA.dll" />
    <File Id="MyAddin.pdb" Name="MyAddin.pdb" Source="..\MyAddin\bin\Debug\MyAddin.pdb" />
    <File Id="MyAddin.tlb" Name="MyAddin.tlb" Source="..\MyAddin\bin\Debug\MyAddin.tlb" />
    <File Id="UMLToolingFramework.pdb" Name="UMLToolingFramework.pdb" Source="..\MyAddin\bin\Debug\UMLToolingFramework.pdb" />
    <File Id="MyAddin.dll" Name="MyAddin.dll" Source="..\MyAddin\bin\Debug\MyAddin.dll" />
    

Step 4: Register MyAddin.dll for COM Interop

The MyAddin.dll is the add-in dll that EA needs to talk to, so this dll needs to be registered for COM Interop. This is the part that is done by regasm.exe when doing a manual installation, but we don’t want to be calling any executables on the target machine during install if we can avoid it. Instead we will just add the same registry keys that regasm.exe creates.

  • Open a command prompt in the folder where MyAddin.dll is located (bin\Debug\)
  • Execute following command:
    "C:\Program Files (x86)\WiX Toolset v3.8\bin\heat.exe" file MyAddin.dll -ag -template fragment -out MyAddin.wxs

    This will have created a file in the same folder with the name MyAddin.wxs.

  • Open that file and copy the contents of the Component tag:
    <Class Id="{10BC65F1-32C0-3ED4-98A0-17661A8C4455}" Context="InprocServer32" Description="MyAddin.MyAddinClass" ThreadingModel="both" ForeignServer="mscoree.dll">
     <ProgId Id="MyAddin.MyAddinClass" Description="MyAddin.MyAddinClass" />
    </Class>
    <File Id="filCC4172BEC1312562EDEF49648E45AE0D" KeyPath="yes" Source="..\MyAddin\bin\Debug\MyAddin.dll" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="Class" Value="MyAddin.MyAddinClass" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="Assembly" Value="MyAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC4172BEC1312562EDEF49648E45AE0D]" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="Class" Value="MyAddin.MyAddinClass" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="Assembly" Value="MyAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="CodeBase" Value="file:///[#filCC4172BEC1312562EDEF49648E45AE0D]" Type="string" Action="write" />
  • Replace the file tag for MyAddin.dll in your files.wxs by the copied part
  • Add a Name attribute Name=”MyAddin.dll to the file tag for MyAddin.dll so the tag looks like:
    <File Id="filCC4172BEC1312562EDEF49648E45AE0D" Name="MyAddin.dll" KeyPath="yes" Source="..\MyAddin\bin\Debug\MyAddin.dll" /> 

Step 5: Add the EA Addin registry key

This step will instruct the installer to create the add-in registry key that tells EA there is an add-in to load

  • Add following Registry key tag to the MyAddinRegEntries tag in the Files.wxs
    <RegistryKey Root="HKCU" Key="Software\Sparx Systems\EAAddins\MyAddin" Action="createAndRemoveOnUninstall">
    <RegistryValue Type="string" Value="MyAddin.MyAddinClass" />
     </RegistryKey>
    

All xml file editing should now be behind us. The complete Files.wxs should look something like:

<?xml version="1.0"?>
   <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
     <Fragment>
       <DirectoryRef Id="TARGETDIR">
         <Directory Id="ProgramFilesFolder" Name="PFiles">
           <Directory Id="INSTALLDIR" Name="MyAddin">
             <Component Id="MyAddinFiles" Guid="5C526B21-FB62-42AD-9897-F990FEA7E164" DiskId="1">
               <File Id="EAAddinFramework.dll" Name="EAAddinFramework.dll" Source="..\MyAddin\bin\Debug\EAAddinFramework.dll" />
               <File Id="UMLToolingFramework.dll" Name="UMLToolingFramework.dll" Source="..\MyAddin\bin\Debug\UMLToolingFramework.dll" />
               <File Id="EAAddinFramework.pdb" Name="EAAddinFramework.pdb" Source="..\MyAddin\bin\Debug\EAAddinFramework.pdb" />
               <File Id="Interop.EA.dll" Name="Interop.EA.dll" Source="..\MyAddin\bin\Debug\Interop.EA.dll" />
               <File Id="MyAddin.pdb" Name="MyAddin.pdb" Source="..\MyAddin\bin\Debug\MyAddin.pdb" />
               <File Id="MyAddin.tlb" Name="MyAddin.tlb" Source="..\MyAddin\bin\Debug\MyAddin.tlb" />
               <File Id="UMLToolingFramework.pdb" Name="UMLToolingFramework.pdb" Source="..\MyAddin\bin\Debug\UMLToolingFramework.pdb" />
               <Class Id="{10BC65F1-32C0-3ED4-98A0-17661A8C4455}" Context="InprocServer32" Description="MyAddin.MyAddinClass" ThreadingModel="both" ForeignServer="mscoree.dll">
                 <ProgId Id="MyAddin.MyAddinClass" Description="MyAddin.MyAddinClass" />
               </Class>
               <File Id="filCC4172BEC1312562EDEF49648E45AE0D" Name="MyAddin.dll" KeyPath="yes" Source="..\MyAddin\bin\Debug\MyAddin.dll" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="Class" Value="MyAddin.MyAddinClass" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="Assembly" Value="MyAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC4172BEC1312562EDEF49648E45AE0D]" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="Class" Value="MyAddin.MyAddinClass" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="Assembly" Value="MyAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
               <RegistryValue Root="HKCR" Key="CLSID\{10BC65F1-32C0-3ED4-98A0-17661A8C4455}\InprocServer32" Name="CodeBase" Value="file:///[#filCC4172BEC1312562EDEF49648E45AE0D]" Type="string" Action="write" />
             </Component>
             <Component Id="MyAddinRegEntries" Guid="8439A7F4-D42F-43AC-B91D-CBF823A89DDE">
              <RegistryKey Root="HKCU" Key="Software\Sparx Systems\EAAddins\MyAddin" Action="createAndRemoveOnUninstall">
                <RegistryValue Type="string" Value="MyAddin.MyAddinClass" />
              </RegistryKey>
            </Component>
          </Directory>
        </Directory>
      </DirectoryRef>
    </Fragment>
 </Wix>

Step 6: Fill in the license details

  • Open license.rft in wordpad, or another rtf editor and fill in the license details
    Do NOT use Microsoft Word to edit the license.rtf as Word will make a horrible mess of the rtf file.

Step 7: Build and test your setup project

Now all we need to do is build and test the setup project. You can run it right from within Sharpdevelop.

If all is well you should see something similar to this:

More resources

Related blog posts

Source code on GitHub

Sparx Systems

Other

  • Examples in the EA installation folder: C:\Program Files\Sparx Systems\EA\Code Samples

Posted in Sparx Systems Enterprise Architect | Tagged: , , , , , , , , , , | 19 Comments »

 
Follow

Get every new post delivered to your Inbox.

Join 230 other followers

%d bloggers like this: