Select to view content in your preferred language

ArcObjects in ArcGIS Desktop 9.3.1 and 10

2804
12
01-03-2011 08:35 AM
JamesCrandall
MVP Alum
Ok, I am having diffiuclty locating an answer on this and hope someone could help.  I have several applications that I maintain/support across an organizations IT infrastructure, all are developed with .NET Framewrok 3.5 SP1 and are all ICommand/ITooblar interfaces that run in ArcGIS Desktop 9.3/9.3.1 versions.

Will these need modification to be installed with ArcGIS Desktop 10?

1.  Will I need to bind these components to ArcGIS? For ex, will I need to include:

'Insert this line before invoking any ArcObjects to bind Engine runtime.
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop)


2.  Will my existing Setup.exe packages still function?  Do they need modification?

Thanks for any input.

james
0 Kudos
12 Replies
NeilClemmons
Honored Contributor
I've only migrated one project so far, but I followed these instructions and ran into no problems.

http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/Migrating_ArcGIS_9_3_De...

I chose the option to modify the project file to call esriRegAsm.exe instead of using the Add from File option.

The project I migrated used a standard Visual Studio Deployment project to create the installer.  I removed the code in the Installer class to register my classes with the ESRI component categories.  I then added code to call esriRegAsm to perform the category component registration.  This is the code I added to the OnAfterInstall event in the installer class:

protected override void OnAfterInstall(IDictionary savedState)
        {
            base.OnAfterInstall(savedState);

            string regAsmPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles), "ArcGIS\\bin\\ESRIRegAsm.exe");
            string appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string args = "\"" + appPath + "\" /p:Desktop /s";
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName = regAsmPath;
            startInfo.Arguments = args;
            System.Diagnostics.Process.Start(startInfo);
}


This is the code I added to the OnBeforeUninstall event:

protected override void OnBeforeUninstall(IDictionary savedState)
        {
            base.OnBeforeUninstall(savedState);

            string regAsmPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles), "ArcGIS\\bin\\ESRIRegAsm.exe");
            string appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string args = "\"" + appPath + "\" /p:Desktop /u /s";
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName = regAsmPath;
            startInfo.Arguments = args;
            System.Diagnostics.Process.Start(startInfo);
}
0 Kudos
StephenK
Emerging Contributor
Personally I prefer programs that can be installed through a simple installer and that don't require any later adjustments by the end-user in ArcMap. You will likely get more satisfied users and less demand for installation support. ESRI has created a good example on how to achieve this: http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//00010000016r000000

The process is a bit time-consuming, especially the first time you give this a try, but most of the code can easily be reused in other projects.
0 Kudos
JamesCrandall
MVP Alum
Neil,

Thanks for the detailed reply -- very helpful.  I am fairly sure about what to do, but just to clarify something....

There is no longer a need to have that Installer Component/Class that contains Uninstall/Install Subs to register/unregister the assembly and instead I should replace those Subs with the esriRegAsm code you posted?

Don't mean to be redundant, just wanted to verify I am understanding correctly.

Thanks again.

james


I chose the option to modify the project file to call esriRegAsm.exe instead of using the Add from File option.

The project I migrated used a standard Visual Studio Deployment project to create the installer.  I removed the code in the Installer class to register my classes with the ESRI component categories.  I then added code to call esriRegAsm to perform the category component registration.  This is the code I added to the OnAfterInstall event in the installer class:

protected override void OnAfterInstall(IDictionary savedState)
        {
            base.OnAfterInstall(savedState);

            string regAsmPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles), "ArcGIS\\bin\\ESRIRegAsm.exe");
            string appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string args = "\"" + appPath + "\" /p:Desktop /s";
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName = regAsmPath;
            startInfo.Arguments = args;
            System.Diagnostics.Process.Start(startInfo);
}


This is the code I added to the OnBeforeUninstall event:

protected override void OnBeforeUninstall(IDictionary savedState)
        {
            base.OnBeforeUninstall(savedState);

            string regAsmPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles), "ArcGIS\\bin\\ESRIRegAsm.exe");
            string appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string args = "\"" + appPath + "\" /p:Desktop /u /s";
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName = regAsmPath;
            startInfo.Arguments = args;
            System.Diagnostics.Process.Start(startInfo);
}
0 Kudos
NeilClemmons
Honored Contributor
That is correct, the old Install/Uninstall code is no longer needed.  I commented out that code and added the code I posted earlier.  I used the same Installer class so that I wouldn't have to add new Custom Actions for a new Installer class.
0 Kudos
JamesCrandall
MVP Alum
That is correct, the old Install/Uninstall code is no longer needed.  I commented out that code and added the code I posted earlier.  I used the same Installer class so that I wouldn't have to add new Custom Actions for a new Installer class.


