Careers
Webinars

# Plug-in Scripting

## Overview

All of Deadline's plug-ins are completely scripted, which means that it's easy to create your own plug-ins or customize the existing ones (providing you have some experience with the Python scripting language). Because Deadline can use IronPython or Python for .NET to execute scripts, not only can you access all of the Python modules, you can import all of the .NET libraries as well, which means the level of customization is nearly endless.

## General Plug-in Information

There are two types of plug-ins that can be created for Deadline:

• Simple

To create a new plug-in, you start by creating a folder in the Repository's plugins folder and give it the name of your plug-in. For the sake of this document, we will call our new plug-in MyPlugin. All relative script and configuration files for this plug-in are to be placed in this plug-in's folder (some are required and some are optional).

### The dlinit File - Required

The first file is MyPlugin.dlinit, which is the main configuration file for this plug-in. It is a plain text file that defines a few general key=value plug-in properties, which include:

Key Name Description
About A short description of the plug-in.
ConcurrentTasks If the plug-in supports concurrent tasks (True/False). Note that if you change this value, you'll have to restart the Slave applications so that they recognize the change. This is because they cache this information.

It can also define key=value custom settings to be used by the plug-in. A common custom setting is the executable to use to render the job. For this example, our MyPlugin.dlinit file might look like this:

About=My Example Plugin for Deadline
MyPluginRenderExecutable=c:\path\to\my\executable.exe


### The py File - Required

The other required file is MyPlugin.py, which is the main plug-in script file. It defines the main DeadlinePlugin class that contains the necessary functions that Deadline uses to render a job. The template for this script file might look like this:

from Deadline.Plugins import *

######################################################################
## This is the function that Deadline calls to get an instance of the
######################################################################
return MyPlugin()

######################################################################
## This is the main DeadlinePlugin class for MyPlugin.
######################################################################

# TODO: Place code here


The GetDeadlinePlugin() function is important, as it allows Deadline to get an instance of our MyPlugin class (which is extending the abstract DeadlinePlugin class). If this function isn't defined, Deadline will report an error when it tries to render the job. Notice that we're importing the Deadline.Plugins namespace so that we can access the DeadlinePlugin class. In fact, because we're using IronPython, you can import any .NET namespace, like System, System.IO, etc:

from System import *
from System.Diagnostics import *
from System.IO import *


The MyPlugin class will need to override certain functions based on the type of plug-in it is (simple or advanced). One function that all plug-ins should override is the InitializeProcess function. This function defines some general plug-in settings:

    ## Called by Deadline to initialize the process.
def InitializeProcess( self ):
# Set the plugin specific settings.
self.SingleFramesOnly = False
self.PluginType = PluginType.Simple


Remember that by default, Deadline will execute scripts using the IronPython engine. If you want to use Python for .NET, the first line of your MyPlugin.py must look like the following. This tells Deadline that the plugin is a Python.NET plugin:

#Python.NET


In addition, the way you override functions is slightly different for Python.NET plugins. For example, in an IronPython plugin, you just need to define the function in the plugin class (see the code for InitializeProcess() above). In Python.NET plugins, you also need to add a corresponding event handler in the __init__ constructor for the plugin class. For example:

    def __init__( self ):
# Set up the event handlers because this is a Python.NET plugin
self.InitializeProcessEvent += self.InitializeProcess

## Called by Deadline to initialize the process.
def InitializeProcess( self ):
# Set the plugin specific settings.
self.SingleFramesOnly = False
self.PluginType = PluginType.Simple


The general plug-in properties that can be defined are:

Property Description
PluginType The type of plug-in this is (PluginType.Simple/PluginType.Advanced).
SingleFramesOnly If this plug-in can only render one frame at a time (True/False).

There are many other functions that can be overridden, but most of these are dependent on the type of plug-in we're creating, and will be covered in their respective sections below. Here is the list of functions you can override for both types of plug-in:

Function Description
void MonitoredManagedProcessExit( string name ) Optional - Allows you to handle the situation where a Monitored Managed Process exits unexpectedly. If not overridden, the job will simply fail when this happens.
void MonitoredProgramExit( string name ) Optional - Allows you to handle the situation where a Monitored Program exits unexpectedly. If not overridden, the job will simply fail when this happens.
void InitializeProcess() Required - Defines some plug-in settings and any popup or stdout handlers that we need.
bool IsSingleFramesOnly() Optional - Allows you to override SingleFramesOnly setting in the InitializeProcess() function, using code to determine if the setting should be True or False. If not overridden, the SingleFramesOnly setting is used.

