Compile Mono Resource Files Safely with resgen2
resgen2 turns a text resource file into the binary .resources format that Mono and .NET load at runtime. Allow about ten minutes if Mono is already installed, covering the conversion, a round-trip check, and compiling several files at once.
The route
Jump straight to the step you need, or tick off Done means at the end.
The examples also show the default output name and a safe replacement pattern. The commands change only files in the directory you choose, and normally need no elevated privileges.
1. Check the installed command and version
This guide follows the resgen2(1) manual and the installed command on a Debian or Ubuntu system. The machine used for these examples has the mono-devel package at version 6.8.0.105+dfsg-3.6ubuntu2, and resgen2 reports Mono Resource Generator version 6.8.0.105. Other Mono releases can differ, so check the local help before putting an option into a build script.
$ command -v resgen2
/usr/bin/resgen2
$ dpkg-query -W -f='${Package} ${Version}\n' mono-devel
mono-devel 6.8.0.105+dfsg-3.6ubuntu2
$ resgen2 --help
Mono Resource Generator version 6.8.0.105
On a non-Debian system, use its package query tool or skip the package-version check. The command itself is the useful check: it confirms which executable your shell will run.
2. Create a small TXT resource file
A TXT resource file holds one key=value entry per line. Lines beginning with # or ; are comments. Values can use the documented escapes \n, \r, \t and \\, and resgen2 also accepts a four-digit Unicode escape such as \u03bb.
$ mkdir -p "$HOME/resgen2-demo"
$ cd "$HOME/resgen2-demo"
$ cat > messages.txt <<'EOF'
# Text used by the example application
welcome=Hello\nworld
symbol=\u03bb
path=C:\\tmp
EOF
The quoted here-document keeps the backslashes in the file. Replace the example directory with a working directory you control. Do not use sudo to create ordinary project resources: changing ownership or permissions to work around a path mistake only hides the real problem.
3. Convert TXT to RESOURCES
Give the source and destination explicitly when you want the command to be easy to review:
$ resgen2 messages.txt messages.resources
Read in 3 resources from 'messages.txt'
Writing resource file... Done.
The destination is the binary format read by .NET and Mono resource APIs. It is normal for file to describe this output only as generic data.
$ test -s messages.resources && file messages.resources
messages.resources: data
$ resgen2 messages.resources messages-roundtrip.txt
Read in 3 resources from 'messages.resources'
Writing resource file... Done.
$ sed -n '1,10p' messages-roundtrip.txt
symbol=\u03bb
welcome=Hello\nworld
path=C:\\tmp
The round trip is a useful smoke test. Resource ordering is not a contract, so do not compare the text output line by line in a test unless your build explicitly permits reordering.
4. Let resgen2 choose the default destination
If you omit the destination, the manual says source.resources is used. Convenient for a one-off conversion, and an easy way to overwrite an existing file without noticing.
$ resgen2 messages.txt
Read in 3 resources from 'messages.txt'
Writing resource file... Done.
$ test -s messages.resources && echo 'resources file is present'
resources file is present
Before using this form in a directory that already contains generated files, inspect the target first:
$ test -e messages.resources && ls -l messages.resources || echo 'no existing output'
Warning
Shell redirection is not involved here, but the converter still writes the named destination. If the old output matters, copy it to a backup before conversion. To undo that, restore the backup with mv after checking the exact paths, and do not delete the backup until the new resource has been tested.
5. Compile several files in one command
Use /compile before the resource list for a bulk conversion. Each item can be source,destination. The installed command also accepts -compile, but the slash form matches the manual's synopsis.
$ resgen2 /compile \
strings.txt,strings.resources \
errors.txt,errors.resources
Read in 12 resources from 'strings.txt'
Writing resource file... Done.
Read in 4 resources from 'errors.txt'
Writing resource file... Done.
Use real source names in place of the examples. The files must be TXT or RESX inputs for this bulk mode. Check every output after the command, especially when a later item fails, because earlier items may already have been written:
$ for f in strings.resources errors.resources; do
> test -s "$f" && file "$f" || printf 'missing or empty: %s\n' "$f"
> done
strings.resources: data
errors.resources: data
6. Choose the right format and diagnose failures
The supported formats in the manual are text, binary .resources, .resx and .po. A PO file is a gettext-style source with msgid and msgstr pairs. Plurals and other extended PO features are not supported by this resource conversion, so do not assume a general gettext catalogue converts losslessly.
If a file cannot be opened, check the path and read permission without changing anything:
$ test -r messages.txt && echo readable || echo 'not readable'
$ ls -l messages.txt
$ resgen2 missing.txt missing.resources
Error: Could not find file "missing.txt"
A non-zero exit and a missing or empty destination mean the conversion did not produce a usable result. Fix the source syntax or path, then rerun into a new destination. Do not run as root to bypass an error unless the input is intentionally protected and you have a separate, reviewed reason for elevated access.
Done means
- The installed
resgen2executable and Mono version were confirmed. - Your TXT, RESX, PO or resources input is in a supported format.
- The intended
.resourcesdestination was checked before it could be replaced. - A conversion completed with a success message and a non-empty output file.
- Bulk output files were checked individually, including after a partial failure.
- The original source was kept, and any backup can be restored before it is deleted.