Friday, August 6, 2010

Creating an installer for a COM component for ArcGIS 10

I just wrote my first installer for an ArcGIS 10 COM component. I realize that ESRI has created this new thing called an add-in, but since I want my component to work with both 9.3 and 10, I figured it would be easiest to keep most things the same. So I built my base project, fired up ArcGIS 10, and my toolbar was right where I expected it to be. Then I built a setup program using the 9.3 instructions on the ESRI website. I built the setup program, ran it, started ArcGIS, and my toolbar was nowhere to be found. Hmmm....

Turns out that with version 10, ESRI decided not to use the regular Windows COM registration services and instead uses its own registration utility. This utility can be used to register COM components, or they suggest using the Add From File option on the Customize dialog in ArcMap. I didn't like that solution because that's asking a bit too much for some of our users (don't ask what they're doing using ArcMap!). I want them to just double-click a file icon.

So here's how I created my installer for ArcGIS 10:
  1. Open the solution that you want to create an installer for.
  2. Add an Installer Class to the project that you want to create the installer for.
  3. Add the following code to the new Installer class. Note that you may want to enclose things in try/catch blocks. I have it show an error message if it takes more than 5 seconds to unregister the component.
public override void Install(System.Collections.IDictionary stateSaver)
{
    base.Install(stateSaver);
    string esriRegAsmFilename = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles),
        "ArcGIS\\bin\\ESRIRegAsm.exe");
    Process esriRegAsm = new Process();
    esriRegAsm.StartInfo.FileName = esriRegAsmFilename;
    esriRegAsm.StartInfo.Arguments =
        string.Format("\"{0}\" /p:Desktop", base.GetType().Assembly.Location);
    esriRegAsm.Start();
}

public override void Uninstall(System.Collections.IDictionary savedState)
{
    base.Uninstall(savedState);
    string esriRegAsmFilename = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles),
        "ArcGIS\\bin\\ESRIRegAsm.exe");
    Process esriRegAsm = new Process();
    esriRegAsm.StartInfo.FileName = esriRegAsmFilename;
    esriRegAsm.StartInfo.Arguments =
        string.Format("\"{0}\" /p:Desktop /u", base.GetType().Assembly.Location);
    esriRegAsm.Start();
    if (!esriRegAsm.WaitForExit(5000))
        MessageBox.Show("ESRI unregistration failed");
}
  1. Make sure the Specific Version property for the referenced assemblies in the project is set to False and rebuild the project.
  2. Add a Setup Project to your solution.
  3. Right-click the new Setup project in Solution Explorer and select Add | Project Output... 
  4. In the dialog box, select the project you want to deploy from the pulldown menu and then select Primary output and click OK.
  5. This will generate a list of detected dependencies. Right-click and exclude all of the ESRI assembles and stdole.dll.
  6. Open the Properties pane for the .tlb file in the dependency list, and change the Register property to vsdrfDoNotRegister.
  7. Right-click the Setup project in the Solution Explorer and select View | Custom Actions.
  8. In the Custom Actions window, right-click the Install folder and select Add Custom Action...
  9. In the dialog box, select File System on Target Machine from the pulldown menu and then double-click Application Folder.
  10. Double-click Primary output from <AssemblyName>.
  11. Repeat this for the Uninstall folder in the Custom Actions window.
  12. Build the setup project.

8 comments:

  1. Awesome. Thanks a bunch! I spent two days wrestling with the code ESRI provided, trashing setup projects, trashing installers, etc..., and this code took care of it. One enhancement:

    In order to avoid having a bunch of boxes pop up saying "Registration succeeded," I had to amend that one line to be:
    string.Format("\"{0}\" /p:Desktop /s", base.GetType().Assembly.Location);

    Same thing with the uninstall.

    ReplyDelete
  2. Thanks Dan. I think I was testing and wanted confirmation that things worked. Your way is definitely better for something that's being deployed.

    ReplyDelete
  3. Chris, I've successfully installed my stuff with the steps above on two machines, but a third is driving me straight up the wall. All three are XP, and all three have ArcGIS 10 installed along with all the patches. The third machine, though, encounters an error on install that says it can't find the ESRI.ArcGIS.Geometry assembly, version 9.3.0.1770. I've altogether eliminated all references to 9.3 assemblies in my Visual Studio solution and replaced them with the references to 10.0 (but the other two machines successfully installed after I only set the 9.3 dependencies' "Specific Version" property to "False"), and I've even gone so far as to dig through the uncooperative machine's registry and remove a couple lingering old references to 9.3 assemblies as well. Still no dice. Any other options you can think of for me to try? Thanks.

    ReplyDelete
  4. Dan, I don't know that I have any useful ideas off the top of my head. By any chance did you have a 9.3 version of your stuff installed on the machine previously? A guy I work with uninstalled 9.3 without uninstalling custom stuff first, and then he couldn't install the v10 custom things. He had to uninstall 10, reinstall 9.3, uninstall the custom stuff, uninstall 9.3, and reinstall 10. But that's the only thing I can think of, since you have no references to 9.3 assemblies in your solution, and specific version is set to false. I'm no expert on this stuff, though...

    ReplyDelete
  5. Okay thanks Chris. We did exactly what your coworker did. Harumph! :) Thanks.

    Dan

    ReplyDelete
  6. I've derived a static method to call the ESRIRegASM.exe from your proposition and the ESRI documentation: Utility to work with ESRIRegAsm.exe tool

    ReplyDelete
  7. Thankyou so much, this is infinitely clearer than anything on the ESRI website!

    ReplyDelete