### The param File - Optional

The MyPlugin.param is used to declare properties which are used by the Plugin Configuration dialog in the Monitor to dynamically generate a UI for modifying custom settings as they appear in the MyPlugin.dlinit file. After you've created this file, open the Monitor and enter Super User mode. Then select Tools -> Configure Plugins and look for your plug-in in the list on the left.

The file might look something like:

[MyPluginRenderExecutable]
Type=filename
Label=My Plugin Render Executable
Default=c:\path\to\my\executable.exe
Description=The path to the executable file used for rendering.


You'll notice that the property name between the square brackets matches the MyPluginRenderExecutable custom setting we defined in our MyPlugin.dlinit file. This means that this control will change the MyPluginRenderExecutable setting. The available key=value pairs for the properties defined here are:

Key Name Description
Type The type of control (Boolean/Enum/Filename/FilenameSave/Float/Folder/Integer/Label/MultiFilename/String).
Category The category the control should go under.
CategoryIndex This determines the control's order under its category. This does the same thing as Index.
CategoryOrder This determines the category's order among other categories. If more than one CategoryOrder is defined for the same category, the lowest value is used.
Default The default value to be used if this property is not defined in the dlinit file. This does the same thing as DefaultValue.
DefaultValue The default value to be used if this property is not defined in the dlinit file. This does the same thing as Default.
Description A short description of the property the control is for (displayed as a tooltip in the UI).
DisableIfBlank If True, a control will not be shown if this property is not defined in the dinit file (True/False). This does the same thing as IgnoreIfBlank.
IgnoreIfBlank If True, a control will not be shown if this property is not defined in the dinit file (True/False). This does the same thing as DisableIfBlank.
Index This determines the control's order under its category. This does the same thing as CategoryIndex.
Label The control label.
Required If True, a control will be shown for this property even if it's not defined in the dlinit file (True/False).

There are also key/value pairs for specific controls:

Key Name Description
DecimalPlaces The number of decimal places for the Float controls.
Filter The filter string for the Filename, FilenameSave, or MultiFilename controls.
Increment The value to increment the Integer or Float controls by.
Items The semicolon separated list of items for the Enum control. This does the same thing as Values.
Maximum The maximum value for the Integer or Float controls.
Minimum The minimum value for the Integer or Float controls.
Values The semicolon separated list of items for the Enum control. This does the same thing as Items.

### The options File - Optional

The MyPlugin.options file declares properties which are used by the Job Properties dialog in the Monitor to dynamically generate a UI for modifying plug-in specific options as they appear in the plug-in info file that is submitted with the job. After you've created this file, you can right-click on a job in the Monitor that uses this plug-in and select Modify Properties. You should then see a MyPlugin tab page which you can select to view these properties.

Often, these plug-in specific options are used to build up the arguments to be passed to the rendering application. Let's assume that our render executable takes a "-verbose" argument that accepts a boolean parameter, and that the plug-in info file submitted with the job contains the following:

Verbose=True


Now we would like to be able to change this value from the Job Properties dialog in the Monitor, so our MyPlugin.options file might look like this:

[Verbose]
Type=boolean
Label=Verbose Logging
Description=If verbose logging is enabled.
Required=true
DisableIfBlank=false
DefaultValue=True


You'll notice that the property name between the square brackets matches the Verbose setting in our plug-in info file. This means that this control will change the Verbose setting. The available key=value pairs for the properties defined here are the same as those defined for the param file above.

### The ico File - Optional

You can add a MyPlugin.ico file, which is an 16x16 icon file for identifying the plug-in. In most cases, this should be the plug-in application's logo. This icon will appear next to the job in the Monitor, and will also identify the plug-in in the Plugin Configuration dialog. After all of your files have been created, your plug-in folder should look something like this:

### The PreLoad.py File - Optional

The only requirement for the PreLoad.py script is that you define a __main__ function. This is the function called by Deadline when it executes the script.

def __main__( *args ):
...
''do something''
...


Here is an example PreLoad.py script that sets a couple of environment variables:

from System import *

def __main__( *args ):
LogInfo( "Setting EnvVar1 to True" )
Environment.SetEnvironmentVariable( "EnvVar1", "True" )

