{"id":21,"date":"2023-03-21T03:28:00","date_gmt":"2023-03-21T03:28:00","guid":{"rendered":"https:\/\/brunocm.azurewebsites.net\/?page_id=21"},"modified":"2025-10-09T14:50:37","modified_gmt":"2025-10-09T12:50:37","slug":"part-5-distribute-your-work-with-a-msi","status":"publish","type":"page","link":"https:\/\/brunocm.azurewebsites.net\/?page_id=21","title":{"rendered":"Part 5 &#8211; Distribute your work with a MSI"},"content":{"rendered":"<h1>Put all this into an MSI<\/h1>\n<p>To create an MSI that will let you distribute your extension, you will need 2 things :<\/p>\n<ul>\n<li>Wix Toolset ( freely available here =&gt; <a href=\"http:\/\/wixtoolset.org\/\"><u>http:\/\/wixtoolset.org\/<\/u><\/a> )<\/li>\n<li>And MSIExt that will bring few features not natively available in &#8220;Wix Toolset&#8221; but are mandatory for us. (here =&gt; <a href=\"http:\/\/dblock.github.io\/msiext\/\"><u>http:\/\/dblock.github.io\/msiext\/<\/u><\/a> )<\/li>\n<\/ul>\n<p>Even if we will create the simplest MSI possible (no wizard), this will be the longest part of this tutorial so please read it entirely before starting.<\/p>\n<p>First, download and install Wix toolset (it will be integrated into VisualStudio so don&#8217;t forget to close it before installing), then download and unzip it wherever you want.<\/p>\n<p>Re-open your VisualStudio project and add a new project (simple as File\/Add\/New project)<\/p>\n<p>Choose &#8220;Windows Installer XML&#8221; and select a &#8220;Setup Project&#8221;<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-56 size-medium\" src=\"\/wp-content\/uploads\/2023\/03\/image16-300x160.png\" alt=\"\" width=\"300\" height=\"160\" srcset=\"\/wp-content\/uploads\/2023\/03\/image16-300x160.png 300w, \/wp-content\/uploads\/2023\/03\/image16.png 430w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/p>\n<p>Don&#8217;t forget to give it a nice name before validating (I will simply name it &#8220;myExtSetup&#8221; here)<\/p>\n<p>A template is automatically created.<\/p>\n<p>If you want to understand every item it contains and how to make it reflect more your will, follow the tutorial provided on the Wix Toolset web site. This tutorial is really clear and simple to understand, I can&#8217;t do better (<a href=\"https:\/\/www.firegiant.com\/wix\/tutorial\/\"><u>https:\/\/www.firegiant.com\/wix\/tutorial\/<\/u><\/a>)<\/p>\n<p>Before start, we need to link the setup project with our dll project.<\/p>\n<p>Right-click on the setup project &#8220;References&#8221; item and choose &#8220;Add Reference\u2026&#8221;.<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-57 size-medium\" src=\"\/wp-content\/uploads\/2023\/03\/image17-300x68.png\" alt=\"\" width=\"300\" height=\"68\" srcset=\"\/wp-content\/uploads\/2023\/03\/image17-300x68.png 300w, \/wp-content\/uploads\/2023\/03\/image17.png 386w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/p>\n<p>Select the &#8220;Project&#8221; tab, highlight your project, Add it and close this window.<\/p>\n<p>Let&#8217;s look the first segment:<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Product<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"*\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"myExtSetup\"<\/span> <span style=\"color: #ff0000;\">Language<\/span><span style=\"color: #0000ff;\">=\"1033\"<\/span> <span style=\"color: #ff0000;\">Version<\/span><span style=\"color: #0000ff;\">=\"1.0.0.0\"<\/span> <span style=\"color: #ff0000;\">Manufacturer<\/span><span style=\"color: #0000ff;\">=\"\"<\/span> <span style=\"color: #ff0000;\">UpgradeCode<\/span><span style=\"color: #0000ff;\">=\"99ff1cbe-xxxx-xxxx-xxxx-6913cf65xxxx\"&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Package<\/span> <span style=\"color: #ff0000;\">InstallerVersion<\/span><span style=\"color: #0000ff;\">=\"200\"<\/span> <span style=\"color: #ff0000;\">Compressed<\/span><span style=\"color: #0000ff;\">=\"yes\"<\/span> <span style=\"color: #ff0000;\">InstallScope<\/span><span style=\"color: #0000ff;\">=\"perMachine\" \/&gt;<\/span>\n\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">MajorUpgrade<\/span> <span style=\"color: #ff0000;\">DowngradeErrorMessage<\/span><span style=\"color: #0000ff;\">=\"A newer version of [ProductName] is already installed.\" \/&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">MediaTemplate<\/span> <span style=\"color: #0000ff;\">\/&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Feature<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"ProductFeature\"<\/span> <span style=\"color: #ff0000;\">Title<\/span><span style=\"color: #0000ff;\">=\"myExtSetup\"<\/span> <span style=\"color: #ff0000;\">Level<\/span><span style=\"color: #0000ff;\">=\"1\"&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroupRef<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"ProductComponents\" \/&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Feature<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Product<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>These are general information about your MSI. Change the Name and the Manufacturer as you want but keep everything else as-is for now.<\/p>\n<p>Note that Id=&#8221;*&#8221; means that product Id will be automatically generated on build time. You don&#8217;t have to care about it. Upgrade code is much more important as this will be the key in case of multiple releases. If you keep the upgrade code unchanged and increment the Version number, you will be able to handle correctly automatic version replacement.<\/p>\n<p>Remember, our extension, like the console, is only 32bits. So add the Platform=&#8221;x86&#8243; property to the &#8220;Package&#8221; tag like this:<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Package<\/span> <span style=\"color: #ff0000;\">InstallerVersion<\/span><span style=\"color: #0000ff;\">=\"200\"<\/span> <span style=\"color: #ff0000;\">Compressed<\/span><span style=\"color: #0000ff;\">=\"yes\"<\/span> <span style=\"color: #ff0000;\">InstallScope<\/span><span style=\"color: #0000ff;\">=\"perMachine\"<\/span> <span style=\"color: #ff0000;\"><u>Platform<\/u><\/span><span style=\"color: #0000ff;\"><u>=\"x86\"<\/u><\/span> \/&gt;<\/pre>\n<p>If you want your\u00a0installer to include all file in a single MSI\u00a0file ( by opposition to an MSI with separate Cab files) modify &#8220;MediaTemplate&#8221; like this :<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">MediaTemplate<\/span> <span style=\"color: #0000ff;\">\/&gt;<\/span> =&gt; <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">MediaTemplate<\/span> <span style=\"color: #ff0000;\">EmbedCab<\/span><span style=\"color: #0000ff;\">=\"yes\" \/&gt;<\/span><\/pre>\n<p>A brief explanation about features and Components:<\/p>\n<ul>\n<li>every single object (like a file or a registry key) are components.<\/li>\n<li>Components can be grouped in a ComponentGroup<\/li>\n<li>A feature is a group of components that must be installed at once. This is what is presented to the user during a common install sequence to let them choose what they want. Components can be shared between different Features.<\/li>\n<\/ul>\n<p>We will create simple MSI with no graphical interface. As users won&#8217;t have any choice to make, a ingle feature will be enough.<\/p>\n<p>Change this section to something more adapted like :<\/p>\n<pre><span style=\"color: #3366ff;\">&lt;<\/span><span style=\"color: #993300;\">Feature<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #3366ff;\">=\"MyDeviceExt\"<\/span> <span style=\"color: #ff0000;\">Title<\/span><span style=\"color: #3366ff;\">=\"Device Right click extension\"<\/span> <span style=\"color: #ff0000;\">Level<\/span><span style=\"color: #3366ff;\">=\"1\"&gt;<\/span>\n   <span style=\"color: #3366ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroupRef<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #3366ff;\">=\"ProductComponents\" \/&gt;<\/span>\n<span style=\"color: #3366ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Feature<\/span><span style=\"color: #3366ff;\">&gt;<\/span><\/pre>\n<p>Let the &#8220;ComponentGroupRef&#8221; as-is for now. We will change it later.<\/p>\n<p>Then comes the directory section:<\/p>\n<pre><span style=\"color: #3366ff;\">&lt;<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #3366ff;\">&gt;<\/span>\n   <span style=\"color: #3366ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #3366ff;\">=\"TARGETDIR\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #3366ff;\">=\"SourceDir\"&gt;<\/span>\n      <span style=\"color: #3366ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #3366ff;\">=\"ProgramFilesFolder\"&gt;<\/span>\n         <span style=\"color: #3366ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #3366ff;\">=\"INSTALLFOLDER\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #3366ff;\">=\"myExtSetup\" \/&gt;<\/span>\n      <span style=\"color: #3366ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #3366ff;\">&gt;<\/span>\n   <span style=\"color: #3366ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #3366ff;\">&gt;<\/span>\n<span style=\"color: #3366ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #3366ff;\">&gt;<\/span><\/pre>\n<p>This will create a &#8220;myExtSetup&#8221; folder under &#8220;program Files(x86)&#8221; (remember the platform property). Let&#8217;s change that to create first a folder with our company name then a subfolder for our extension:<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"TARGETDIR\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"SourceDir\"&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"ProgramFilesFolder\"&gt;<\/span>\n         <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"NOBUR_INC\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"Nobur inc.\" &gt;<\/span>\n            <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"INSTALLFOLDER\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"Sccm Device Extension\" \/&gt;<\/span>\n         <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>When choosing an Id, don&#8217;t forget they must :<\/p>\n<ul>\n<li>be unique in the file<\/li>\n<li>contains only alphanumerical characters and underscores (_). Spaces are forbidden.<\/li>\n<li>never start with a number<\/li>\n<\/ul>\n<p>Now the last part of the file.<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroup<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"ProductComponents\"<\/span> <span style=\"color: #ff0000;\">Directory<\/span><span style=\"color: #0000ff;\">=\"INSTALLFOLDER\"&gt;<\/span>\n      <span style=\"color: #339966;\">&lt;!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. --&gt;<\/span>\n<span style=\"color: #339966;\">      &lt;!-- &lt;Component Id=\"ProductComponent\"&gt; --&gt;<\/span>\n<span style=\"color: #339966;\">      &lt;!-- TODO: Insert files, registry keys, and other resources here. --&gt;<\/span>\n<span style=\"color: #339966;\">      &lt;!-- &lt;\/Component&gt; --&gt;<\/span>\n  <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ComponentGroup<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>There we add our dll like this :<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<span style=\"color: #993300;\">Fragment<\/span>&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroup<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"deviceExtComponents\"<\/span> Directory<span style=\"color: #0000ff;\">=\"INSTALLFOLDER\"&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Component<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"deviceExtdll\"&gt;<\/span>\n         <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">File<\/span> <span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=\"$(var.MyFirstExtension.TargetPath)\"<\/span> <span style=\"color: #ff0000;\">DiskId<\/span><span style=\"color: #0000ff;\">=\"1\"\/&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Component<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ComponentGroup<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>This instructs Wix to place the file generated in the &#8220;MyFirstExtension&#8221; project (represented by this variable: $(var.MyFirstExtension.TargetPath)) into the folder identified by &#8220;INSTALLFOLDER&#8221;. As we embed all the files into a unique MSI, you don&#8217;t have to care about the DiskId=&#8221;1&#8243; parameter.<\/p>\n<p>Go back to the feature list and change the id of the componentGroupRef to reflect our new componentGroup Id<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroupRef<\/span> <span style=\"color: #ff0000;\">Id<span style=\"color: #0000ff;\">=\"<u>deviceExtComponents<\/u>\" \/&gt;<\/span><\/span><\/pre>\n<p>Now, if you build this solution you will get a working\u00a0MSI file\u00a0that will deploy your Dll. This is not enough as we also need to deploy 2 XML files into the console directory.<\/p>\n<p>This is much harder than what we already did. Are you ready?<\/p>\n<p>First, we need to include our XML extension file into our project. Right-click on the &#8220;MyFirstExtension&#8221; project then select &#8220;Add&#8221; =&gt; &#8220;Existing Item\u2026&#8221;. Browse your disk to the place you saved our extension XML and add it. Now that is has been imported, rename it to mark it as a template:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-59 size-full\" src=\"\/wp-content\/uploads\/2023\/03\/image19.png\" alt=\"\" width=\"242\" height=\"109\" \/><\/p>\n<p>We will modify it a little to make more flexible (remember that the path to our dll in hardly coded into it). Double click on it to start edition and replace all the path targeting our Dll by something like a tag.<\/p>\n<p>My file will look like something like this:<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ActionDescription<\/span> <span style=\"color: #ff0000;\">Class<\/span><span style=\"color: #0000ff;\">=\"AssemblyType\"<\/span> <span style=\"color: #ff0000;\">DisplayName<\/span><span style=\"color: #0000ff;\">=\"show collections\"<\/span> <span style=\"color: #ff0000;\">MnemonicDisplayName<\/span><span style=\"color: #0000ff;\">=\"show collections\"<\/span> <span style=\"color: #ff0000;\">Description<\/span><span style=\"color: #0000ff;\">=\"Shows the list of collection IDs this device is member of\"&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ImagesDescription<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ResourceAssembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n         <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Assembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span><strong><em>[INSTALLFLD]<\/em><\/strong>MyFirstExtension.dll<span style=\"color: #0000ff;\">&lt;<\/span>\/<span style=\"color: #993300;\">Assembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n         <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Type<\/span><span style=\"color: #0000ff;\">&gt;<\/span>MyFirstExtension.Properties.Resources.resources<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Type<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ResourceAssembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ImageResourceName<\/span><span style=\"color: #0000ff;\">&gt;<\/span>collinfo<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ImageResourceName<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ImagesDescription<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ShowOn<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">string<\/span><span style=\"color: #0000ff;\">&gt;<\/span>ContextMenu<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">string<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n     <span style=\"color: #0000ff;\"> &lt;<\/span><span style=\"color: #993300;\">string<\/span><span style=\"color: #0000ff;\">&gt;<\/span>DefaultHomeTab<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">string<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ShowOn<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ActionAssembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Assembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span><strong><em>[INSTALLFLD]<\/em><\/strong>MyFirstExtension.dll<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Assembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Type<\/span><span style=\"color: #0000ff;\">&gt;<\/span>MyFirstExtension.DeviceTools<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Type<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Method<\/span><span style=\"color: #0000ff;\">&gt;<\/span>deviceCollections<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Method<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ActionAssembly<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n\u2026\u2026<\/pre>\n<p>Save it!<\/p>\n<p>On the bottom right of the screen (in the property pane), change &#8220;copy to output dir&#8221; option to &#8220;Copy if newer&#8221; to be sure this file will be accessible from our setup project<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60 size-full\" src=\"\/wp-content\/uploads\/2023\/03\/image20.png\" alt=\"\" width=\"251\" height=\"249\" srcset=\"\/wp-content\/uploads\/2023\/03\/image20.png 251w, \/wp-content\/uploads\/2023\/03\/image20-150x150.png 150w\" sizes=\"(max-width: 251px) 85vw, 251px\" \/><\/p>\n<p>There is where MSIExt comes into the show. We will use the MSIExt template feature to replace &#8220;on the fly&#8221; our &#8220;INSTALLFLD&#8221; flag with the correct path during installation.<\/p>\n<p>Right-click on your setup project to add an existing file and browse to where you previously unzip MSIExt. Open the &#8220;WixExtensions&#8221; subfolder, change the filter to &#8220;*.*&#8221; and add WixSystemToolsExtension.dll.<\/p>\n<p>Now that Wix&#8217;s extension is included in your project, add a reference to it (right-click on references, then &#8220;Add Reference\u2026.&#8221;) And select the file you just imported (the one in your project folder!)<\/p>\n<p>MSIExt doesn&#8217;t provide XSD files in their distribution archive. That is not mandatory but makes work easier as it prevents notice messages during building and, moreover, provides auto-completion info to IntelliSense.<\/p>\n<p>Luckily, this is an opensource project and XSD files are available on GitHub. I&#8217;ve already extracted those from version 1.5 for you and place them into this Zip archive.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2023\/03\/MSIExt1.5-xsd.zip\">MSIExt1.5-xsd<\/a>\u00a0(zip archive)<\/p>\n<p>Add the corresponding SystemTools.xsd file to your setup project. Open the product.wxs file for edition select &#8220;Schemas\u2026&#8221; in the XML menu.<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-61 size-full\" src=\"\/wp-content\/uploads\/2023\/03\/image22.png\" alt=\"\" width=\"166\" height=\"69\" \/><\/p>\n<p>And add the freshly imported XSD.<\/p>\n<p>Finally, add the XML namespace for this extension in our XML file like this :<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Wix<\/span> <span style=\"color: #ff0000;\">xmlns<\/span><span style=\"color: #0000ff;\">=\"http:\/\/schemas.microsoft.com\/wix\/2006\/wi\"<\/span> <span style=\"color: #ff0000;\"><strong><em>xmlns:SystemTools<\/em><\/strong><\/span><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>http:\/\/schemas.appsecinc.com\/wix\/SystemToolsExtension<\/em><\/strong><strong><em>\"<\/em><\/strong>&gt;<\/span><\/pre>\n<p>Now that everything is ready, let&#8217;s modify the WXS file!<\/p>\n<p>In the Product section, just after the features, let an empty line and add:<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Condition<\/span> <span style=\"color: #ff0000;\">Message<\/span><span style=\"color: #0000ff;\">=\"You need to be an administrator to install this product.\"&gt;<\/span>\n   Privileged\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Condition<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>I will not explain that. I think you already understand what it means ^^<\/p>\n<p>Let another empty line then add :<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Property<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"UIFOLDER\"<\/span> <span style=\"color: #ff0000;\">Secure<\/span><span style=\"color: #0000ff;\">=\"yes\"&gt;<\/span>\n<span style=\"color: #0000ff;\">   &lt;<\/span><span style=\"color: #993300;\">RegistrySearch<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"SccmUiFolder\"<\/span> <span style=\"color: #ff0000;\">Root<\/span><span style=\"color: #0000ff;\">=\"HKLM\"<\/span> <span style=\"color: #ff0000;\">Key<\/span><span style=\"color: #0000ff;\">=\"SOFTWARE\\Microsoft\\ConfigMgr10\\Setup\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"UI Installation Directory\"<\/span> <span style=\"color: #ff0000;\">Type<\/span><span style=\"color: #0000ff;\">=\"directory\"<\/span> <span style=\"color: #0000ff;\">\/&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Property<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>Quite simple also! This will search the registry for the SCCM console installation folder and place the result into a Property named &#8220;UIFOLDER&#8221;.<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Property<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"XMLSTORAGE\"<\/span> <span style=\"color: #ff0000;\">Secure<\/span><span style=\"color: #0000ff;\">=\"yes\"&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">DirectorySearch<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"CheckSubDir\"<\/span> <span style=\"color: #ff0000;\">Path<\/span><span style=\"color: #0000ff;\">=\"[UIFOLDER]\"<\/span> <span style=\"color: #ff0000;\">Depth<\/span><span style=\"color: #0000ff;\">=\"0\"&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">DirectorySearch<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"xml_storage_search\"<\/span> <span style=\"color: #ff0000;\">Path<\/span><span style=\"color: #0000ff;\">=\"XmlStorage\"<\/span> <span style=\"color: #ff0000;\">Depth<\/span><span style=\"color: #0000ff;\">=\"5\"<\/span> <span style=\"color: #0000ff;\">\/&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">DirectorySearch<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Property<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>We already found the console installation path, this will search inside the tree the XmlStorage subfolder and place it into the &#8220;XMLSTORAGE&#8221; property.<\/p>\n<p>Now we can describe the directory structure of the SCCM console installation.<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"TARGETDIR\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"SourceDir\"&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"ProgramFilesFolder\"&gt;<\/span>\n        <span style=\"color: #0000ff;\"> &lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"NOBUR_INC\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"Nobur inc.\"<\/span> &gt;\n            <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Directory<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"INSTALLFOLDER\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"Sccm Device Extension\" \/&gt;<\/span>\n         <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\"><strong><em>         &lt;<\/em><\/strong><\/span><span style=\"color: #993300;\"><strong><em>Directory<\/em><\/strong> <\/span><span style=\"color: #ff0000;\"><strong><em>Id<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>XMLSTORAGE<\/em><\/strong><strong><em>\"<\/em><\/strong><\/span> <strong><em>Name<\/em><\/strong><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>XMLSTORAGE<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>&gt;<\/em><\/strong><\/span>\n<span style=\"color: #0000ff;\"><strong><em>            &lt;<\/em><\/strong><\/span><span style=\"color: #993300;\"><strong><em>Directory<\/em><\/strong> <\/span><span style=\"color: #ff0000;\"><strong><em>Id<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>EXTENSIONS<\/em><\/strong><strong><em>\"<\/em><\/strong><\/span> <strong><em>Name<\/em><\/strong><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>Extensions<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>&gt;<\/em><\/strong><\/span>\n<span style=\"color: #0000ff;\"><strong><em>               &lt;<\/em><\/strong><\/span><span style=\"color: #993300;\"><strong><em>Directory<\/em><\/strong> <\/span><span style=\"color: #ff0000;\"><strong><em>Id<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>ACTIONS<\/em><\/strong><strong><em>\"<\/em><\/strong><\/span> <strong><em>Name<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>Actions<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>&gt;<\/em><\/strong><\/span><\/span>\n<span style=\"color: #0000ff;\"><strong><em>                  &lt;<\/em><\/strong><\/span><span style=\"color: #993300;\"><strong><em>Directory<\/em><\/strong> <\/span><span style=\"color: #ff0000;\"><strong><em>Id<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>_FD01CD1_9E01_461E_92CD_94866B8D1F39<\/em><\/strong><strong><em>\"<\/em><\/strong> <\/span><strong><em>Name<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>3fd01cd1-9e01-461e-92cd-94866b8d1f39<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em> \/&gt;<\/em><\/strong><\/span><\/span>\n<span style=\"color: #0000ff;\"><strong><em>                  &lt;<\/em><\/strong><\/span><span style=\"color: #993300;\"><strong><em>Directory<\/em><\/strong> <\/span><span style=\"color: #ff0000;\"><strong><em>Id<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>ED9DEE86_EADD_4AC8_82A1_7234A4646E62<\/em><\/strong><strong><em>\"<\/em><\/strong> <\/span><strong><em>Name<\/em><\/strong><span style=\"color: #0000ff;\"><strong><em>=<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em>ed9dee86-eadd-4ac8-82a1-7234a4646e62<\/em><\/strong><strong><em>\"<\/em><\/strong><strong><em> \/&gt;<\/em><\/strong><\/span><\/span>\n<span style=\"color: #0000ff;\"><strong><em>               &lt;\/<\/em><\/strong><\/span><span style=\"color: #993300;\"><strong><em>Directory<\/em><\/strong><\/span><span style=\"color: #0000ff;\"><strong><em>&gt;<\/em><\/strong><\/span>\n<strong><em>            <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;\n<\/span><\/em><\/strong><strong><em>         <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/em><\/strong>\n      <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Directory<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Fragment<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>A directory XMLSTORAGE having the same Id that the property containing the XmlStorage path. Inside an &#8220;Extensions&#8221; folder containing an &#8220;Actions&#8221; folder with a GUID folder within.<\/p>\n<p>Note the IDs of GUID folders: I simply uppercase all letters and replace dashes (-) with underscores (as dashes are not allowed in IDs). Note also that the first one starts with a number so I had to replace it with an underscore too.<\/p>\n<p>Add a new component in a new componentGroup. We can&#8217;t use the actual componentGroup because all the files will not reside in the same folder tree.<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroup<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"deviceExtxmlComponents<\/span>\"&gt;\n<span style=\"color: #0000ff;\">   &lt;<\/span><span style=\"color: #993300;\">Component<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"ext_xml_1\"<\/span> <span style=\"color: #ff0000;\">Directory<\/span><span style=\"color: #0000ff;\">=\"_FD01CD1_9E01_461E_92CD_94866B8D1F39\"&gt;<\/span>\n      &lt;<span style=\"color: #993300;\">File<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"XmlTemplate1\"<\/span> <span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=\"$(var.MyFirstExtension.TargetDir)MyfirstExtensionTemplate.xml\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"MyfirstExtension.xml\" DiskId=\"1\" \/&gt;<\/span>\n      <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">SystemTools:TemplateFile<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"fileTemplateProcessXml1\"<\/span> <span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=\"[#XmlTemplate1]\"<\/span> <span style=\"color: #ff0000;\">Target<\/span><span style=\"color: #0000ff;\">=\"[#XmlTemplate1]\"<\/span> <span style=\"color: #ff0000;\">ExecuteOnInstall<\/span><span style=\"color: #0000ff;\">=\"yes\"&gt;<\/span>\n         &lt;<span style=\"color: #993300;\">SystemTools:TemplateFileProperty<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"INSTALLDIR_property\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"INSTALLFLD\"<\/span> <span style=\"color: #ff0000;\">Value<\/span><span style=\"color: #0000ff;\">=\"[INSTALLDIR]\" \/&gt;<\/span>\n      &lt;\/<span style=\"color: #993300;\">SystemTools:TemplateFile<\/span>&gt;\n   <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Component<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">ComponentGroup<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>This requires some explanation. This define a new component named ext_xml_1 that will be installed in 3fd01cd1-9e01-461e-92cd-94866b8d1f39 folder. It is composed of a file (id XmlTemplate1) that must be taken from the build output folder of the MyFirstExtension project, named MyfirstExtensionTemplate.xml and will be renamed MyfirstExtension.xml at installation time.<\/p>\n<p>Here comes the SystemTools WixExtension. We will use the file identified by id=XmlTemplate1 as a template (<span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=&#8221;[#XmlTemplate1]&#8221;<\/span>) and place the result of processing in the same file (in-place) (<span style=\"color: #ff0000;\">Target<\/span><span style=\"color: #0000ff;\">=&#8221;[#XmlTemplate1]&#8221;<\/span>). This is only required during installation so : <span style=\"color: #ff0000;\">ExecuteOnInstall<\/span><span style=\"color: #0000ff;\">=&#8221;yes&#8221;<\/span><\/p>\n<p>In this file, we will replace all reference to INSTALLFLD property (<span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=&#8221;INSTALLFLD&#8221;<\/span>) with the content of the INSTALLDIR property (<span style=\"color: #ff0000;\">Value<\/span><span style=\"color: #0000ff;\">=&#8221;[INSTALLDIR]&#8221;<\/span>)<\/p>\n<p>Now duplicate this to proceed with the second xml file :<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroup<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"deviceExtxmlComponents<\/span>\"&gt;\n<span style=\"color: #0000ff;\">   &lt;<\/span><span style=\"color: #993300;\">Component<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"ext_xml_1\"<\/span> <span style=\"color: #ff0000;\">Directory<\/span><span style=\"color: #0000ff;\">=\"_FD01CD1_9E01_461E_92CD_94866B8D1F39\"&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;<span style=\"color: #993300;\">File<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"XmlTemplate1\"<\/span> <span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=\"$(var.MyFirstExtension.TargetDir)MyfirstExtensionTemplate.xml\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"MyfirstExtension.xml\" DiskId=\"1\" \/&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0 <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">SystemTools:TemplateFile<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"fileTemplateProcessXml1\"<\/span> <span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=\"[#XmlTemplate1]\"<\/span> <span style=\"color: #ff0000;\">Target<\/span><span style=\"color: #0000ff;\">=\"[#XmlTemplate1]\"<\/span> <span style=\"color: #ff0000;\">ExecuteOnInstall<\/span><span style=\"color: #0000ff;\">=\"yes\"&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;<span style=\"color: #993300;\">SystemTools:TemplateFileProperty<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"INSTALLDIR_property\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"INSTALLFLD\"<\/span> <span style=\"color: #ff0000;\">Value<\/span><span style=\"color: #0000ff;\">=\"[INSTALLDIR]\" \/&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/<span style=\"color: #993300;\">SystemTools:TemplateFile<\/span>&gt;\n\u00a0\u00a0 <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Component<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Component<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"<strong>ext_xml_2<\/strong>\"<\/span> <span style=\"color: #ff0000;\">Directory<\/span><span style=\"color: #0000ff;\">=\"<strong><em>ED9DEE86_EADD_4AC8_82A1_7234A4646E62<\/em><\/strong>\"&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;<span style=\"color: #993300;\">File<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"<strong>XmlTemplate2<\/strong>\"<\/span> <span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=\"$(var.MyFirstExtension.TargetDir)MyfirstExtensionTemplate.xml\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"MyfirstExtension.xml\" DiskId=\"1\" \/&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0 <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">SystemTools:TemplateFile<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"<strong>fileTemplateProcessXml2<\/strong>\"<\/span> <span style=\"color: #ff0000;\">Source<\/span><span style=\"color: #0000ff;\">=\"[#<strong>XmlTemplate2<\/strong>]\"<\/span> <span style=\"color: #ff0000;\">Target<\/span><span style=\"color: #0000ff;\">=\"[#<strong>XmlTemplate2<\/strong>]\"<\/span> <span style=\"color: #ff0000;\">ExecuteOnInstall<\/span><span style=\"color: #0000ff;\">=\"yes\"&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;<span style=\"color: #993300;\">SystemTools:TemplateFileProperty<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"INSTALLDIR_property\"<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"INSTALLFLD\"<\/span> <span style=\"color: #ff0000;\">Value<\/span><span style=\"color: #0000ff;\">=\"[INSTALLDIR]\" \/&gt;<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/<span style=\"color: #993300;\">SystemTools:TemplateFile<\/span>&gt;\n\u00a0\u00a0 <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #993300;\">Component<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\n<span style=\"color: #3366ff;\">&lt;\/<span style=\"color: #993300;\">ComponentGroup<\/span>&gt;<\/span><\/pre>\n<p>Don&#8217;t forget that Id must always be unique!<\/p>\n<p>Last step: add this componentGroup to our feature and that&#8217;s all !!<\/p>\n<pre><span style=\"color: #0000ff;\">&lt;<\/span>Feature <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"MyDeviceExt\"<\/span> <span style=\"color: #ff0000;\">Title<\/span><span style=\"color: #0000ff;\">=\"Device Right click extension\"<\/span> <span style=\"color: #0000ff;\"><span style=\"color: #ff0000;\">Level<\/span>=\"1\"&gt;<\/span>\n   <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroupRef<\/span> <span style=\"color: #ff0000;\">Id<\/span><span style=\"color: #0000ff;\">=\"deviceExtComponents\" \/&gt;<\/span>\n   <em><strong><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">ComponentGroupRef<\/span> <span style=\"color: #ff0000;\">Id<\/span><\/strong><\/em><span style=\"color: #0000ff;\"><em><strong>=\"deviceExtXmlComponents\" \/&gt;\n<\/strong><\/em>&lt;\/<\/span><span style=\"color: #993300;\">Feature<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>A common error on compilation time is:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-62 size-full\" src=\"\/wp-content\/uploads\/2023\/03\/image23.png\" alt=\"\" width=\"797\" height=\"80\" srcset=\"\/wp-content\/uploads\/2023\/03\/image23.png 797w, \/wp-content\/uploads\/2023\/03\/image23-300x30.png 300w, \/wp-content\/uploads\/2023\/03\/image23-768x77.png 768w\" sizes=\"(max-width: 797px) 85vw, 797px\" \/><\/p>\n<p>Surely due to the fact that our two project doesn&#8217;t have the same target architecture. Set x86 Architecture for release and debug targets in both projects then rebuild.<\/p>\n<p>Don&#8217;t forget to update the version number in the WXS file before each release. Without this, you will not be able to replace the previously installed version (it will complain that the product is already installed)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Put all this into an MSI To create an MSI that will let you distribute your extension, you will need 2 things : Wix Toolset ( freely available here =&gt; http:\/\/wixtoolset.org\/ ) And MSIExt that will bring few features not natively available in &#8220;Wix Toolset&#8221; but are mandatory for us. (here =&gt; http:\/\/dblock.github.io\/msiext\/ ) Even &hellip; <a href=\"https:\/\/brunocm.azurewebsites.net\/?page_id=21\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Part 5 &#8211; Distribute your work with a MSI&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":""},"_links":{"self":[{"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=\/wp\/v2\/pages\/21"}],"collection":[{"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=21"}],"version-history":[{"count":2,"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=\/wp\/v2\/pages\/21\/revisions"}],"predecessor-version":[{"id":89,"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=\/wp\/v2\/pages\/21\/revisions\/89"}],"wp:attachment":[{"href":"https:\/\/brunocm.azurewebsites.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=21"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}