# How to trigger a Python script from an ArcGIS Desktop “save” operation?

Similar to the question Run a Python Script when opening an MXD, I'm looking for a way to run a Python script that is triggered when the "Save" command/button is pressed.

I've read the Creating a Python add-in application extension help for building a Python Add-In, but I don't see an interface in the Extension class that triggers upon Save, only close.

Is there something I might be overlooking? Otherwise, what are my alternative options other than ArcObjects, which is a road I am not willing to explore for this idea?

I found something in ArcObjects that will do the job. Thanks to This Post by Kirk Kuykendall as implemented on This Post by Rebecca Zeckoski. This is very counter-intuitive, the interface to find button clicks is ICustomizationFilter, which detects when a command is about to run (any command that implements ICommand I think).

Using Visual Studio I created an ArcMap addin and selected Extension and AutoLoad, then added a class alongside which implements ICustomizationFilter, using the LockCustomization method of the application the class is linked to the event then call the python script by (in this case) shell() other methods are discussed in this post; I'm not sure if you can make an ICommandItem from a python add-in but that would be how I would execute custom ArcObjects code.

Public Class Extension1
'I am not using this event'
Public Sub New()
End Sub

Protected Overrides Sub OnStartup()
WireDocumentEvents() ' uncomment this, it is here by default'
End Sub

Protected Overrides Sub OnShutdown()
End Sub

Private Sub WireDocumentEvents()
End Sub

Private Sub ArcMapNewDocument()
' Wire the event here in case the user starts with a blank'
' map and saves... this event does not survive a file::open'
Dim pCustFlt As ESRI.ArcGIS.Framework.ICustomizationFilter = New CustFlt
My.ArcMap.Application.LockCustomization("myLock", pCustFlt)
End Sub
Private Sub ArcMapDocumentOpen()
' When the document is opened wire the events to it'
' otherwise they dissapear after a new MXD is opened.'
Dim pCustFlt As ESRI.ArcGIS.Framework.ICustomizationFilter = New CustFlt
My.ArcMap.Application.LockCustomization("myLock", pCustFlt)
End Sub
End Class
Class CustFlt   ' new class to implement the filter'
Implements ESRI.ArcGIS.Framework.ICustomizationFilter

Public Function OnCustomizationEvent(custEventType As ESRI.ArcGIS.Framework.esriCustomizationEvent, eventCtx As Object) As Boolean Implements ESRI.ArcGIS.Framework.ICustomizationFilter.OnCustomizationEvent
' modified from Rebecca Zeckoskis' post http://rzeckoskiengineering.blogspot.com.au/2012/06/capturing-button-clicks-in-arcobjects.html
' inspired by Kirk Kuykendalls' post https://gis.stackexchange.com/questions/8149/can-i-listen-to-the-icommandbar-or-icommand-onclick-event

If custEventType = ESRI.ArcGIS.Framework.esriCustomizationEvent.esriCEInvokeCommand Then
' if it is a call to invoke a command then find the command
' that is being invoked (executed)
Dim cmd As ESRI.ArcGIS.Framework.ICommandItem
cmd = TryCast(eventCtx, ESRI.ArcGIS.Framework.ICommandItem)

' find the name of the command, there's a whole bunch of them
' at http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#//00010000029s000000
' search by tool caption to find others, you can use either the name or GUID/CLSID
If cmd.Name = "File_Save" Then
MsgBox("Customization Save") ' run your python here
' if you have a custom ArcObjects tool here you could make a new
' ICommandItem and execute, not sure if that works for python
' addins. You can call the shell with the path like this:
Shell("c:\path\to\your\script.py", AppWinStyle.Hide, False) ' returns an integer
' see https://stackoverflow.com/questions/13807860/execute-python-script-from-vb-net
End If
End If

Return False

End Function
End Class


I think your best bet will be to create a custom button that saves your map document - mxd.save() - as well as whatever operations you wish.

• Like a 'save with benefits' button.. that would work but I can see what he's trying to do; the best way to ensure a script is run is to not give the operator the option... with a 'special save' button, how can you ensure that the user has clicked that one and not just closed the window and hit yes on the save dialog? – Michael Stimson Mar 4 '15 at 23:17
• That's a good suggestion if there are no other options. But as @MichaelMiles-Stimson mentioned, the whole point is to provide a "pain free" experience that just happens behind the scenes. – RyanKDalton Mar 11 '15 at 21:05