Perfect!  I really appreciate your help on this.

Take Care,

James
0 Kudos
JamesCrandall
MVP Alum
That is correct, the old Install/Uninstall code is no longer needed.  I commented out that code and added the code I posted earlier.  I used the same Installer class so that I wouldn't have to add new Custom Actions for a new Installer class.


Neil,

I just finally had an opportunity to get going on this and have re-built and tested my .NET assembly on the dev workstation that has ArcGIS10 installed -- everything is working great!  So, now I am on to creating the Setup.exe and just had a quick observation/concern....

After adding the original Setup.exe project the solution (.sln), I noticed 2 new things in the Detected Dependencies list:

1. ESRI.ArcGIS.Search.dll is new and not excluded.  Should this be excluded like all of the others (SystemUI, Editor, Geometery, etc)???

2. Should I just start with a brand new Setup assembly?

Also: the code you posted is C#, correct?  Is there a VB.NET version?

Thanks again for your help on this!

Take Care,

james
0 Kudos
NeilClemmons
Honored Contributor
Yes, exclude all of the ESRI references.  The code I posted is in C# and I don't have a VB.NET version.  This is an untested conversion of the first routine:

            myBase.OnAfterInstall(savedState);

            Dim regAsmPath As String = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles), "ArcGIS\bin\ESRIRegAsm.exe")
            Dim appPath As String = System.Reflection.Assembly.GetExecutingAssembly().Location
            Dim args As String = """" & appPath & """ /p:Desktop /s"
            Dim startInfo As System.Diagnostics.ProcessStartInfo = new System.Diagnostics.ProcessStartInfo()
            startInfo.FileName = regAsmPath
            startInfo.Arguments = args
            System.Diagnostics.Process.Start(startInfo)
0 Kudos
JamesCrandall
MVP Alum
Yes, exclude all of the ESRI references.  The code I posted is in C# and I don't have a VB.NET version.  This is an untested conversion of the first routine:

            myBase.OnAfterInstall(savedState);

            Dim regAsmPath As String = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles), "ArcGIS\bin\ESRIRegAsm.exe")
            Dim appPath As String = System.Reflection.Assembly.GetExecutingAssembly().Location
            Dim args As String = """" & appPath & """ /p:Desktop /s"
            Dim startInfo As System.Diagnostics.ProcessStartInfo = new System.Diagnostics.ProcessStartInfo()
            startInfo.FileName = regAsmPath
            startInfo.Arguments = args
            System.Diagnostics.Process.Start(startInfo)



Well, I was a bit impatient and attempted to build the Setup package --- I found this,

http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/How_to_deploy_a_custom_...

Which says to add an entirely NEW assembly/project soley for the purpose of adding the Installer Class file (instead of just having it inside of the target assembly that I want to register/install) -- the code they suggest is about midway down that page:

Imports System.ComponentModel
Imports System.Configuration.Install

Public Class Installer1
    
    Public Sub New()
        MyBase.New()
        
        'This call is required by the Component Designer.
        InitializeComponent()
        
        'Add initialization code after the call to InitializeComponent.
    End Sub
    
    Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)
    MyBase.Install(stateSaver)
    
    'Register the custom component.
    '-----------------------------
    
    'The default location of the ESRIRegAsm utility.
    'Note how the whole string is embedded in quotes because of the spaces in the path.
    Dim cmd1 As String = """" + Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + "\ArcGIS\bin\ESRIRegAsm.exe" + """"
    
    'Obtain the input argument (via the CustomActionData Property) in the setup project.
    'An example CustomActionData property that is passed through might be something like:
    '/arg1="[ProgramFilesFolder]\[ProductName]\bin\ArcMapClassLibrary_Implements.dll",
    'which translates to the following on a default install:
    'C:\Program Files\MyGISApp\bin\ArcMapClassLibrary_Implements.dll.
    Dim part1 As String = Me.Context.Parameters.Item("arg1")
    
    'Add the appropriate command line switches when invoking the ESRIRegAsm utility.
    'In this case: /p:Desktop = means the ArcGIS Desktop product, /s = means a silent install.
    Dim part2 As String = " /p:Desktop /s"
    
    'It is important to embed the part1 in quotes in case there are any spaces in the path.
    Dim cmd2 As String = """" + part1 + """" + part2
    
    'Call the routing that will execute the ESRIRegAsm utility.
    Dim exitCode As Integer = ExecuteCommand(cmd1, cmd2, 10000)
    
