For UiPath
version 18.2.3
I successfully created a new logging activity. The idea is, while logging everything in Orchestrator
, the new activity would in addition log in a file as well. Coming up our organization will upgrade to UiPath 2019.4.3
and my activity did not work, so I needed to upgrade the UiPath references to current dlls (e.g. UiPath.Core.Activities.dll
to UiPath.System.Activities.dll
). Doing that gives me a compilable code, but the activity causes a null-pointer exception
during execution. Why?
This is my code:
using System;
using System.Activities;
using System.Activities.Presentation.Metadata;
using System.ComponentModel;
using System.IO;
using System.Text;
using UiPath.Core.Activities;
namespace CustomCode.Log
{
/// <summary>
/// Designer attribute gives a look & feel like UiPaths own LogMessage activity
/// </summary>
[Designer(typeof(UiPath.Core.Activities.Design.LogDesigner))]
public class LogMessage : CodeActivity, IRegisterMetadata
{
[Category("Input")]
public CurentLogLevel Level { get; set; }
[Category("Input")]
public InArgument<System.String> Message { get; set; }
[Category("Input")]
public InArgument<System.String> LogFilePath { get; set; }
/// <summary>
/// UiPath Log Message object reference
/// </summary>
private UiPath.Core.Activities.LogMessage _LogMessage { get; set; }
/// <summary>
/// Constructor
/// </summary>
public LogMessage()
{
DisplayName = "Extended Log Message";
Level = CurentLogLevel.Trace; // default setting
}
/// <summary>
/// declare dummy register metadata class to force UiPath to load this assembly
/// </summary>
public void Register()
{
// intentionally empty
}
/// <summary>
/// First log as if done by native UiPath then log to the file specified
/// </summary>
/// <param name="context"></param>
protected override void Execute(CodeActivityContext context)
{
// first do the usual UiPath logging...
string message = Message.Get(context);
//bool isNew = false;
#region log as UiPath standard
// it is necessary to create new objects every time.
// reassigning property values causes errors when logging is frequent...
_LogMessage = new UiPath.Core.Activities.LogMessage
{
Level = this.Level,
Message = new InArgument<string>(message),
};
// do UiPath log
try
{
WorkflowInvoker.Invoke(_LogMessage); // NULL POINTER EXCEPTION HERE
}
catch (Exception ex)
{
throw new Exception("Internal UiPath Invoke Exception ", ex);
}
#endregion
string logFilePath = LogFilePath.Get(context);
// log to file if path is specified...
if (logFilePath != null)
{
LogToFile(logFilePath, message, Level.ToString());
}
}
/// <summary>
/// Method to write a line in the log file
/// </summary>
/// <param name="filename">the file to which to log</param>
/// <param name="message">the log message</param>
/// <param name="level">the log level</param>
private void LogToFile(string filename, string message, string level)
{
StringBuilder LogLine = new StringBuilder(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
LogLine.Append("\t");
LogLine.Append(level);
LogLine.Append("\t");
LogLine.Append("\t - ");
LogLine.Append(message);
LogLine.Append(Environment.NewLine);
try
{
// append the log line
File.AppendAllText(filename, LogLine.ToString());
}
catch (Exception ex)
{
// try to log the exception in UiPath
_LogMessage.Message = new InArgument<string>(ex.Message + Environment.NewLine + ex.StackTrace);
throw new Exception("Internal append to log file exception", ex);
}
}
}
}