typical/working command line inputs for MGCB?

Hi guys,

I don’t really understand how to start MGCB.exe properly.
What I’ve tried so far is something along the lines of

pProcess.StartInfo.Arguments =             "/outputDir:bin " +
                                           "/importer:TextureImporter " +
                                           "/processor:TextureProcessor " +
                                           "/processorParam:ColorKeyEnabled = false " +
                                           "/build:tex.png ";

to compile a texture.

However, MGCB throws me a
“BuilderBuilds optimized game content for MonoGame projects.Too many arguments” exception. What? These arguments are not even close to enough.

EDIT: I guess I need to create a seperate mgcb file to reference here, yes? That can’t be right

EDIT2: It works if i just call build:tex.png, but otherwise no.

The whole exception

MonoGame Content BuilderBuilds optimized game content for MonoGame projects.Too many argumentsUsage: MGCB Options: /launchdebugger Wait for debugger to attach before building content. /quiet Only output content build errors. /outputDir: The directory where all content is written. /intermediateDir: The directory where all intermediate files are written. /rebuild Forces a full rebuild of all content. /clean Delete all previously built content and intermediate files. /incremental Skip cleaning files not included in the current build. /reference: Adds an assembly reference for resolving content importers, processors, and writers. /platform: Set the target platform for this build. Defaults to Windows desktop DirectX. /profile: Set the target graphics profile for this build. Defaults to HiDef. /config: The optional build config string from the build system. /importer: Defines the class name of the content importer for reading source content. /compress Compress the XNB files for smaller file sizes. /@: Read a text response file with additional command line options and switches. /workingDir: The working directory where all source content is located. /processor: Defines the class name of the content processor for processing imported content. /processorParam:<name=value> Defines a parameter name and value to set on a content processor. /build: Build the content source file using the previously set switches and options. /copy: Copy the content source file verbatim to the output directory.

Lose the spaces in the processorParam, these arguments are split by spaces

no same problem. EDIT: I missed one, you were right.

But now i got a new one. I settled with making a text file to read out. runtimepipeline.txt. Then i added some different #if options inside the textfile. It worked. Then I added a /define:Texture=Yes in front. It worked the way it was supposed to (save in a different folder).

It worked, then i changed something else in a whole different class and renamed the mgcb file and voila

pProcess.StartInfo.Arguments = “/define:Texture=Yes /@:Content/mgcb/runtimepipeline.txt /build:tex.png”;

Which throws me this error

MonoGame Content BuilderBuilds optimized game content for MonoGame projects.Unknown option 'define’Usage: MGCB Options: /launchdebugger Wait for debugger to attach before building content. /quiet Only output content build errors. /outputDir: The directory where all content is written. /intermediateDir: The directory where all intermediate files are written. /rebuild Forces a full rebuild of all content. /clean Delete all previously built content and intermediate files. /incremental Skip cleaning files not included in the current build. /reference: Adds an assembly reference for resolving content importers, processors, and writers. /platform:

Really? Unknown option ‘define’. It was known to you 20 seconds ago. Oh well.

What’s really interesting now is this:
It will apply Texture=Yes if I don’t have a define in front. This can’t be intended, right?

My runtimepipeline.txt looks like this

$if Texture=No
/outputDir:Content/Runtime/Textures
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
$endif

$if Texture=Yes
/outputDir:Content/Runtime/Textures2
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
$endif

It seems like this was actually not implemented :confused:

I’ll try and get that fixed when I find the time.

@kosmonautgames FYI https://github.com/MonoGame/MonoGame/issues/5435

amazing. So define is actually unknown. Now the question for me remains why it didn’t throw an exception for some time. Strange, i must have overseen something or didn’t properly rebuild the solution.

Anyways thanks. It works now.

You should be able to use $set inside the response file though if that’s an acceptable alternative (but that’s harder to do through code, hence my suggestion on GitHub :slight_smile: ).

it’s not, since I want one response file for all different cases, and just set a value based on input.

I geuss i have to make a couple of response files.

Speaking of MGCB, can I load from a general directory aka C:/…/ etc? I haven’t seen a reference about that. If relative, can I go backwards? aka ./././myfile etc?

Maybe you guys know that, otherwise I’ll try to check the source later

I believe absolute and relative paths work fine.

build:test.png works in the current directory,

build:content/test.png works.

build:C:/test/test.png doesn’t work.

So how do I go about absolute file paths? No info on that in the mgcb documentation page

I’ll check the parser

The : seems to be a separator which makes C:/ a problem, I’ll check further

It may just be doing something like Path.Combine(currentDir, buildPath). In any case, they should be fixed to work properly as expected.

I remember now it was 2MGFX that I was using absolute paths with, which prompted a PR to fix the parameter prefixes on non-Windows systems because absolute paths on non-Windows systems start with the same character as parameters on Windows.

I am a bit confused

