public class GPMessageEventHandler : IGeoProcessorEvents
{
private MessageDetails messageDetails = null;
public GPMessageEventHandler(MessageDetails messageDetails)
{
this.messageDetails = messageDetails;
}
public void OnMessageAdded(IGPMessage message)
{
this.messageDetails(message);
}
public void PostToolExecute(IGPTool tool, IArray values, int result, IGPMessages messages)
{
}
public void PreToolExecute(IGPTool tool, IArray values, int processID)
{
}
public void ToolboxChange()
{
}
}
Prima di eseguire il geoprocesso registriamo l'istanza della classe che riceve gli eventi mediante RegisterGeoProcessorEvents.
private static readonly log4net.ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly bool isDebugEnabled = log.IsDebugEnabled;
public static void RunTool(Geoprocessor geoprocessor, IGPProcess process, ESRI.ArcGIS.esriSystem.ITrackCancel trackCancel, MessageDetails messageDetails)
{
try
{
// Set the overwrite output option to true
geoprocessor.OverwriteOutput = true;
IGeoProcessorEvents geoProcessorEvents = new GPMessageEventHandler(messageDetails);
if (isDebugEnabled)
{
log.Debug("RegisterGeoProcessorEvents");
}
geoprocessor.RegisterGeoProcessorEvents(geoProcessorEvents);
if (isDebugEnabled)
{
log.Debug("Execute the tool");
}
geoprocessor.Execute(process, trackCancel);
if (isDebugEnabled)
{
log.Debug("UnRegisterGeoProcessorEvents");
}
geoprocessor.UnRegisterGeoProcessorEvents(geoProcessorEvents);
}
catch(Exception ex)
{
ExceptionHandler.ThrowException(ex, typeof(Helper));
}
}
Nel costruttore della classe, che riceve gli eventi, passiamo il delegato che si occupa di visualizzare i messaggi ( messageDetails ).
Nel nostro caso il delegato è dichiarato nel seguente modo:
public delegate void MessageDetails(IGPMessage data);
e nella windows form, il metodo di tipo MessageDetails, che visualizza i messaggi è:
public void WriteDetails(IGPMessage message)
{
// Font font = new Font("Tahoma", 8, FontStyle.Regular);
// richTextBox1.SelectionFont = font;
Color color = Color.Black;
if (message.IsError())
{
color = Color.Red;
}
else if (message.IsWarning())
{
color = Color.Green;
}
else if (message.IsAbort())
{
color = Color.DarkMagenta;
}
rtbDetails.SelectionColor = color;
rtbDetails.SelectedText = message.Description;
rtbDetails.SelectionStart = rtbDetails.Text.Length;
rtbDetails.ScrollToCaret();
rtbDetails.AppendText(System.Environment.NewLine);
}
Volevo aprire una parentesi riguardo alla possibilità di utilizzare log4net come logger per la dll.
Impostiamo il file di appender a runtime:
XmlConfigurator.Configure(new System.IO.FileInfo(string.Format("{0}\\logging.config", codeBase)));
IAppender appender = log4net.LogManager.GetRepository().GetAppenders()[0];
FileAppender fileAppender = appender as FileAppender;
fileAppender.File = Path.Combine(codeBase, "GPExtensionLog.txt");
fileAppender.ActivateOptions();
e utilizziamo una classe di handler per le eccezioni:
public static class ExceptionHandler
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static void ThrowException(Exception e, Type source, string message)
{
log.Error("Exception: " + message);
log.Error("{" + source + "} " + e.Message + ", StackTrace: " + e.StackTrace);
throw e;
}
public static void ThrowException(Exception e, Type source)
{
log.Error("{" + source + "} " + e.Message + ", StackTrace: " + e.StackTrace);
throw e;
}
}
per poi utilizzarla:
geoprocessor.UnRegisterGeoProcessorEvents(geoProcessorEvents);
}
catch(Exception ex)
{
ExceptionHandler.ThrowException(ex, typeof(Helper));
}
Scarica qui la soluzione