End Sub

Public Overrides Sub Uninstall(ByVal savedState As System.Collections.IDictionary)
MyBase.Uninstall(savedState)

'Unregister the custom component.
'---------------------------------

'The default location of the ESRIRegAsm utility.
'Note how the whole string is embedded in quotes because of the spaces in the path.
Dim cmd1 As String = """" + Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + "\ArcGIS\bin\ESRIRegAsm.exe" + """"

'Obtain the input argument (via the CustomActionData Property) in the setup project.
'An example CustomActionData property that is passed through might be something like:
'/arg1="[ProgramFilesFolder]\[ProductName]\bin\ArcMapClassLibrary_Implements.dll",
'which translates to the following on a default install:
'C:\Program Files\MyGISApp\bin\ArcMapClassLibrary_Implements.dll.
Dim part1 As String = Me.Context.Parameters.Item("arg1")

'Add the appropriate command line switches when invoking the ESRIRegAsm utility.
'In this case: /p:Desktop = means the ArcGIS Desktop product, /u = means unregister the Custom Component, /s = means a silent install.
Dim part2 As String = " /p:Desktop /u /s"

'It is important to embed the part1 in quotes in case there are any spaces in the path.
Dim cmd2 As String = """" + part1 + """" + part2

'Call the routing that will execute the ESRIRegAsm utility.
Dim exitCode As Integer = ExecuteCommand(cmd1, cmd2, 10000)

End Sub

Public Shared Function ExecuteCommand(ByVal Command1 As String, ByVal Command2 As String, ByVal Timeout As Integer) As Integer

'Set up a ProcessStartInfo using your path to the executable (Command1) and the command line arguments (Command2).
Dim ProcessInfo As ProcessStartInfo = New ProcessStartInfo(Command1, Command2)
ProcessInfo.CreateNoWindow = True
ProcessInfo.UseShellExecute = False

'Invoke the process.
Dim Process As Process = Process.Start(ProcessInfo)
Process.WaitForExit(Timeout)

'Finish.
Dim ExitCode As Integer = Process.ExitCode
Process.Close()
Return ExitCode
End Function

End Class



However, I didn't see how this related to the code you provided.  Well, actually, I didn't put much effort into attempting to modify it because I thought this would actually perform the register for me.  But it doesn't do as expected --- I ran the Setup.exe on a workstation and everything installed just fine!  BUT!  It did not register the .dll(s) with ArcGIS/Map -- and I had to select the "add from file" command from the Customize menu.  And this actually did add the new toolbar.

Anyway -- Thanks for your help and I'll attempt to alter the Installer class with the translated VB.NET code you've provided.

Thanks!!!!!

james


EDIT: I think I will re-try with the entirely different Assembly that contains the new Installer class.  I was a bit confused on whether or not I could just use the existing one in my target assembly and just replace/update the code in the Installer class file.  Probably something really simple was left out.
0 Kudos
NeilClemmons
Honored Contributor
The solution in that link is pretty much the same thing as the code I posted except they're putting the installer class in its own project.  They then add new custom actions to the installer project to call this installer class.  I used the same installer class that I had been using just so that I wouldn't have to remove the old custom actions and add new ones (not that it would take any real effort to do so).  The big difference between their solution and mine is how the installer class get the path to your assembly.  In my code, I'm using the Reflection namespace to get the needed path.  It's easy and it works.  Their solution is getting the path through a property you have to set inside your installer project.  This is what they're doing in the walkthrough when they are setting the CustomActionData property in the custom action properties dialog.  If you use this solution, you'll have to change this so that it uses the location of the assembly you want to register.  I haven't tried it but you'll probably need to change the value to something like this:  /arg1="[TARGETDIR]\yourAssemblyName.dll".  This is assuming you're installing the assembly directly to the target directory.  Othewise you'll also have to append whatever subdirectory path you're installing to before the assembly filename.
0 Kudos