3

I am trying to create an executable which does the following.

  1. Accepts 3 arguments
  2. Finds local ArcMap process. Brings process window to foreground.
  3. Uses ArcMap session to query 3 arguments and zoom to specific location.

I am able to do everything except #3. I do not know how to identify arcmap. the bottom section of code works when the code is built as an ESRI add-in but this is an executable which is run outside of arcgis. can someone let me know what I can do to fix this?

Error 3 The name 'ArcMap' does not exist in the current context

public class ZoomToGeo : ESRI.ArcGIS.Desktop.AddIns.Extension
{

    static string FeatClassName;
    static string QueryFieldName;
    static string UNIQUE_ID;

    static void Main(string[] args)
    {
        try
        {
            if (args.Length == 3)
            {
                FeatClassName = args[0].ToString().ToUpper();
                QueryFieldName = args[1].ToString().ToUpper();
                UNIQUE_ID = args[2].ToString();

                Process[] p = Process.GetProcessesByName("ArcMap");
                if (p.Length > 0)
                {
                    foreach (Process i in p)
                    {
                        try
                        {
                            ShowWindow(i.MainWindowHandle, SW_RESTORE);
                            SetForegroundWindow(i.MainWindowHandle);
                            ArcMap.Events.OpenDocument += new ESRI.ArcGIS.ArcMapUI.IDocumentEvents_OpenDocumentEventHandler(zoomToPOI);
                        }
                        catch (Exception Ex)
                        {
                            MessageBox.Show("Foreground, zoom to point" + Ex.Message);
                        }
                    }                                      
                }
            }

        }
        catch (Exception Ex)
        {
            MessageBox.Show("Main Thread:\n" + Ex.Message);
        }
    }

    static void zoomToPOI()
    {
        IFeatureLayer FeatLayer;
        IFeatureClass FeatClass;
        ILayer TargetLayer = null;
        IFeatureClass TargetFeatClass = null;
        IFeature TargetFeature;
        IQueryFilter QF = new QueryFilterClass();
        IFeatureCursor FeatCur;
        IApplication App = ArcMap.Application;
        IMxDocument MxDoc = (IMxDocument)App.Document;
        IMap CurrMap = MxDoc.FocusMap;
        IActiveView ActView = MxDoc.ActiveView;
        IDisplay Disp = ActView.ScreenDisplay;
        IEnumLayer Layers = CurrMap.Layers;
        ILayer Layer = Layers.Next();

        while (Layer != null)
        {
            if (Layer is IFeatureLayer)
            {
                FeatLayer = (IFeatureLayer)Layer;
                FeatClass = FeatLayer.FeatureClass;
                if (FeatClass.AliasName.ToUpper() == FeatClassName)
                {
                    TargetLayer = Layer;
                    TargetFeatClass = FeatClass;
                }
            }
            Layer = Layers.Next();
        }
        if (TargetFeatClass != null)
        {
            QF.WhereClause = QueryFieldName + " = \'" + UNIQUE_ID + "\'";
            FeatCur = TargetFeatClass.Search(QF, false);
            TargetFeature = FeatCur.NextFeature();
            if (TargetFeature != null)
            {
                CurrMap.ClearSelection();
                CurrMap.SelectFeature(TargetLayer, TargetFeature);
                ActView.Refresh();

                //Zoom to Selected
                UID ZTS_UID = new UIDClass();
                ZTS_UID.Value = "esriArcMapUI.ZoomToSelectedCommand";
                App.Document.CommandBars.Find(ZTS_UID).Execute();
            }
            else
            {
                //target feature couldn't be found. Notify and exit.
                MessageBox.Show("A feature in " + FeatClassName + " with " + QueryFieldName + " of " + UNIQUE_ID + " could not be found.");
            }

        }
    }

    protected override void OnShutdown()
    {

    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    private const int SW_RESTORE = 9;

}
  • 1
    I suggest looking into IAppROT and perhaps also IObjectFactory. – Kirk Kuykendall Sep 9 '16 at 18:19
  • @Midavalo ArcMap 10.2.2 – Anthony Barron Sep 9 '16 at 18:28
  • 3
    I'd actually hope that step #3 is impossible, since being able to take over a running application and force it to do things it was not prepared to do would be a HUGE security hole in Windows. You could make an add-in/extension DLL which enabled this sort of interprocess communication, and that would be considered a security threat as well, but at least it would be a proactive step to allow that type of communication. – Vince Sep 9 '16 at 19:52
  • What you are talking about is Automation, you hook into a running instance ArcMap through the IAppROT interface. – Hornbydd Sep 10 '16 at 12:00
  • @Vince one can always hope, but I think this is <del>flaw</del> feature exists. – Kirk Kuykendall Sep 12 '16 at 14:29
1

You are probably mixing up different things.

On the one hand you can create and ESRI Add-in (for example an Extension derived from ESRI.ArcGIS.Desktop.AddIns.Extension). These Add-Ins are intended for a use inside a running ArcGIS application as an extension (inside the ArcMap process space). How the Add-In appears and when it is loaded in an ArcMap session can be steered by the file Config.esriaddinx. From the Add-In you have nearly full control of the ArcMap application and the MXD.

On the other hand you can create a stand alone application. This has nothing to do with the ESRI.ArcGIS.Desktop.AddIns.Extension. Please have a look at the Building stand-alone applications for a quick overview about different application types.

In your case I guess you want to have your own application which steers an own ArcMap process. Please have a look at Automating ArcGIS for Desktop applications for details. Please have a detailed look at the notes at the bottom of this article.

Another option as Kirk and Hornbydd already mentioned is to use the IAppROT. Here you'll need to reference ESRI.ArcGIS.Framework and ESRI.ArcGIS.Display. Please try this:

static void Main(string[] args)
{
    //Initialisieren der ESRI Lizenz
    bool LicenseKo = m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeArcEditor },
        new esriLicenseExtensionCode[] { esriLicenseExtensionCode.esriLicenseExtensionCodeMLE, esriLicenseExtensionCode.esriLicenseExtensionCodeDataInteroperability });
    if (!LicenseKo)
    {
        IAppROT myAppROT = new AppROTClass();
        for (int i = 0; i < myAppROT.Count; i++)
        {
            IApplication theApp = myAppROT.Item[i] as IApplication;
            if (theApp != null)
            {
                IMxDocument mxDoc = theApp.Document as IMxDocument;
                IMap theMap = mxDoc.FocusMap;
            }
        }
        m_AOLicenseInitializer.ShutdownApplication();
    }
}
|improve this answer|||||
  • 1
    This can fail if ArcCatalog is running. – Kirk Kuykendall Sep 12 '16 at 13:58

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.