LogInfo( "Setting EnvVar2 to False" )
Environment.SetEnvironmentVariable( "EnvVar2", "False" )


## Simple Plug-ins

A Deadline job goes through three stages:

• StartJob: A job enters this stage when it is first picked up by a slave.
• RenderTasks: A job can enter this stage many times (once for each task a slave dequeues while it has the current job loaded).
• EndJob: A job enters this stage when a slave is unloading the job.

Simple plug-ins only covers the RenderTasks stage, and are pretty straight forward. They are commonly used to render with applications that support simple command line rendering (running a command line executable and waiting for it to complete). For example, After Effects has a command line renderer called aerender.exe, which can be executed by Deadline to render specific frames of an After Effects project file. By default, Deadline always assumes you are creating a simple plug-in, but you can explicitly tell Deadline this by overriding the InitializeProcess() function (as explained above) and adding this line:

self.PluginType = PluginType.Simple


Within the InitializeProcess() function, you can also define settings specific to the simple plug-in, as well as any popup or stdout handlers that we need.

    ## Called by Deadline to initialize the process.
def InitializeProcess( self ):
# Set the plugin specific settings.
self.SingleFramesOnly = False
self.PluginType = PluginType.Simple

# Set the process specific settings.
self.ProcessPriority = ProcessPriorityClass.BelowNormal
self.UseProcessTree = True
self.StdoutHandling = True
self.PopupHandling = True

# Set the stdout handlers.

# Set the popup ignorers.

# Set the popup handlers.


At this point, if you're creating a Python.NET plugin, your __init__ and InitializeProcess() functions will now look like this. Notice that the stdout handlers are set up a bit differently for Python.NET plugins. This is covered a bit later.

    def __init__( self ):
# Set up the event handlers because this is a Python.NET plugin
self.InitializeProcessEvent += self.InitializeProcess

## Called by Deadline to initialize the process.
def InitializeProcess( self ):
# Set the plugin specific settings.
self.SingleFramesOnly = False
self.PluginType = PluginType.Simple

# Set the process specific settings.
self.ProcessPriority = ProcessPriorityClass.BelowNormal
self.UseProcessTree = True
self.StdoutHandling = True
self.PopupHandling = True

# Set the stdout handlers.

# Set the popup ignorers.

# Set the popup handlers.


The plugin properties that can be defined are:

