5

I have an issue with using ArcObjects and the Geoprocessor .dll library in a UnitTest environment (MSTest) in Visual Studio. When I test a program that creates an ESRI.ArcGIS.Geoprocessor object and I try to use it I get an error thrown:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Debug Trace: Could not load file or assembly 'GpMetadataFunctions, Version=10.2.0.0, Culture=neutral, PublicKeyToken=8fc3cc631e44ad86' or one of its dependencies. The system cannot find the file specified.

This always occurs when I Debug and step through the Unit test. Running the Unit Test (no step through in the debugger) will cause the test to stay pending indefinitely.

Details:

Everything works fine when run in the program itself or call the program from a separate VS project. This issue only occurs when I attempt to call the method from a Unit test style project.

I'm new to Unit Testing with .NET so there could be something inherent to the way it works that I am not understanding.

Tried:

  • seem able to test other ArcGIS COM and other 3rd party libraries/dlls so am assuming something particular to the way the Geoprocessor class/library/dll is invoked is issue (hence post on gis stack exchange).
  • Tried on other machines with same behavior.
  • tried on VS 2010 with same behaviour (I'm running VS2015)
  • tried with Admin rights for Visual Studio

I have found posts of users running unit tests on ArcObjects including from ESRI so I know that it is being done but code examples are scarce. Any thoughts or advice is welcome.

Update/Correction: If I load GPMetadataFunctions.dll from the ArcGIS installation folder into the project or the GAC of the targeted .NET framework the test will run but it will still fail when stepping through in the debugger. When it fails I get the same message as above without debug trace.

Example: Project.cs

using ESRI.ArcGIS.ConversionTools;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geoprocessor;
using System;
using System.Runtime.CompilerServices; //added to allow testing of private methods

[assembly: InternalsVisibleTo("ArcObjectsSampleTests")]
namespace ArcObjectsSample
{
class Program
{
    [STAThread()]
    static void Main(string[] args)
    {
        ProcessStuff myProcessStuff = new ProcessStuff();
        myProcessStuff.OpenFolder();
        myProcessStuff.Run(
            @"C:\temp\test\foo.shp",
            @"C:\temp\test\",
            "fooCopy.shp"
            );
    }
}


internal class ProcessStuff
{
    internal ProcessStuff()
    {
        //Get a license checked out:
        ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop);
        IAoInitialize aoInitialize = new AoInitializeClass();
        esriLicenseStatus stat;
        stat = aoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeBasic);
        // if not licensed - initialize license
        if (stat == esriLicenseStatus.esriLicenseNotLicensed) stat = aoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);
    }

    internal void Run(string inputFC, string outputPath, string outputFCName)
    {
        Console.WriteLine("Starting");
        Geoprocessor gp = new Geoprocessor();
        gp.OverwriteOutput = true;

       //Testing fails on the following line below (does not matter what is set as workspace)
        gp.SetEnvironmentValue("workspace", "c:/temp");
        FeatureClassToFeatureClass featureClassTool = new FeatureClassToFeatureClass();
        featureClassTool.in_features = inputFC; 
        featureClassTool.out_path = outputPath; 
        featureClassTool.out_name = outputFCName;

        gp.Execute(featureClassTool, null);


        Console.WriteLine("Done");
        Console.WriteLine("Press any key to close...");
        Console.ReadKey();
    }

}
}

UnitTest Project.cs

using Microsoft.VisualStudio.TestTools.UnitTesting;
using ArcObjectsSample;
using System;
using System.Collections.Generic;

namespace ArcObjectsSample.Tests
{
[TestClass()]
public class ProcessStuffTests
{
    [TestMethod()]
    [STAThread]
    public void RunTest()
    {


       ProcessStuff myProcessStuff = new ProcessStuff();

        myProcessStuff.Run(
            @"C:\temp\test\foo.shp",
            @"C:\temp\test\",
            "fooCopy.shp"
            );


        //myProcessStuff.OpenFolder();
        //do some test of the results here
    }
}
}
  • 2
    Wild guess: verify both projects target the same platform (x86, x64) and not Any CPU. – Richard Morgan Nov 21 '17 at 20:08
  • Good point. I should have mentioned that I do have both projects targeting x86 with this behaviour. That was ESRI Canada's only advice also. – user3147913 Nov 22 '17 at 1:31
  • 2
    2nd wild guess: is GPMetadataFunctions in the GAC? See this thread: community.esri.com/thread/14848 even though the issue is with Python. – Richard Morgan Nov 22 '17 at 10:11
  • Gave that a try. When it is loaded I no longer get the Debug Trace portion of the above error but I still get the same System.AccessViolationException message. Same behaviour as if I loaded the dll as a project reference. – user3147913 Nov 22 '17 at 20:16
  • Correction/Update: The test works with GPMetadataFunctions added as a reference if I run it. It only fails if I step through in the debugger. I'm going to update my question accordingly. @RichardMorgan +1 – user3147913 Nov 23 '17 at 12:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.