ArcObjects Library Reference  

Form1

About the Automate ArcGIS Desktop applications Sample

[C#]

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.esriSystem;

namespace DesktopAutomationCS
{
    public partial class Form1 : Form
    {
        private IApplication m_application;

        //Application removed event
        private IAppROTEvents_Event m_appROTEvent;
        private int m_appHWnd = 0;

        //Retrieve the hWnd of the active popup/modal dialog of an owner window
        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern int GetLastActivePopup(int hwndOwnder);

        public Form1()
        {
          ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine);
            InitializeComponent();

            //Preselect option
            cboApps.SelectedIndex = 0;
        }

        private void btnStartApp_Click(object sender, EventArgs e)
        {
            IDocument doc = null;
            try
            {
                this.Cursor = Cursors.WaitCursor;
                switch (cboApps.SelectedItem.ToString())
                {
                    case "ArcMap":
                        doc = new ESRI.ArcGIS.ArcMapUI.MxDocumentClass();
                        break;
                    case "ArcScene":
                        doc = new ESRI.ArcGIS.ArcScene.SxDocumentClass();
                        break;
                    case "ArcGlobe":
                        doc = new ESRI.ArcGIS.ArcGlobe.GMxDocumentClass();
                        break;
                }
            }
            catch { } //Fail if you haven't installed the target application
            finally
            {
                this.Cursor = Cursors.Default;
            }

            if (doc != null)
            {
                //Advanced (AppROT event): Handle manual shutdown, comment out if not needed
                m_appROTEvent = new AppROTClass();
                m_appROTEvent.AppRemoved += new IAppROTEvents_AppRemovedEventHandler(m_appROTEvent_AppRemoved);

                //Get a reference of the application and make it visible
                m_application = doc.Parent;
                m_application.Visible = true;
                m_appHWnd = m_application.hWnd;

                //Enable/disable controls accordingly
                txtShapeFilePath.Enabled = true;
                btnShutdown.Enabled = true;
                btnDrive.Enabled = ShouldEnableAddLayer;
                cboApps.Enabled = btnStartApp.Enabled = false;
            }
            else
            {
                m_appROTEvent = null;
                m_application = null;

                txtShapeFilePath.Enabled = false;
                btnShutdown.Enabled = btnDrive.Enabled = false;
                cboApps.Enabled = btnStartApp.Enabled = true;
            }
        }

        private void btnShutdown_Click(object sender, EventArgs e)
        {
            if (m_application != null)
            {
                //Try to close any modal dialogs by sending the Escape key
                //It doesn't handle the followings: 
                //- VBA is up and has a modal dialog
                //- Modal dialog doesn't close with the Escape key
                Microsoft.VisualBasic.Interaction.AppActivate(m_application.Caption);
                int nestModalHwnd = 0;
                while ((nestModalHwnd = GetLastActivePopup(m_application.hWnd)) != m_application.hWnd)
                {
                    SendKeys.SendWait("{ESC}");
                }

                //Manage document dirty flag - abandon changes
                IDocumentDirty2 docDirtyFlag = (IDocumentDirty2)m_application.Document;
                docDirtyFlag.SetClean();

                //Stop listening before exiting
                m_appROTEvent.AppRemoved -= new IAppROTEvents_AppRemovedEventHandler(m_appROTEvent_AppRemoved);
                m_appROTEvent = null;

                //Exit
                m_application.Shutdown();
                m_application = null;
                
                //Reset UI for next automation
                txtShapeFilePath.Enabled = false;
                btnShutdown.Enabled = btnDrive.Enabled = false;
                cboApps.Enabled = btnStartApp.Enabled = true;
            }
        }

        private void btnDrive_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            try
            {
                IObjectFactory objFactory = m_application as IObjectFactory;

                //Use reflection to get ClsID of ShapefileWorkspaceFactory
                Type shpWkspFactType = typeof(ShapefileWorkspaceFactoryClass);
                string typeClsID = shpWkspFactType.GUID.ToString("B");

                string shapeFile = System.IO.Path.GetFileNameWithoutExtension(txtShapeFilePath.Text);
                string fileFolder = System.IO.Path.GetDirectoryName(txtShapeFilePath.Text);
                IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)objFactory.Create(typeClsID);
                IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspaceFactory.OpenFromFile(fileFolder, 0); //(@"C:\data\test", 0);

                //Create the layer
                IFeatureLayer featureLayer = (IFeatureLayer)objFactory.Create("esriCarto.FeatureLayer");
                featureLayer.FeatureClass = featureWorkspace.OpenFeatureClass(shapeFile); // ("worldgrid");
                featureLayer.Name = featureLayer.FeatureClass.AliasName;

                //Add the layer to document
                IBasicDocument document = (IBasicDocument)m_application.Document;
                document.AddLayer(featureLayer);
                document.UpdateContents();
            }
            catch { } //Or make sure it is a valid shp file first

            this.Cursor = Cursors.Default;
        }

        private void txtShapeFilePath_TextChanged(object sender, EventArgs e)
        {
            btnDrive.Enabled = ShouldEnableAddLayer;
        }

        private bool ShouldEnableAddLayer
        {
            get
            {
                //Only allow .shp file
                if (System.IO.File.Exists(txtShapeFilePath.Text))
                {
                    return (System.IO.Path.GetExtension(txtShapeFilePath.Text).ToLower() == ".shp");
                }
                else
                {
                    return false;
                }
            }
        }

        #region "Handle the case when the application is shutdown by user manually"
        void m_appROTEvent_AppRemoved(AppRef pApp)
        {
            //Application manually shuts down. Stop listening
            if (pApp.hWnd == m_appHWnd) //compare by hwnd
            {
                m_appROTEvent.AppRemoved -= new IAppROTEvents_AppRemovedEventHandler(m_appROTEvent_AppRemoved);
                m_appROTEvent = null;
                m_application = null;
                m_appHWnd = 0;

                //Reset UI has to be in the form UI thread of this application, 
                //not the AppROT thread;
                if (this.InvokeRequired) //i.e. not on the right thread
                {
                    this.BeginInvoke(new IAppROTEvents_AppRemovedEventHandler(AppRemovedResetUI), pApp);
                }
                else
                {
                    AppRemovedResetUI(pApp); //call directly
                }
            }
        }

        void AppRemovedResetUI(AppRef pApp)
        {
            txtShapeFilePath.Enabled = false;
            btnShutdown.Enabled = btnDrive.Enabled = false;
            cboApps.Enabled = btnStartApp.Enabled = true;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //Clean up
            if (m_appROTEvent != null)
            {
                m_appROTEvent.AppRemoved -= new IAppROTEvents_AppRemovedEventHandler(m_appROTEvent_AppRemoved);
                m_appROTEvent = null;
            }
        }
        #endregion
    }
}
[Visual Basic .NET]

