[Mono-bugs] [Bug 80134][Nor] New - HOWTO: Embed .resx resources into assemblies

bugzilla-daemon at bugzilla.ximian.com bugzilla-daemon at bugzilla.ximian.com
Sat Dec 2 18:19:48 EST 2006


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by peter at drealm.org.uk.

http://bugzilla.ximian.com/show_bug.cgi?id=80134

--- shadow/80134	2006-12-02 18:19:48.000000000 -0500
+++ shadow/80134.tmp.17059	2006-12-02 18:19:48.000000000 -0500
@@ -0,0 +1,103 @@
+Bug#: 80134
+Product: Mono Tasks
+Version: 0%
+OS: 
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Normal
+Component: Build
+AssignedTo: mono-bugs at ximian.com                            
+ReportedBy: peter at drealm.org.uk               
+QAContact: mono-bugs at ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: HOWTO: Embed .resx resources into assemblies
+
+Under Visual Studio, .resx files are extensively generated to separate
+changeable, localisable and other non-programatic values from the main
+program source.  The .resx file is an XML document that is converted to
+"standard" .resources format during the MSBuild process.
+
+For the new-comer to building C# using MONO, getting a single .resx file
+converted to .resources format and embedded into the assembly isn't
+terribly clear.  The key factor is the name of the .resources file (at
+least, the name applied during the mcs compile).
+
+For example, file1.cs uses file1.resx to externalise strings (perhaps so
+they can be generated, etc).
+
+file1.cs:
+using System;
+using System.Resources;
+namespace p {
+  public class q {
+    [STAThread]
+    static void Main() {}
+    static q() {
+      ResourceManager r = new ResourceManager(typeof(q));
+      Console.WriteLine(r.GetString("localisedGreeting"));
+} } }
+
+file1.resx:
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 117 lines of XML header omitted for clarity -->
+  <data name="localisedGreeting" xml:space="preserve">
+    <value>Hello, world!</value>
+  </data>
+</root>
+
+Running "gmcs file1.cs" happily produces "file1.exe" but it crashes.  Quite
+helpfully, it explains:
+> Make sure "p.q.resources" was correctly embedded or linked into assembly
+"file1" at compile time
+
+So that's the clue!  But how to we get a file called p.q.resources
+embedded?  There's a tool in the MONO distribution called resgen2: you pass
+it two arguments (in this simple case).
+> resgen2 source.ext [dest.ext]
+By default, "file1.resx" would become "file1.resources" but that's not what
+we want.  We need p.q.resources.  So the command is:
+> resgen2 file1.resx p.q.resources
+
+Okay, onto the final step - compiling with the require resource.  This is
+just a matter of telling gmcs about it with the "-resource" parameter:
+> gmcs -resource:p.q.resources file1.cs
+
+Now running file1.exe produces the required results:
+> file1
+Hello, world!
+
+----------------
+All of the above holds true for .resx files relating to form layout managed
+by the Visual Studio designer.
+> #region Windows Form Designer generated code
+...
+>System.ComponentModel.ComponentResourceManager resources = new
+System.ComponentModel.ComponentResourceManager(typeof(Form1));
+
+That "Form1" will get turned into a fully qualified type name (e.g
+p.ui.Form1) and the appropriate .resources file will be needed
+(p.ui.Form1.resources).
+
+In all the examples here, it's been easy to guess the name that is needed
+because the filenames and classnames have matched.  However, life isn't
+always that kind.  Visual Studio doesn't rely on the filename, after all. 
+You could have called the file "Setup.cs", have a namespace of
+"our.widgets.userinterface.custom" and a component named
+"PopupScrollViewerForSetup" inside it, along with a few other classes just
+for good measure.  Indeed, Visual Studio will - if you try hard - let you
+have a different .resx filename from the .cs filename and maybe even allows
+more than one .resx filename (e.g. for different purposes in different
+classes in the one file!).  MSBuild uses the .csproj file to explain all
+this and generates the necessary commands.
+
+Moral: keep it simple (...).
+
+For those building with ANT, I've not yet come up with a good solution.  A
+partial solution involves a macrodef for the resgen step and manually
+calling it where required.  I've bundled up my work so far on ANT here:
+http://www.drealm.info/simpe/CsharpAnt.zip


More information about the mono-bugs mailing list