Class extension for use with ArcGIS Server

5329
8
Jump to solution
06-19-2015 06:44 AM
JohnFannon
Occasional Contributor III

Hi

We've developed a class extension for ArcGIS Desktop (v10.2.1) for a client who now wants to use serve some of their data, which is registered with the class extension, using ArcGIS Server (v10.2.1).

I've deployed the desktop class extension onto their development ArcGIS Server, which also has ArcGIS Desktop installed. The data is visible in ArcGIS Desktop, but when we publish this to server we are getting errors to do with the class extension along the lines of:

The Layer:'<layername>' in Map:'Layers' is invalid. The base table definition string "<tablename>" is invalid. Unable to create object class extension COM component [<tablename>].

I've just done a quick search and it looks like this is due to ArcGIS Server being 64-bit and the class extension is designed and compiled for desktop, which is 32-bit. So it sounds like we need to produce a version of the class extension that is compiled against the 64-bit server assemblies.

Is this all that is required? Has anyone else had to do this? What are the steps involved?

Any help most appreciated.

Cheers

John

0 Kudos
1 Solution

Accepted Solutions
JohnFannon
Occasional Contributor III

After much experimentation I have now managed to get our class extension working with ArcGIS Server.

For anyone else that is attempting to convert a 32-bit class extension into a 64-bit one that is compatible with server, the steps I took were as follows:

  1. Set the platform target for the project(s) to x64;
  2. Changed the installer class (which invokes the ESRIRegAsm.exe to perform registration) to use “/p:Server” instead of “/p:Desktop”;
  3. Set the TargetPlatform for the setup and deployment project to x64;
  4. Build the solution;
  5. Use Orca to force the msi to use the 64-bit InstallUtilLib.dll for the custom actions.

The final step was required because the resulting msi from the visual studio build would not install successfully and produced the following error:

Error 1001: Exception occurred while initializing the installation: System.BadImageFormatException: Could not load file or assembly....

The following MSDN blog discussed this issue and how to work around it:

http://blogs.msdn.com/b/heaths/archive/2006/02/01/64-bit-managed-custom-actions-with-visual-studio.a...

I followed the second set of steps, which are below and then the msi would successfully install and the class extension was correctly registered with server:

  1. Open the resulting .msi in Orca from the Windows Installer SDK
  2. Select the Binary table
  3. Click the Tables menu and then Add Row
  4. Enter, for example, InstallUtil64 for the Name
  5. Select the Data row and click the Browse button
  6. Browse to %WINDIR%\Microsoft.NET\Framework64\v2.0.50727
  7. Select InstallUtilLib.dll
  8. Click the Open button
  9. Click the OK button
  10. Select the CustomAction table
  11. For each custom action where the Source column is InstallUtil and only those custom actions that are 64-bit managed custom actions (or that were built with /platform:anycpu, the default, where you want to run as 64-bit custom actions), change the value to, for example, InstallUtil64

View solution in original post

0 Kudos
8 Replies
FreddieGibson
Occasional Contributor III

Hi John,

I'll have to see if I can find the documentation that lists the steps, but it appears that you understand this properly. ArcGIS Server is now a 64 bit product and requires that custom COM components be compiled to 64-bit and registered to it via the 64 bit esriregasm (C:\Program Files\Common Files\ArcGIS\bin\ESRIRegAsm.exe).

JohnFannon
Occasional Contributor III

I've been working on this today and have got so far, but still struggling to get my class extension working with server.

I've now set the platform target to x64, but references to Esri libraries all still look to be referring to the x86 version. The solution will compile, but gives me warnings like the below:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3912,5): warning : Type library exporter warning: Referenced type is defined in managed component, which is imported from a type library that could not be loaded because it was not registered (type: 'ESRI.ArcGIS.Geodatabase.IClassExtension'; component: 'C:\Windows\assembly\GAC_MSIL\ESRI.ArcGIS.Geodatabase\10.2.0.0__8fc3cc631e44ad86\ESRI.ArcGIS.Geodatabase.dll').

I've tried adding new references, but cannot see anything other than the x86 versions when I go to Add Reference > .Net tab.

Any ideas - surely someone has done this before??

Thanks in advance,

John