Form1.vb

Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.DataSourcesFile
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.esriSystem

Public Class Form1
    Private m_application As IApplication

    'Application removed event
    Private m_appHWnd As Integer = 0
    Private m_appROTEvent As IAppROTEvents_Event

    'Retrieve the hWnd of the active popup/modal dialog of an owner window
    Declare Auto Function GetLastActivePopup Lib "user32" (ByVal hwndOwnder As Integer) As Integer

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'Bind to Engine
    ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine)
    'Preselect option
        cboApps.SelectedIndex = 0
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
        'Clean up
        m_application = Nothing
        m_appROTEvent = Nothing
    End Sub

    Private Sub btnStartApp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartApp.Click
        Dim doc As IDocument = Nothing
        Try
            Me.Cursor = Cursors.WaitCursor
            Select Case cboApps.SelectedItem.ToString()
                Case "ArcMap"
                    doc = New ESRI.ArcGIS.ArcMapUI.MxDocumentClass()
                Case "ArcScene"
                    doc = New ESRI.ArcGIS.ArcScene.SxDocumentClass()
                Case "ArcGlobe"
                    doc = New ESRI.ArcGIS.ArcGlobe.GMxDocumentClass()
            End Select
        Catch
        Finally
            Me.Cursor = Cursors.Default
        End Try

        If doc IsNot Nothing Then
            'Advanced (AppROT event): Handle manual shutdown, comment out if not needed
            m_appROTEvent = New AppROTClass()
            AddHandler m_appROTEvent.AppRemoved, AddressOf m_appROTEvent_AppRemoved

            'Get a reference of the application and make it visible
            m_application = doc.Parent
            m_application.Visible = True
            m_appHWnd = m_application.hWnd

            'Enable/disable controls accordingly
            txtShapeFilePath.Enabled = True
            btnShutdown.Enabled = True
            btnDrive.Enabled = ShouldEnableAddLayer
            cboApps.Enabled = False
            btnStartApp.Enabled = False
        Else
            m_appROTEvent = Nothing
            m_application = Nothing

            txtShapeFilePath.Enabled = False
            btnShutdown.Enabled = False
            btnDrive.Enabled = False
            cboApps.Enabled = True
            btnStartApp.Enabled = True
        End If
    End Sub

    Private Sub txtShapeFilePath_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtShapeFilePath.TextChanged
        btnDrive.Enabled = ShouldEnableAddLayer
    End Sub

    Private ReadOnly Property ShouldEnableAddLayer()
        Get
            If System.IO.File.Exists(txtShapeFilePath.Text) Then
                Return System.IO.Path.GetExtension(txtShapeFilePath.Text).ToLower() = ".shp"
            Else
                Return False
            End If
        End Get
    End Property

    Private Sub btnDrive_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDrive.Click
        Me.Cursor = Cursors.WaitCursor
        Try
            Dim objFactory As IObjectFactory = DirectCast(m_application, IObjectFactory)

            'Use reflection to get ClsID of ShapefileWorkspaceFactory
            Dim shpWkspFactType As Type = GetType(ShapefileWorkspaceFactoryClass)
            Dim typeClsID As String = shpWkspFactType.GUID.ToString("B")

            Dim shapeFile As String = System.IO.Path.GetFileNameWithoutExtension(txtShapeFilePath.Text)
            Dim fileFolder As String = System.IO.Path.GetDirectoryName(txtShapeFilePath.Text)
            Dim workspaceFactory As IWorkspaceFactory = DirectCast(objFactory.Create(typeClsID), IWorkspaceFactory)
            Dim featureWorkspace As IFeatureWorkspace = DirectCast(workspaceFactory.OpenFromFile(fileFolder, 0), IFeatureWorkspace)

            'Create the layer
            Dim featureLayer As IFeatureLayer = DirectCast(objFactory.Create("esriCarto.FeatureLayer"), IFeatureLayer)
            featureLayer.FeatureClass = featureWorkspace.OpenFeatureClass(shapeFile)
            featureLayer.Name = featureLayer.FeatureClass.AliasName

            'Add the layer to document
            Dim document As IBasicDocument = DirectCast(m_application.Document, IBasicDocument)
            document.AddLayer(featureLayer)
            document.UpdateContents()
        Catch
        End Try

        Me.Cursor = Cursors.Default
    End Sub

    Private Sub btnShutdown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShutdown.Click
        If m_application IsNot Nothing Then

            'Try to close any modal dialogs by sending the Escape key
            'It doesn't handle the followings: 
            '- VBA is up and has a modal dialog
            '- Modal dialog doesn't close with the Escape key
            AppActivate(m_application.Caption)
            Dim nestModalHwnd As Integer = GetLastActivePopup(m_application.hWnd)
            Do Until nestModalHwnd = m_application.hWnd
                SendKeys.SendWait("{ESC}")
                nestModalHwnd = GetLastActivePopup(m_application.hWnd)
            Loop

            'Manage document dirty flag - abandon changes
            Dim docDirtyFlag As IDocumentDirty2 = DirectCast(m_application.Document, IDocumentDirty2)
            docDirtyFlag.SetClean()

            'Exit
            RemoveHandler m_appROTEvent.AppRemoved, AddressOf m_appROTEvent_AppRemoved
            m_appROTEvent = Nothing

            m_application.Shutdown()
            m_application = Nothing
            m_appHWnd = 0


            'Reset UI for next automation
            txtShapeFilePath.Enabled = False
            btnShutdown.Enabled = False
            btnDrive.Enabled = False
            cboApps.Enabled = True
            btnStartApp.Enabled = True
        End If
    End Sub

#Region "Handle the case when the application is shutdown by user manually"
    Private Sub m_appROTEvent_AppRemoved(ByVal pApp As AppRef)
        'Application is shut down manually. Stop listening
        If pApp.hWnd = m_appHWnd Then 'compare by hwnd
            RemoveHandler m_appROTEvent.AppRemoved, AddressOf m_appROTEvent_AppRemoved
            m_appROTEvent = Nothing
            m_application = Nothing
            m_appHWnd = 0

            'Reset UI has to be in the form UI thread of this application, 
            'not the AppROT thread;
            If (Me.InvokeRequired) Then 'i.e. not on the right thread
                Me.BeginInvoke(New IAppROTEvents_AppRemovedEventHandler(AddressOf AppRemovedResetUI), pApp)
            Else
                AppRemovedResetUI(pApp) 'call directly
            End If
        End If
    End Sub

    Private Sub AppRemovedResetUI(ByVal pApp As AppRef)
        txtShapeFilePath.Enabled = False
        btnShutdown.Enabled = False
        btnDrive.Enabled = False
        cboApps.Enabled = True
        btnStartApp.Enabled = True
    End Sub
#End Region
End Class