title: Register dll for VB from C#: Regasm works, WiX does not: Runtime 430
body: <p>I have a dll created by me in C#. It has an interface with guid and staff in order for it to support intellisense in Excel VB. When I register it either automatically (couple checkboxes in MSVS) or using regasm mydll.dll /tlb:mydll.dll - it works fine. </p>
  
  <p>But I want to deploy it automatically with the rest of my program using WiX. 
  I used heat like described here <a href="https://stackoverflow.com/questions/543995/replicating-visual-studio-com-registration-with-a-wix-installer">Replicating Visual Studio COM registration with a WiX Installer</a></p>
  
  <p>Quote:</p>
  
  <pre><code>Run: Regasm MyDLL.dll /tlb:MyDLL.tlb
  
  Run: Heat file MyDLL.dll -out MyDll-1.wxs
  
  Run: Heat file MyDll.tlb -out MyDll-2.wxs
  </code></pre>
  
  <p>MyDll-2.wxs contains a  element that you will want to copy and nest inside the  element that was generated in MyDll-1.wxs. This will give you a complete  element that you can use in the installer project.</p>
  
  <p>This way Excel says error loading dll and in the path correct path to my dll is shown.</p>
  
  <p>If I simply put two separate components in WiX, dll is added ok to Excel VB, Intellisense works, also the path shown - is to tlb, not to dll.  But it is the same for regasm, so I assume it is correct. But when I run the code in Excel VB I get the following error:</p>
  
  <p>Runtime '430':
  Class does not support Automation or does not support expected inteface</p>
  
  <p>Again, if I directly use regasm, everything works fine.</p>
  
  <p>So how should I do it in WiX?</p>
  
  <p>Thanks in advance!</p>
  
  <p>Update:</p>
  
  <p>From heat after calling it with my dll as a parameter I get </p>
  
  <pre><code>&lt;Component Id="cmp199C512A0B3C2ACB727633983C104D83" Guid="306F6849-3C35-4602-AB76-2FD993D675C4"&gt;
              &lt;Class Id="{97B04EDD-D0FC-4429-98FE-8D942E31CA98}" Context="InprocServer32" Description="Synthec.SynthecHandler" ThreadingModel="both" ForeignServer="mscoree.dll"&gt;
                  &lt;ProgId Id="Synthec.SynthecHandler" Description="Synthec.SynthecHandler" /&gt;
              &lt;/Class&gt;
              &lt;File Id="filAEDB64435A66D04AC60E3377C956C115" KeyPath="yes" Source="Synthec.dll" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32\1.0.0.0" Name="Class" Value="Synthec.SynthecHandler" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32\1.0.0.0" Name="Assembly" Value="Synthec, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filAEDB64435A66D04AC60E3377C956C115]" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32" Name="Class" Value="Synthec.SynthecHandler" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32" Name="Assembly" Value="Synthec, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /&gt;
              &lt;RegistryValue Root="HKCR" Key="CLSID\{97B04EDD-D0FC-4429-98FE-8D942E31CA98}\InprocServer32" Name="CodeBase" Value="file:///[#filAEDB64435A66D04AC60E3377C956C115]" Type="string" Action="write" /&gt;
          &lt;/Component&gt;
  </code></pre>
  
  <p>and for tlb:</p>
  
  <pre><code>&lt;Component Id="cmpB02C4AD21F21B1B50A662E8F59126370" Guid="ADBDF57B-8E1E-433D-B047-867DC71D5FB8"&gt;
              &lt;File Id="filB2F5CE36C4E03293677DE32B903A3DC7" KeyPath="yes" Source="mydll.tlb"&gt;
                  &lt;TypeLib Id="{E7864806-81DA-46AC-881B-A5255CAE2D2E}" Description="Synthec" Language="0" MajorVersion="1" MinorVersion="0"&gt;
                      &lt;Interface Id="{E31D9546-8BCC-4CA1-8B95-21EB6EFC0808}" Name="ISynthecHandler" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" /&gt;
                  &lt;/TypeLib&gt;
              &lt;/File&gt;
          &lt;/Component&gt;
  </code></pre>
  
  <p>So there is no Interface entry in dll component itself... What should I do?</p>
  
  <p>RESULT:
  In order to see a reference Excel wanted tlb. </p>
  
  <p>To create tlb automatically by Visual Studio you should check Register for COM Interop checkbox and also run Visual Studio as administrator.</p>
  
  <p>To get tlb automatically, I copied (using msbuild copy task) dll and tlb into separate directory (after build of the project where dll is created), then as suggested in an answer used heat task (installer project, before build), then referenced generated wxs (actually, componentgroup from it) in my main wxs (Product.wxs by default) file.</p>
  
  <p>Also this generated wxs should then be added to the installer project in order to be seen by main  wxs(so, the first time you get an error about componentgroupref not found). But then the contents of this file are updated automatically by heat task.</p>
  
  <p>So, some extra tuning is required, but this way I just rebuild solution and get completely new installer with new dlls. Also this installer is capable of registering quite OK. </p>
  
  <p>Hopefully this will help someone else.</p>