JohnFannon
Occasional Contributor III

After much experimentation I have now managed to get our class extension working with ArcGIS Server.

For anyone else that is attempting to convert a 32-bit class extension into a 64-bit one that is compatible with server, the steps I took were as follows:

  1. Set the platform target for the project(s) to x64;
  2. Changed the installer class (which invokes the ESRIRegAsm.exe to perform registration) to use “/p:Server” instead of “/p:Desktop”;
  3. Set the TargetPlatform for the setup and deployment project to x64;
  4. Build the solution;
  5. Use Orca to force the msi to use the 64-bit InstallUtilLib.dll for the custom actions.

The final step was required because the resulting msi from the visual studio build would not install successfully and produced the following error:

Error 1001: Exception occurred while initializing the installation: System.BadImageFormatException: Could not load file or assembly....

The following MSDN blog discussed this issue and how to work around it:

http://blogs.msdn.com/b/heaths/archive/2006/02/01/64-bit-managed-custom-actions-with-visual-studio.a...

I followed the second set of steps, which are below and then the msi would successfully install and the class extension was correctly registered with server:

  1. Open the resulting .msi in Orca from the Windows Installer SDK
  2. Select the Binary table
  3. Click the Tables menu and then Add Row
  4. Enter, for example, InstallUtil64 for the Name
  5. Select the Data row and click the Browse button
  6. Browse to %WINDIR%\Microsoft.NET\Framework64\v2.0.50727
  7. Select InstallUtilLib.dll
  8. Click the Open button
  9. Click the OK button
  10. Select the CustomAction table
  11. For each custom action where the Source column is InstallUtil and only those custom actions that are 64-bit managed custom actions (or that were built with /platform:anycpu, the default, where you want to run as 64-bit custom actions), change the value to, for example, InstallUtil64
0 Kudos
Søren_BollOvergaard
New Contributor II

I have very similar problem.

I want to make trigger on geometry change which make some custom action.

I created class extension and it's working when I want to deploy it on ArcGIS Desktop, but when I want to publish this on ArcGIS Server it give me:
Warning when publishing: 20019: Layer is being published with custom class extension

Error on ArcMap

Error on Server logs:
<Msg time="2017-06-19T20:43:43,941" type="SEVERE" code="8252" source="System/PublishingTools.GPServer" process="4452" thread="228" methodName="" machine="machine_name" user="" elapsed="">Instance of the service 'System/PublishingTools.GPServer' crashed. Please see if an error report was generated in 'C:\arcgisserver\logs\<mashine_name>\errorreports'. To send an error report to Esri, compose an e-mail to ArcGISErrorReport@esri.com and attach the error report file.</Msg>
<Msg time="2017-06-19T20:44:51,948" type="SEVERE" code="8254" source="Server" process="4452" thread="1" methodName="" machine="machine_name" user="" elapsed="">The containing process for 'System/PublishingTools' job 'jba127676c8764dd0acf4d8a54' has crashed.</Msg>

No raport in pointed location.


I tried to to solve this in described way but after register dll with ESRIRegAsm.exe with server option I'm still get the error like no server registration was made.

I have no more ideas how to solve this.

0 Kudos
JohnFannon
Occasional Contributor III

Hi Soren

It sounds like your class extension is built against the 32-bit assemblies, which explains why it works with desktop but not server. Server is looking for a class extension that is 64-bit and cannot find one. You need to create a separate solution for the server version and build this on a machine where ArcGIS Server is installed? This is required to build against the 64-bit Esri assemblies.

You also need to follow all the other steps above, including setting the platform target to 64-bit for each project and for the setup and deployment project and changing the installer class (InstallerClass.cs) code to use the "/p:server" flag when installing/uninstalling.

Here is the installer class for our class extension:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Diagnostics;