I can import files with absolute paths in the pipeline tool (If i add a file and use “link” instead of “copy to directory”.

In my mgcb file it looks like this

/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:E:/images/11098302195_9b9e9ac974_o.png

when i build this it will throw no error.

However, when I call the command line tool with the same line ( /build: directory)

pProcess.StartInfo.Arguments = "/@:Content/mgcb/" + pipeLineFile + "/build:E:/images/11098302195_9b9e9ac974_o.png";

it tells me
System.NotSupportedException: The given path’s format is not supported.

What am i doing wrong? I merely copied the build operation from the generated mgcb file

Unhandled Exception: System.NotSupportedException: The given path's format is not supported.
   at System.Security.Permissions.FileIOPermission.EmulateFileIOPermissionChecks(String fullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
   at System.IO.StreamReader..ctor(String path, Encoding encoding)
   at System.IO.File.InternalReadAllLines(String path, Encoding encoding)
   at MGCB.MGBuildParser.Preprocess(IEnumerable`1 args) in C:\Users\Thomy\Documents\Visual Studio 2015\Projects\Monogame\Tools\MGCB\CommandLineParser.cs:line 287
   at MGCB.MGBuildParser.Parse(IEnumerable`1 args) in C:\Users\Thomy\Documents\Visual Studio 2015\Projects\Monogame\Tools\MGCB\CommandLineParser.cs:line 182
   at MGCB.Program.Main(String[] args) in C:\Users\Thomy\Documents\Visual Studio 2015\Projects\Monogame\Tools\MGCB\Program.cs:line 35

In the code generated command-line, you’re missing a space before /build.

Change

pProcess.StartInfo.Arguments = "/@:Content/mgcb/" + pipeLineFile + "/build:E:/images/11098302195_9b9e9ac974_o.png";

to

pProcess.StartInfo.Arguments = "/@:Content/mgcb/" + pipeLineFile + " /build:E:/images/11098302195_9b9e9ac974_o.png";

ah yes.

Now it’s back to the old too many arguments exception. Same if i comment out my content file and only build with
"/build:E:/ … "

really strange

EDIT: Sorry, I didn’t supply the full path to the image since it was super long, contained personal information and I thought it didn’t matter. But it does. Really sorry for the confusion.
One folder in the path is named “My Data” and the parser interprets the space between the words. So it seperates the string into /build:E:/…/My and Data/…/… .png

I’ve tried this by manually starting the mgcb.exe with the command line /build: etc from the monogame source code.

I am not 100% sure this happens in the actual content pipeline tool though, i will investigate.

EDIT: In the content pipeline the containing folders are marked with a red cross if i use a “link” to the texture file. It throws no build errors, and I’m not sure why, since it doesn’t build the files at all.
What is the intended behaviour for linking files? They should still be processed and copied to the output path, right?

EDIT: Nvm, it will create the .xnb inside the linked folder. Interesting. This works fine, too. I can load the content inside the game with the long path.

Does it make a difference if I supply stuff like
/outputDir:bin/$(Platform)
/intermediateDir:obj/$(Platform)
/platform:Windows
/config:
/profile:Reach
/compress:False
before hand?

When paths are specified on the command-line, it should work by wrapping the path in double quotes.

pProcess.StartInfo.Arguments = "/@:\"Content/mgcb/" + pipeLineFile + "\" /build:\"E:/images/11098302195_9b9e9ac974_o.png\"";

The reason the paths are treated differently when on the command-line and in the response file is that on the command-line, the command processor is responsible for splitting up the command-line parameters. In the response file, it is the application that reads and processes the response file, and it just takes each line as a separate parameter.

1 Like

ah that works!

Thank you very much, maybe that should be added to the documentation

One last question though - it seems like if I use a relative path to the file then the output generated (xxx.xnb) will also be in that folder.
For an application that just wants to load some files to display this is obviously not a good fit, I don’t want to access write/delete files that are outside my application directory

Can I not specify a different output folder if I use absolute paths?

I use this in my pipelinefile and it worked before with relative paths.
/outputDir:Content/Runtime/Textures

I found this old PR related to MGCB and relative paths. You may be coming across the same bug. I will have to get back to have a look at that PR again.

Ok thank you.

For easy reference

Executing:
mgcb.exe /outputDir:RelativePath /build:AbsolutePath

Expected Result
Processed file found in outputdir (RelativePath)

Actual Result
Processed file found in AbsolutePath

oh wow

the behaviour described above only happens if the loaded file is only happening if the files are on a different partition.

Otherwise this will be a strange mingle of relative paths… am a bit confused how i can work with this.

My settings are
/outputDir:Content/Runtime/Textures

(no working directory set - is this important?)

Full version
My program executes from here:
C:\Users\Me\Documents\Visual Studio 2015\Projects\HelperSuite\HelperSuite\bin\Windows\x86\Debug

if I process the file
C:\Users\Me\Documents\Visual Studio 2015\Projects\DeferredCascadedShadowMaps\GameThumbnail.png

The resulting processed file will be created here
C:\Users\Me\Documents\Visual Studio 2015\Projects\HelperSuite\HelperSuite\bin\DeferredCascadedShadowMaps\GameThumbnail.xnb

So it’s not stored in the input directory and not in the working output directory either. It seems like the output dir is a relative path again plus the path to the input