Property Description
dictionary EnvironmentVariables Gets or sets a dictionary containing extra environment variables that will be added to the created process
bool HideDosWindow If the application uses a console window, you can use this property to show it (it's hidden by default).
bool PopupHandling Needs to be True if using Popup handlers.
ProcessPriorityClass ProcessPriority The process priority of the executable that is launched. Note that ProcessPriorityClass is a .NET enumeration. This property is currently ignored on Linux and OSX.
bool StdoutHandling Needs to be True if using Stdout handlers.
bool UseProcessTree This should almost always be True. If Enabled, Deadline will control and monitor any child processes launched by the main executable.

The AddStdoutHandler() function takes two arguments: a regular expression string, and a pointer to a handler function that is defined in the plug-in class. This handler function will be called when the regular expression string matches a line of stdout from the rendering application. For example:

self.AddStdoutHandler( "WARNING:.*", self.HandleStdoutWarning )


If you are writing a Python.NET plugin, you must use the AddStdoutHandlerEvent() function instead. It only takes one argument, which is the regular expression string. It returns a RegexHandlerEvent object with a HandleEvent property that you can assign the handler function to. For example:

warningEventHandler = self.AddStdoutHandlerEvent( "WARNING:.*" )
warningEventHandler.HandleEvent += self.HandleStdoutWarning
errorEventHandler.HandleEvent += self.HandleStdoutError


There is also a shorthand way of doing this:

warningEventHandler = self.AddStdoutHandlerEvent( "WARNING:.*" ).HandleEvent += self.HandleStdoutWarning
errorEventHandler = self.AddStdoutHandlerEvent( "ERROR:(.*)" ).HandleEvent += self.HandleStdoutError


Within these handler functions, the GetRegexMatch( int index ) function can be used to get a specific match from the regular expression. The index passed to GetRegexMatch() is the index of the matches that were found. 0 returns the entire matched string, and 1, 2, etc returns the matched substrings (matches that are surrounded by round brackets). If there isn't a corresponding substring, you'll get an error (note that 0 is always a valid index). For example:

In HandleStdoutWarning(), 0 is the only valid index because there is no substring in round brackets in the regular expression. In HandleStdoutError(), 0 and 1 are valid. 0 will return the entire matched string, whereas 1 will return the substring in the round brackets.

You can also use the SuppressThisLine() function to suppress the current line of stdout, or you can use the GetPreviousStdoutLine() function to get the previous line of stdout (if there is any). For the example above, the following functions would have to be defined:

    def HandleStdoutWarning( self ):
LogWarning( self.GetRegexMatch(0) )

def HandleStdoutError( self ):
FailRender( "Detected an error: " + self.GetRegexMatch(1) )


The AddPopupIgnorer() function takes one argument: a regular expression string. If a popup is displayed with a title that matches the given regular expression, the popup is simply ignored. Popup ignorers should only be used if the popup doesn't halt the rendering because it is waiting for a button to be pressed. In the case where a button needs to be pressed to continue, popup handlers should be used instead. The AddPopupHandler() function takes two arguments, a regular expression string, and the button(s) to press (multiple buttons can be separated with semicolons).

There are many other functions you can override, but the only required one is RenderExecutable(). As the name indicates, this function should return the full path to the executable to be used for rendering. Continuing our example, this path is specified in the MyPlugin.dlinit file, and we can access it using the global GetConfigEntry() function (all global functions are covered below in the plug-in script function reference):

def RenderExecutable( self ):
return GetConfigEntry( "MyPluginRenderExecutable" )


Another important (but optional) function to override is the RenderArgument() function. This function should return the arguments you want to pass to the render executable. If this function is not overridden, then no arguments will be passed to the executable. Some of these arguments may be hardcoded, some may be pulled from the job properties (like the data/scene file name, start and end frame), and others may be pulled from the plug-in info file that was submitted with the job using the global GetPluginInfoEntry() function:

def RenderArgument( self ):
arguments = " -continueOnError -verbose " + GetPluginInfoEntry( "Verbose" )
arguments += " -start " + str(GetStartFrame()) + " -end " + str(GetEndFrame())
arguments += " -scene \"" + GetDataFilename() + "\""
return arguments


At this point, if you're creating a Python.NET plugin, your __init__ function will now look like this:

    def __init__( self ):
# Set up the event handlers because this is a Python.NET plugin
self.InitializeProcessEvent += self.InitializeProcess
self.RenderExecutableEvent += self.RenderExecutable
self.RenderArgumentEvent += self.RenderArgument


The full list of simple plug-in functions you can override is as follows:

Function Description
void CheckExitCode( int exitCode ) Optional - Allows you to explicitly check the return code of the executable and handle it as necessary. If not overridden, the job will succeed on a return code of 0, and fail on any other return code.
void PostRenderTasks() Optional - Allows you to perform some tasks after the render executable has exited. This can be used to clean up temporary files, perform operations on the rendered output, etc.
void PreRenderTasks() Optional - Allows you to perform some tasks before the render executable is launched. This can be used to set environment variables, copy over some dependencies, etc. Within this function, you can use the SetUpdateTimeout( int seconds ) function to set a timeout. If no stdout is received from the application within this amount of time, the TimeoutTasks() function is called (see below).
string RenderArgument() Optional - Returns the arguments you want to pass to the render executable. If not overridden, then no arguments are passed to the render executable.
string RenderExecutable() Required - Returns the full path to the executable to be used for rendering.
string StartupDirectory() Optional - Returns the working folder that the render executable should launch in. If not overridden, then the folder that the executable resides in will be used.
void TimeoutTasks() Optional - Allows you to perform some action when an update timeout occurs. This task timeout is set up using the global SetUpdateTimeout() function. If not overridden, the job will simply fail if an update timeout occurs.

The best place to find examples of simple plug-ins is to look at some of the plug-ins that are shipped with Deadline. These range from the very basic (Blender), to the more complex (MayaCmd).

Advanced plug-ins are a little more complicated, as they control all three job stages mentioned above. They are commonly used to render with applications that support some sort of slave/server mode that Deadline can interact with. Usually, this requires the application to be started during the StartJob phase, fed commands during the RenderTasks stage(s), and finally shut down during the EndJob stage. For example, the 3ds Max plug-in starts up 3dsmax in slave mode and forces it to load our Lightning plug-in. The Lightning plug-in listens for commands from Deadline and executes them as necessary. After rendering is complete, 3ds Max is shut down.

To tell Deadline that you're creating an advanced plug-in, add the following line to the InitializeProcess() function:

self.PluginType = PluginType.Advanced


There are a few other functions you can override, but the only required one is RenderTasks(). This contains the code to be executed for each task that a slave dequeues. This could involve launching applications, communicating with already running applications, or simply running a script to automate a particular task (like backup a group of files).

def RenderTasks( self ):

# Do stuff...


At this point, if you're creating a Python.NET plugin, your __init__ function will now look like this:

    def __init__( self ):
# Set up the event handlers because this is a Python.NET plugin


The full list of advanced plug-in functions you can override is as follows:

Function Description
void EndJob() Optional - Contains the code to be executed when a slave finishes with a job. This can include shutting down the application or cleaning up some temporary files. If not overridden, than nothing is done during the EndJob phase.
void RenderTasks() Required - Contains the code to be executed for each task that a slave dequeues.
void StartJob() Optional - Contains the code to be executed when a slave first picks up a job for rendering. This can include starting up the application or setting up the environment for rendering. If not overridden, than nothing is done during the StartJob phase.

As mentioned above, a common use for advanced plug-ins is to start up some sort of server application during the StartJob stage and feed it render commands during the RenderTasks stage(s). The benefit to this is that you only have to deal with the overhead of loading the application for the first task the slave dequeues for the job. This is a big deal if the scene file you're rendering is large, and needs to load a lot of plug-ins and external references. More often than not, this involves launching and monitoring a Managed Process. In your python file, you can create another class that extends the abstract ManagedProcess class. To continue our example, we'll call this class MyPluginProcess:

class MyPluginProcess (ManagedProcess):

# TODO: Place code here


This managed process class will define the render executable, command line arguments, etc for the process we will be monitoring. If this sounds familiar, that's because we do the same thing for a simple plug-in. In fact, the abstract DeadlinePlugin class we talked about near the beginning is just a specialized ManagedProcess class. So you would define your RenderExecutable(), RenderArgument(), etc, functions here like you would for a simple plug-in. After you've created your managed process class, you can create an instance of it in the StartJob() function and use the global StartMonitoredManagedProcess() function to launch the process.

def StartJob( self ):
# Do some initialization...

myProcess = MyPluginProcess()
StartMonitoredManagedProcess( "My Process", myProcess )


Then in the EndJob() function, you can use the global ShutdownMonitoredManagedProcess() function to shut down the process:

def EndJob( self ):
# Do some cleanup...

ShutdownMonitoredManagedProcess( "My Process" )


At this point, if you're creating a Python.NET plugin, your __init__ function will now look like this:

    def __init__( self ):
# Set up the event handlers because this is a Python.NET plugin
self.StartJobEvent += self.StartJob
self.EndJobEvent += self.EndJob


There are other global managed process functions you can use to control and monitor the process, which are explained in the scripting reference below. Because the advanced plug-ins are much more involved than the simple plug-ins, we suggest you take a look at the following plug-ins that are shipped with Deadline for examples: 3dsmax, Combustion, Fusion, Lightwave, MayaBatch, Modo, Rhino, VNS, and XSIBatch.

## Global Function Reference

All these functions can be called from your plug-in python script file.

### Job Functions

Function Description
Job GetJob() Returns the current job object.
string GetJobInfoEntry( string Key ) Returns the value for the given Key from the job's submission info file. Throws an error if the Key does not exist.
string GetJobInfoEntryElement( int Index, string Key ) Returns the value from job's submission info file for the specified Key at the specified Index. Causes an error if the Index is out of range, or the Key does not exist. This is only valid if the Key stores its values as an array.
int GetJobInfoEntryElementCount( string Key ) Returns the number of values in the job's submission info file for the specified Key. This is only valid if the Key stores its values as an array.

### Plugin Configuration Functions

Function Description
bool GetBooleanConfigEntry( string Key ) Returns the value for the given Key from the plug-in dlinit file. Throws an error if the Key does not exist.
bool GetBooleanConfigEntryWithDefault( string Key, bool Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
string GetConfigEntry( string Key ) Returns the value for the given Key from the plug-in dlinit file. Throws an error if the Key does not exist.
string GetConfigEntryWithDefault( string Key, string Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
float GetFloatConfigEntry( string Key ) Returns the value for the given Key from the plug-in dlinit file. Throws an error if the Key does not exist.
float GetFloatConfigEntryWithDefault( string Key, float Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
int GetIntegerConfigEntry( string Key ) Returns the value for the given Key from the plug-in dlinit file. Throws an error if the Key does not exist.
int GetIntegerConfigEntryWithDefault( string Key, int Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
long GetLongConfigEntry( string Key ) Returns the value for the given Key from the plug-in dlinit file. Throws an error if the Key does not exist.
long GetLongConfigEntryWithDefault( string Key, int Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.

### Plugin Info File Functions

Function Description
bool GetBooleanPluginInfoEntry( string Key ) Returns the value for the given Key from the job's plug-in info file. Throws an error if the Key does not exist.
bool GetBooleanPluginInfoEntryWithDefault( string Key, bool Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
float GetFloatPluginInfoEntry( string Key ) Returns the value for the given Key from the job's plug-in info file. Throws an error if the Key does not exist.
float GetFloatPluginInfoEntryWithDefault( string Key, float Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
int GetIntegerPluginInfoEntry( string Key ) Returns the value for the given Key from the job's plug-in info file. Throws an error if the Key does not exist.
int GetIntegerPluginInfoEntryWithDefault( string Key, int Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
long GetLongPluginInfoEntry( string Key ) Returns the value for the given Key from the job's plug-in info file. Throws an error if the Key does not exist.
long GetLongPluginInfoEntryWithDefault( string Key, int Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.
string GetPluginInfoEntry( string Key ) Returns the value for the given Key from the job's plug-in info file. Throws an error if the Key does not exist.
string GetPluginInfoEntryWithDefault( string Key, string Default ) Same as above but with a Default value to be returned if the Key does not exist. Useful for backwards-compatibility, because it will not throw an error if the Key does not exist.

### Rendering Information Functions

Function Description
string[] GetAuxiliaryFilenames() Returns the list of files that were submitted with the job.
string GetDataFilename() Returns the path of the scene file that was submitted with the job.
int GetEndFrame() Returns the last frame of the task currently being rendered.
string GetJobsDataDirectory() Returns the local jobs data directory path of the current slave.
string GetPluginDirectory() Returns the local plug-in directory path of the current slave.
string GetPluginInfoFilename() Returns the path of the plugin-info file that was submitted with the job.
string GetSlaveDirectory() Returns the root local path of the current slave, where things like job and plugin files get copied to.
int GetStartFrame() Returns the first frame of the task currently being rendered.

### Logging and Control Funtions

Function Description
void ExitWithSuccess() Exits the render immediately, reporting success.
void FailRender( string Message ) Fails the render, returning the given message as the error.
bool IsCanceled() Returns true if the current render has been canceled.
void LogInfo( string Message ) Prints an info message to the log.
void LogWarning( string Message ) Prints a warning message to the log.
void SetProgress( float Percentage ) Sets the progress of the render.
void SetStatusMessage( string Message ) Sets the render status message.

### General Process Functions

Function Description
void ClearProcessEnvironmentVariables() Clears the extra environment variables that will be passed on to any process launched by the plugin for the duration of the current job.
string GetProcessEnvironmentVariable( string key ) Gets an extra environment variable that will be passed on to any process launched by the plugin for the duration of the current job.
int RunProcess( string Executable, string Arguments, string StartupDir, int TimeoutMilliseconds ) Launches a program and waits for the specified TimeoutMilliseconds for it to complete (specify -1 for no timeout). The program's stdout is redirected to the slave. Returns the process' return code (1 is returned for a timeout).
void SetProcessEnvironmentVariable( string key, string value ) Sets an extra environment variable that will be passed on to any process launched by the plugin for the duration of the current job. The Slave's environment will be left unchanged. Note that this does not work if used in the PreRenderTasks() function for a simple plugin, because when this function is called, the environment has already been set.

### Managed Process Functions

Function Description
string CheckForMonitoredManagedProcessPopups( string Name ) Checks for any popups shown by the managed process. If a popup is found, the dump of the popup is returned, otherwise an empty string is returned.
void DetachMonitoredManagedProcess( string Name ) This allows the managed process to continue running after the slave has finished the current job.
void FlushMonitoredManagedProcessStdout( string Name ) Flushes the managed process's stdout buffer to the slave.
int GetMonitoredManagedProcessExitCode( string Name ) Gets the exit code for the managed process. If the process hasn't exited yet, an error will occur.
int[] GetMonitoredManagedProcessIDs( string Name ) Gets the list of the parent process and any child process PIDs for the managed process.
bool MonitoredManagedProcessIsRunning( string Name ) Returns True if the managed process is still running.
void RedirectStdOutToFileForMonitoredManagedProcess( string Name, string Filename ) Writes the contents of the given Filename to the given managed process's stdin.
void RunManagedProcess( ManagedProcess process ) Runs a managed process, and returns when the process has exited.
void SetMonitoredManagedProcessExitCheckingFlag( string Name, bool Value ) Sets the managed process's exit checking flag to the given Value.
void ShutdownMonitoredManagedProcess( string Name ) Stops the managed process by sending a close message. If that fails, the process is terminated.
void StartMonitoredManagedProcess( string Name, ManagedProcess process ) Starts a managed process, and tracks it with the given Name as its id. Use FlushMonitoredManagedProcessStdout() to redirect the program's stdout to the slave.
void VerifyMonitoredManagedProcess( string Name ) Throws an error if the given managed process is no longer running.
bool WaitForMonitoredManagedProcessToExit( string Name, int timeoutMilliseconds ) Waits for the managed process to exit, and returns True if it does so in the given amount of time. Specify -1 for no timeout.
void WriteStdinToMonitoredManagedProcess( string Name, string Stdin ) Writes the given Stdin string to the given managed process's stdin.

### Monitored Program Functions

Function Description
void DetachMonitoredProgram( string Name ) This allows the program to continue running after the slave has finished the current job.
bool MonitoredProgramIsRunning( string Name ) Returns True if the specified managed program is running, False otherwise.
void SetMonitoredProgramExitCheckingFlag( string Name, bool Value ) Sets the program's exit checking flag to the given Value.
void ShutdownMonitoredProgram( string Name ) Stops the program by sending a windows close message. If that fails, the process is terminated.
void StartMonitoredProgram( string Name, string Executable, string Arguments, string StartupDir ) Starts a program, and tracks it with the given Name as its id. The program's stdout is not redirected to the slave.
void VerifyMonitoredProgram() Throws an error if the managed program is no longer running.
bool WaitForMonitoredProgramToExit( string Name, int TimeoutSeconds ) Waits for the specified managed program to exit. Returns True if the program exited before the specified TimeoutSeconds,, False otherwise.

### File/Path/Directory Functions

</tr>
Function Description
string CheckPathMapping( string Path ) Maps the given path to a different path if necessary. If no path mapping is required, the original path is returned. Path Mappings can be set up in the Repository Options in the Monitor.
string CheckPathMappingInFile( string InFileName, string OutFileName ) Checks each line of the given input file to see if a path mapping is required. The new file with any paths that may have been swapped is saved to the output file defined. Path Mappings can be set up in the Repository Options in the Monitor.
string CheckPathMappingInFileAndReplaceSeparator( string InFileName, string OutFileName, string SeparatorToReplace, string NewSeparator ) This is identical to CheckPathMappingInFile above, except that lines that are swapped out will replace the given SeparatorToReplace with the given NewSeparator.
void CreateCommandFile( string FilePath, string Command ) Writes the Command to the given file.
string CreateTempDirectory( string Tag ) Uses the Tag specified to create a unique output directory in local jobs data folder and returns the path.
bool PathMappingRequired( string Path ) Checks if the given Path needs to be mapped to a different path. Path Mappings can be set up in the Repository Options in the Monitor.
void VerifyAndMoveDirectory( string SrcFolderPath, string DestFolderPath, bool failIfEmpty, int fileSize ) Same as above, but it moves an entire folder and its contents to DestFolderPath after it has verified the file(s) within the folder.
void VerifyAndMoveFile( string SrcFilePath, string DestFilePath, int fileSize ) Same as above, but it moves the frame to DestFilePath after it has verified the file.
void VerifyFile( string FilePath, int fileSize ) Verifies that a given file exists and has size greater than the given file size. Throws an error otherwise.
string WaitForCommandFile( string FilePath, int DeleteFile, int TimeoutMilliseconds ) Waits for the specified file to appear, and returns the command that was written to that file. Specify 1 for DeleteFile to delete the command file afterwards. Returns "" if a timeout occurs (specify -1 as the timeout to disable it).