Home

Dec. 9, 2014, 2 min read

Writing to stdout and stderr from MAXScript

As far as I know there is no builtin way to do this with MAXScript. For example print() or format() only end up in the MAXScript Listener, which can be dumped to a file using openLog(), but still that may not meet the requirements, e.g. when 3ds Max is launched by some other tool that is listening to the standard streams. However we can use .NET for it, as System.Console.WriteLine() does write to stdout and stderr.

And since we can dynamically compile C# code from MAXScript, it is actually easy:

code = "
using System;

class StdOutPrinter {
    static public bool print(string txt) {
        Console.WriteLine(txt);
        return true;
    }
}

class StdErrPrinter {
    static public bool print(string txt) {
        Console.Error.WriteLine(txt);
        return true;
    }
}
"

fn createAssembly code className = (
    provider = dotNetObject "Microsoft.CSharp.CSharpCodeProvider"
    param = dotNetObject "System.CodeDom.Compiler.CompilerParameters"
    param.GenerateInMemory = on
    compiled = provider.CompileAssemblyFromSource param #(code)
    compiled.CompiledAssembly.CreateInstance className
)

stdout = createAssembly code "StdOutPrinter"
stderr = createAssembly code "StdErrPrinter"

-- Testing:
stdout.print "INFO: This is written to standard out!"
stderr.print "ERROR: This is written to standard error!"

Sadly there is nothing to be seen inside 3ds Max itself, but you can test the result by redirecting 3ds Max output streams to files by starting it through a .bat like:

"C:\Program Files\Autodesk\3ds Max 20xx\3dsmax.exe" 1>stdout.txt 2>stderr.txt

Your print statements will end up in the associated text files.