Sunday, January 23, 2011

Installer for a IE browser helper object


Recently I developed an unmanaged browser helper object (BHO which is commonly known as plugin) for Internet Explorer. A good tutorial to follow for this is: http://msdn.microsoft.com/en-us/library/bb250489(v=vs.85).aspx#setup 

However, this tutorial or any other document that I could found in the internet did not provide a direct guidance on creating an installer for the BHO. The challenging part is adding all the registry keys required for Internet Explorer to identify our BHO. Although installer templates are provided with Visual Studio for Microsoft Office plugins, I could not find an installer template for an IE BHO. 

When the Visual Studio project for the BHO is built for the first time, VS automatically registers the BHO in the developer machine. Therefore what I did was identifying the registry changes caused by this process using a registry change tracker tool. The tool I used was regshot (http://sourceforge.net/projects/regshot/) which is an open source tool.

Then I used Wix (http://wix.sourceforge.net/) for building the installer. Following is the full code for the installer. Someone using Wix to build the installer will be able to directly use this code after changing the stuff specific to his BHO (name, location, etc). If some other installer builder tool is used, this will be still useful to find the exact registry keys that need to be added during installation.

Do not forget to replace the strings in all caps to the appropriate values for your BHO. Also change all the guids to new values. Replace 99C27324-6DA7-4340-A44F-2A57F3EF9A63 with the guid given for your BHO class and D37FECE4-5E7C-4956-A2E1-23605AFFC70C with the guid given for your type library. Both these values can be found in the .idl file for your plugin.

In addition to the plugin I’m installing the C runtime using the merge modules provided by visual studio. These merge module packages can be found in YOUR_PROGRAM_FILES_FOLDER\Common Files\Merge Modules.

<?xml version='1.0'?>
<?define  VC_Runtime_Path = ‘FOLDER_CONTAINING_VC_RUNTIME_MERGE_MODULE_PACKAGES’ ?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
   <Product Id='038D6D6B-FD9C-4ea2-A82C-EE77F3FA0D87' Name=’PRODUCT_NAME’ Language='1033'
            Version='1.0.0.0' Manufacturer=YOUR_NAME UpgradeCode=’A_GUID_FOR_UPGRADE_CODE’>
      <Package Description=’DESCRIPTION’
                Comments=’COMMENTS’
                Manufacturer=’YOUR_NAME’ InstallerVersion='300' Compressed='yes'/>

      <Media Id='1' Cabinet='product.cab' EmbedCab='yes'/>

      <Directory Id='TARGETDIR' Name='SourceDir'>
         <Directory Id='ProgramFilesFolder' Name='PFiles'>
            <Directory Id=’BHO_FOLDER’ Name=’BHO_FOLDER_NAME’>
               <Component Id='COMPONENT_ID' Guid='BE13C927-63EC-4d61-9ED7-5338A3965D42'>
                  <File Id='dll' Name=PLUGIN_DLL_NAME' DiskId='1' Source='PATH_TO_PLUGIN_DLL\PLUGIN_DLL.dll' />
                  <RegistryKey Root='HKLM' Key='SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{99C27324-6DA7-4340-A44F-2A57F3EF9A63}\' Action='createAndRemoveOnUninstall'>
                      <RegistryValue Type='string' Value=' BHO_NAME '/>
                      <RegistryValue Type='integer' Name='NoExplorer' Value='1'/>
                  </RegistryKey>
                  <RegistryKey Root='HKCR' Key='CLSID\{99C27324-6DA7-4340-A44F-2A57F3EF9A63}\InprocServer32'>
                      <RegistryValue Type='string' Value='[BHO_FOLDER]PLUGIN_DLL.dll'/>
                      <RegistryValue Type='string' Name='ThreadingModel' Value='Apartment'/>
                  </RegistryKey>
                  <RegistryKey Root='HKCR' Key='CLSID\{99C27324-6DA7-4340-A44F-2A57F3EF9A63}\ProgID'>
                      <RegistryValue Type='string' Value='PLUGIN_NAME.BHO_NAME.1'/>
                   </RegistryKey>
                 <RegistryKey Root='HKCR' Key='CLSID\{99C27324-6DA7-4340-A44F-2A57F3EF9A63}\TypeLib'>
                   <RegistryValue Type='string' Value='{D37FECE4-5E7C-4956-A2E1-23605AFFC70C}'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key='CLSID\{99C27324-6DA7-4340-A44F-2A57F3EF9A63}\VersionIndependentProgID'>
                   <RegistryValue Type='string' Value=' PLUGIN_NAME. BHO_NAME '/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key='CLSID\{99C27324-6DA7-4340-A44F-2A57F3EF9A63}'>
                   <RegistryValue Type='string' Value=’PLUGIN_DESCRIPTION’ />
                 </RegistryKey>
                 <RegistryKey Root='HKLM' Key='SOFTWARE\Microsoft\Internet Explorer'>
                   <RegistryValue Type='string' Name ='DownloadUI' Value='{99C27324-6DA7-4340-A44F-2A57F3EF9A63}'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCU' Key='Software\Microsoft\Internet Explorer'>
                   <RegistryValue Type='string' Name ='DownloadUI' Value='{99C27324-6DA7-4340-A44F-2A57F3EF9A63}'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key=' PLUGIN_NAME. BHO_NAME '>
                   <RegistryValue Type='string' Value='PLUGIN_DESCRIPTION'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key=' PLUGIN_NAME. BHO_NAME \CLSID'>
                   <RegistryValue Type='string' Value='{99C27324-6DA7-4340-A44F-2A57F3EF9A63}'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key=' PLUGIN_NAME. BHO_NAME \CurVer'>
                   <RegistryValue Type='string' Value=' PLUGIN_NAME. BHO_NAME.1'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key=' PLUGIN_NAME. BHO_NAME.1'>
                   <RegistryValue Type='string' Value=’PLUGIN_DESCRIPTION’ />
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key=' PLUGIN_NAME. BHO_NAME.1\CLSID'>
                   <RegistryValue Type='string' Value='{99C27324-6DA7-4340-A44F-2A57F3EF9A63}'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key='AppID\PLUGIN_DLL.DLL'>
                   <RegistryValue Type='string' Name ='AppID' Value='{5B774CD0-B31A-4F2D-9991-7CE99B68926A}'/>
                 </RegistryKey>
                 <RegistryKey Root='HKCR' Key='AppID\{5B774CD0-B31A-4F2D-9991-7CE99B68926A}'>
                   <RegistryValue Type='string' Value=' PLUGIN_NAME '/>
                 </RegistryKey>
                 <RegistryKey Root='HKLM' Key='SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\{99C27324-6DA7-4340-A44F-2A57F3EF9A63}'>
                   <RegistryValue Type='string' Value=' PLUGIN_NAME '/>
                   <RegistryValue Type='integer' Name='NoExplorer' Value='1'/>
                 </RegistryKey>
               </Component>
            </Directory>
         </Directory>
      </Directory>

     <DirectoryRef Id="TARGETDIR">
       <Merge Id="VCRuntimeBase" SourceFile="$(var.VC_Runtime_Path)\Microsoft_VC90_CRT_x86.msm" DiskId="1" Language="0"/>
       <Merge Id="VCRuntimeBase64" SourceFile="$(var.VC_Runtime_Path)\Microsoft_VC90_CRT_x86_x64.msm" DiskId="1" Language="0"/>
       <Merge Id="VCRuntimeBasePolicy" SourceFile="$(var.VC_Runtime_Path)\policy_9_0_Microsoft_VC90_CRT_x86.msm" DiskId="1" Language="0"/>
       <Merge Id="VCRuntimeBasePolicy64" SourceFile="$(var.VC_Runtime_Path)\policy_9_0_Microsoft_VC90_CRT_x86_x64.msm" DiskId="1" Language="0"/>
       <Merge Id="VCRuntimeATL" SourceFile="$(var.VC_Runtime_Path)\Microsoft_VC90_ATL_x86.msm" DiskId="1" Language="0"/>
       <Merge Id="VCRuntimeATL64" SourceFile="$(var.VC_Runtime_Path)\Microsoft_VC90_ATL_x86_x64.msm" DiskId="1" Language="0"/>
       <Merge Id="VCRuntimeATLPolicy" SourceFile="$(var.VC_Runtime_Path)\policy_9_0_Microsoft_VC90_ATL_x86.msm" DiskId="1" Language="0"/>
       <Merge Id="VCRuntimeATLPolicy64" SourceFile="$(var.VC_Runtime_Path)\policy_9_0_Microsoft_VC90_ATL_x86_x64.msm" DiskId="1" Language="0"/>
     </DirectoryRef>

      <Feature Id='BHO' Title='BHO Feature' Level='1'>
         <ComponentRef Id='COMPONENT_ID' />
      </Feature>

     <Feature Id="Runtimex86" Level="1">
       <MergeRef Id="VCRuntimeBase"/>
       <MergeRef Id="VCRuntimeBasePolicy"/>
       <MergeRef Id="VCRuntimeATL"/>
       <MergeRef Id="VCRuntimeATLPolicy"/>
     </Feature>

     <Feature Id="Runtimex64" Level="1">
       <Condition Level="1">VersionNT64</Condition>
       <MergeRef Id="VCRuntimeBase64"/>
       <MergeRef Id="VCRuntimeBasePolicy64"/>
       <MergeRef Id="VCRuntimeATL64"/>
       <MergeRef Id="VCRuntimeATLPolicy64"/>
     </Feature>
    
   </Product>
</Wix>

No comments:

Post a Comment