Execute Batch on Server

Sometimes it’s necessary to execute a batch file on the server. You may use some .NET code to achieve this. First create a new class e.g. called ExecuteBatchOnServer. Add a static method that is executed on the server. Be aware that the file path is local on the server.

public static server void executeBatch(FilePath _filePath)
{   
    #File
    InteropPermission interop;
    FileIOPermission fileIo;
    Set permissionSet = new Set(Types::Class);
    System.Diagnostics.Process process;
    System.Diagnostics.ProcessStartInfo startInfo;
    str filePath = @"C:\Batch\batchfile.bat";
    ;
   
    interop = new InteropPermission(InteropKind::ClrInterop);
    fileIo = new FileIOPermission(filePath,#io_read);
    permissionSet.add(interop);
    permissionSet.add(fileIo);
    CodeAccessPermission::assertMultiple(permissionSet);
   
    startInfo = new System.Diagnostics.ProcessStartInfo();
    startInfo.set_FileName(filePath);
   
    process = new System.Diagnostics.Process();
    process.set_StartInfo(startInfo);
    process.Start();
    process.WaitForExit();

    CodeAccessPermission::revertAssert();
}

Create a main method to make the class executable

public static void main(Args _args)
{
   DialogButton result;
   ;
   result = Box::yesNo("Excute Batch?",DialogButton::No);
   if(result == DialogButton::Yes)
      ExecuteBatchOnServer::executeBatch();
}

Add Exception Handling and Output Redirection

Typically its useful to see the standard output, error and exception text. Therefore its necessary to redirect the Standard* Output and add a try/catch block

public static server void executeBatch()
{
    #File
    InteropPermission interop;
    FileIOPermission fileIo;
    Set permissionSet = new Set(Types::Class);
    System.Diagnostics.Process process;
    System.Diagnostics.ProcessStartInfo startInfo;
    str filePath = @"C:\Batch\batch.bat";
   
    System.IO.StreamReader stdOut;
    System.IO.StreamReader stdErr;
    str txtOut;
    str txtErr;
    str txtExc;
    ;

    interop = new InteropPermission(InteropKind::ClrInterop);
    fileIo = new FileIOPermission(filePath,#io_read);
    permissionSet.add(interop);
    permissionSet.add(fileIo);
    CodeAccessPermission::assertMultiple(permissionSet);

    try
    {
        startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.set_FileName(filePath);
        startInfo.set_UseShellExecute(false);
        startInfo.set_RedirectStandardOutput(true);
        startInfo.set_RedirectStandardError(true);

        process = new System.Diagnostics.Process();
        process.set_StartInfo(startInfo);
        process.Start();
        stdOut = process.get_StandardOutput();
        txtOut = stdOut.ReadToEnd();
        stdErr = process.get_StandardError();
        stdErr.ReadToEnd();
        process.WaitForExit();
    }
    catch(Exception::CLRError)
    {
        txtExc = ClrInterop::getLastException().toString();
    }

    if(txtOut)  info(txtOut);
    if(txtErr)  error(txtErr);
    if(txtExc)  error(txtExc);

    CodeAccessPermission::revertAssert();
}

About erpcoder
Azure Cloud Architect and Dynamics 365 enthusiast working in Research & Development for InsideAx

Leave a comment