[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