namespace InvokeESRIRegASM
{
    [RunInstaller(true)]
    public partial class InstallerClass : System.Configuration.Install.Installer
    {
        public InstallerClass()
        {
            InitializeComponent();
        }

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.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.
            string cmd1 = "\"" + 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.
            string part1 = this.Context.Parameters["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.
            string part2 = " /p:Server /s";

            //It is important to embed the part1 in quotes in case there are any spaces in the path.
            string cmd2 = "\"" + part1 + "\"" + part2;

            //Call the routing that will execute the ESRIRegAsm utility.
            int exitCode = ExecuteCommand(cmd1, cmd2, 10000);
        }

        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            base.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.
            string cmd1 = "\"" + 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 translate to the following on a default install:
            //C:\Program Files\MyGISApp\bin\ArcMapClassLibrary_Implements.dll.
            string part1 = this.Context.Parameters["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.
            string part2 = " /p:Server /u /s";

            //It is important to embed the part1 in quotes in case there are any spaces in the path.
            string cmd2 = "\"" + part1 + "\"" + part2;

            //Call the routing that will execute the ESRIRegAsm utility.
            int exitCode = ExecuteCommand(cmd1, cmd2, 10000);
        }

        public static int ExecuteCommand(string Command1, string Command2, int Timeout)
        {
            //Set up a ProcessStartInfo using your path to the executable (Command1) and the command line arguments (Command2).
            ProcessStartInfo ProcessInfo = new ProcessStartInfo(Command1, Command2);
            ProcessInfo.CreateNoWindow = true;
            ProcessInfo.UseShellExecute = false;

            //Invoke the process.
            Process Process = Process.Start(ProcessInfo);
            Process.WaitForExit(Timeout);

            //Finish.
            int ExitCode = Process.ExitCode;
            Process.Close();
            return ExitCode;
        }
    }
}

Once you've made these changes, you then need to build the solution and modify the resulting msi using Orca as described above to ensure that custom actions run using the 64-bit install utility (InstallUtil64).

Note that the steps I described work for 10.2.1 and I have not tried building with later versions, but assume the process is similar.

Regards

John

0 Kudos
Søren_BollOvergaard
New Contributor II

Hi John,

Thank you so much for helping.

So what have I done today:

1) I created separate solution with Visual Studio.
2) I built it on Server machine with selected Platform Target for x64
3) I register generated dll file with command: > .\ESRIRegAsm.exe "C:\proj\ClassExtension - x64\bin\Debug64\Extension.dll" /e /p:server /v:10.5 /w:"C:\proj\ClassExtension - x64\bin"
4) I change the name/zip and put ecfg file to C:\Program Files\ArcGIS\Server\bin\Configuration\CATID

(like in this thread: https://community.esri.com/thread/66705 )

Still doesn't working.

But I don't have msi (only dll) file generated in my project so I didn't modify the resulting msi using Orca.

0 Kudos
JohnFannon
Occasional Contributor III

Are you using the correct 64-bit version of ESRIRegAsm?

This should be at:

C:\Program Files\Common Files\ArcGIS\bin\ESRIRegAsm.exe

I'm not sure your step 4 is necessary as my installer class does not do anything with the ecfg file, it just executes the 64-bit EsriRegAsm.

If you aren't installing using an MSI you can ignore the steps to edit the MSI with Orca.

0 Kudos
Søren_BollOvergaard
New Contributor II

Yes, I'm using C:\Program Files\Common Files\ArcGIS\bin\ESRIRegAsm.exe

But still server does not see extension.

I checked also log on ArcGIS Server but I found the same message and also same REST null exception:

SEVERE Jun 20, 2017, 1:04:40 PM The containing process for 'System/PublishingTools' job 'jfc08016a32524d99906c9acb' has crashed. Server
SEVERE Jun 20, 2017, 1:04:20 PM Unable to process request. null Rest
SEVERE Jun 20, 2017, 1:04:10 PM Unable to process request. null Rest
SEVERE Jun 20, 2017, 1:03:32 PM Instance of the service 'System/PublishingTools.GPServer' crashed. Please see if an error report was generated in 'C:\arcgisserver\logs\<machin_name>\errorreports'. To send an error report to Esri, compose an e-mail to ArcGISErrorReport@esri.com and attach the error report file. System/PublishingTools.GPServer
SEVERE Jun 20, 2017, 1:02:53 PM Unable to process request. null Rest
SEVERE Jun 20, 2017, 1:00:57 PM The containing process for 'System/PublishingTools' job 'j0efe7e6f7cbc56ebdfb2318200' has crashed. Server

0 Kudos