I am working on a windows application that will need to be branded. The client will be selling this to other businesses, and needs a customized logo and name for each sale.
The client does not know how to use visual studio!
I think I need to write a packager app to inject custom logo and string resources into the executable. I am planning on using WPF. But since this is a critical requirement, I'd be willing to do it in winforms if that is easier.
What is the best way to do this? Any and all suggestions welcome.
It sounds like what you are after is application skinning. This doesn't mean you have to unpack the exe and inject resources. You just need to consider skinning from the start of the project and build the application to support your skinning requirements.
WPF will make skinning your app much easier. There will be several different ways to accomplish what you want.
Simplest is to leave the logo image loose and reference it with a relative path from the XAML file(s) that need to show this image.
You should look into Resource Dictionaries in WPF and how they help you group resources and support skinning. http://msdn.microsoft.com/en-us/library/ms750613.aspx
The text will be a little different but I am not sure what you need as far as a text goes. Do you mean you need to localize the strings or do you simply need different text (all the same locale) to show for different clients?
One possible solution (perhaps not the simplest one) is to use a parent application which compiles source code for generating child application. You can do it with CSharpCodeProvider and CompilerParameters classes. Add the image as an embedded resource and retrieve it in the child application. A working demo with a source code is available at Slide Show Builder.
My best suggestion for the exact question you asked (although I suspect there is another way by reconsidering the exact requirements) would be to write a utility which uses ildasm to disassemble the assembly, then use ilasm to reassemble it and include your new resource file.
http://msdn.microsoft.com/en-us/library/496e4ekx%28VS.71%29.aspx
The trivial solution is to provide the bitmap along with the EXE as a separate file. Actually replacing an embedded resource in the EXE requires decompiling it with ildasm.exe and putting it back together with ilasm.exe. Ildasm.exe is only available in the Windows SDK, it can be downloaded separately. Error prone and small odds that your customer can get that right, you'll need to provide them with, say, a .bat file that does this.
Of course, whomever is interested in replacing the logo, for whatever reason, would not be slowed down by replacing either the separate image file or using the Ildasm.exe trick. There is therefore very little point in making it any more complicated then it needs to be.
Related
I have this problem:
I made a C# WPF (.NET Framework 4.0) application and everything is ok. Now I want to obfuscate it. I tried with Confuser.
The question is:
If the app is published I can see the main exe file and dll-s. So I tried to obfuscate the exe. Where should I put the obfuscated .exe generated file (I obfuscate only the main exe file). I mean Confuser creates a folder called "Confuser" with the obfuscated exe in it.
If I doubleclick the obfuscated exe to start the app as usually it doesn't work and I get the normal application crush window.
I also tried to replace the original exe file (in the app folder) with the obfuscated one (from Confuser folder).
If the app is deployed I have the setup.msi pack or setup.exe. How should I obfuscate in this case ?
Thankx,
Adrian
All XAML-based platforms (WPF, Silverlight, Windows Phone) are quite problematic area for most obfuscators. The main problem is that XAML references types and members by name. No wonder the applications often doesn't work after obfuscation: the integrity breaks.
There are two ways that are used by obfuscators to keep the output assembly work afterwards:
Search XAML content for everything that could be a type or property name and then roughly exclude all members that anyhow match these names. This doesn't give 100% guarantee that the application is not broken while makes the obfuscation coverage poor because of the inaccurate analysis. Still this approach can potentially save your application from breaking.
Do something similar to what XamlReader does: load XAML tree and find all matching CLR types and members. After renaming all the changes are synchronized with XAML. This approach gives the best reliability and coverage (types and members are renamed both in the code and XAML). There are obfuscators on the market that claim that they support XAML renaming. You may want to try some of them.
There is also a workaround. Most obfuscators support conditional obfuscation allowing to manually exclude specific types and members. You should manually exclude all the types and members that are somehow referenced by XAML. This will take some time but usually works.
First, you obfuscate your main .exe file and replace the old one. Then you pack everything into installer.
Also make sure all the properties and types involved in xaml are declared as public. Or tell the obfuscator to ignore them somehow.
I'd experiment with a simple console app first. Make sure you can get it working with that.
Then I might progress to a simple WPF app.
The problem with WPF and obfuscation is it relies on reflection. The View Models are bound by name. It could be this obfuscator isn't sensitive to this, or you need to configure it to ignore the names of properties on your view models.
If you've any other reflection using name, that could break it too. Even a Enum.Parse call can be tripped up. Maybe you seralize to/from XML, that is also a point it could break at.
You may want to display the exception that the app is crashing with to help you debug, but I would get comfortible with the tool myself with simple apps to work out how it gets around the above issues.
I need to make a ClassLibrary, to contain different Resource Files (resx). This needs to be done, so I can reuse these resources on multiple projects.
After reading for quite a while on how to achieve this, I'm still nowhere near close to an answer.
Note that i need to achieve this in a way that I don't have to recompile the proyect if I want to change a value
Is there a simple way to achieve this that I'm missing?
Hate to be the bearer of bad news, but I'm afraid you're trying to use RESX files for something other than what they're designed to do. RESX files are compiled into .resources files, which are then embedded into the assembly during the build. In other words, if you don't recompile, you won't see any changes that are made to the resx file reflected in the module.
The benefits of RESX files extends far beyond providing compiled cultural/language text tightly coupled to a deployed solution. They have the potential to provide a simple and flexible set of content managed outside the software development process. Some views here:
What are the benefits of resource(.resx) files?
Yes you can work with your RESX files without having to compile them. See here:
Edit ASP.NET MVC 3 resx files in deployment server without recompiling
Yes you can share RESX files between different projects and even roll your own resource manager. You can maintain alternate sets of resources, serving up alternate content depending on for example the user context. I have been involved in a project where we implemented something along these lines to great affect, in my case the solution was used to provide white labeling. Some detail to get you started here:
http://msdn.microsoft.com/en-us/library/aa905797.aspx
I have a WinForms application which I want to translate into multiple languages. However, I do not have any experience with localizing a WinForms app, and I find very contradictory information about this subject.
Basically, what I want is:
In the source code, I want only one file per language
This file gets compiled into the main application on compilation - no satellite assemblies or external data files after building the application
The user can select the language, I do not need/want auto-detection based on the operating system
This should mainly contain strings and ints, but also a CultureInfo
Most solutions I've seen either have one .resx file per Form and/or external satellite assemblies.
Do I have to roll my own?
Or is there something in the framework already?
.net Framework 3.5 SP1 if that matters.
Edit:
For the most part, Visual Studio already offers support for what I want, but there are two issues. When I set Form.Localizable to true I have this nice Designer support, but this generates one resx per Form. The idea of manually overriding it in InitializeComponent fails because it's designer-written code that will regularly be overwritten.
Theoretically, I only want to :
a) override the creation of the ComponentResourceManager to point it to my global resx and
b) change the call to ApplyResources to the overload that takes a CultureInfo as third parameter.
It seems as if I have to add a function call to my constructor that gets called after InitializeComponent() and overrides its behaviour. That seems terribly inefficient, but Visual Studio is right when it warns about touching InitializeComponent().
At the moment, I am indeed rolling my own WinForms localization Framework...
I've just completed a C# .Net 3.5 project with a similar problem. We were writing WinForms plugin for an existing multi-lingual application with 8 languages (including English).
This is how we did it:
Create all our forms and UI in the default language, English.
Put all our internal strings in a resource file (stuff not tied directly to a form like custom error messages and dialog box titles etc)
Once we had completed most of the work and testing we localised it.
Each form already had a .resx file but this was empty. We set the property 'Localizable' to true, the .resx file was filled with things like button sizes & strings.
For each of the other languages, we changed the 'Language' property on the form. We chose the basic version of each language eg: 'Spanish' instead of 'Spanish (Chile)' etc. so that it would work for every 'Spanish' dialect, I think.
Then we went through each control, translated its text and resized, if needed. This created a .resx per language and form combination.
We were then left with, for 8 languages, 8 .resx for each form and 8 .resx for the general strings. When compiled the output folder had the .dll we were creating and then a sub folder for each language with a .resources.dll in it.
We were able to test the versions of the UI in the designer by just changing the language property to check that we had the correct strings & layout.
All in all once we got our heads around it, it was quite easy and painless.
We didn't need to write any custom tweaks to the form loading
I was asking a similar question about ASP.NET and got a first answer - this tool and its workflow might also be something for you - have a look: Lingobit Localizer
It seems to be able to load your Winforms app and allows you to start translating your labels etc. and see the forms while you do it. Lots of other features, too, like incremental translation and translation memory (if you use the same terms over and over again).
Looks quite promising (for Winforms) - haven't used it myself, though.
Here's an extensive list of potential .NET localization tools - not sure, how well they work and what they cover - have a look, maybe you'll find what you're looking for.
Marc
I dont have a solution for your first and second requirement but keep in mind that localizing a form is not as simple as translating each word. You need to check that each translated text fits in their respective control. Also, maybe you have an icon or an image which need to be change in another culture.
For your point three, you can change the language manually with the following lines:
CultureInfo ci = new CultureInfo("fr");
Thread.CurrentThread.CurrentUICulture = ci;
This is a huge subject and there are many ways to accomplish what you want. The framework does provide the basis but a complete solution requires that you implement certain elements yourself.
For example the default framework implementation is to create a .resx file for every resource. In ASP.Net this means each user/server control or page. This doesn't lend itself to easy maintenance and if you want to move resources to a database you need to implement your own provider.
My familiarity with Winforms is limited but if you are using Silverlight or WPF then have a read of Guy Smith-Ferrier's work on the subject at: http://www.guysmithferrier.com/category/Internationalization.aspx. He also has some toolsets that can make your life easier at: http://www.dotneti18n.com/Downloads.aspx.
I've worked with him before and have never come across anyone else with a better depth of understanding of the subject.
What you are asking for:
no satellite resource files
only one size and control placement per form.
lots of languages embedded in the executable.
Is not do-able in vanilla Visual Studio's IDE.
What it would require is some custom work, basically fulfilling all these steps:
Acquire a custom resource manager that handles TMX resource files.
Put all your localizable strings in a TMX file.
Make this TMX file an embedded resource in your project.
In your Form constructor, create your TMX ResourceManager, loading the TMX file from your embedded resources.
In your code, use your tmx ResourceManager instead of the default ResourceManager for getting localized strings.
Let the Form use the default ResourceManager for getting all the designer things except the strings.
Get your TMX file fleshed out with the new language translations.
More can be added in the next release of your project, just by adding them to this TMX file before you compile.
RESOURCES: (not an exhaustive list, by any means)
http://en.wikipedia.org/wiki/Translation_Memory_eXchange
http://sourceforge.net/projects/tmx-editor/
The right way to do this is, suppose you want to add Arabic support witch is RightToLeft language:
Double click the form
Set localizable prop. to true
Change Language prop. to Arabic //This will automatically open a new version of the form so you can customize.
Set RightToLeft prop. to Yes
Set RightToLeftLayout prop. to True
Start renaming controls, and save the form.
Handle Messages/Errors in code // Sorry I don't have a quick solution for now, try duplicate them and If/Else the current local.
We have a resource file with lots of translated strings used various places in our application. Is there a better way for binding for example the text of a button to a certain string?
Currently we are usually just doing something like this in the constructor, in a Load event handler or in a method called by one of those:
someButton.Text = CommonTexts.SomeString;
someMenuItem.Text = CommonTexts.SomeOtherString;
Is there a better way to do it? Maybe in the designer? Or is this the recommended way of doing it?
Just to let you know how we do the actual translation: We have one Class Library project which only contains resx files. The main resx files are written in english (of course). We then open up those base resx files in an application called ResEx where we (or someone else) does the translation to other languages. When compiled Visual Studio automatically creates assemblies for each language which are used automatically depending on the current culture set. This works pretty well, so I don't really need info on how to do the translation and such (although I am always curious to improvements of course). What I am asking is if there is a better way for getting those translated strings from the resource assembly and into all the various Text properties.
I understand, it's an old question, but still, I had the same issue (VS 2010), and one of the first links in google is this topic.
In order to move all the texts to forms resource file - you need to set the winform Localizable property to True. And that's it. :)
(c) Cap. O.
You can do:
using System.Resources;
using System.Reflection;
Assembly assembly = this.GetType().Assembly;
resman = new ResourceManager("StringResources.Strings", assembly);
btnButton.Text = resman.GetString("ButtonName");
There is a good tool called LingoBit Localizer that does the job for the fraction of the time it would take to build all the reasources files.
You don't have to care about other languages while in development process, you simply code and set properties as you would if you were programming for a unilingual software. After you're done, or whenever you wish, you run LingoBit Localizer over your DLL or Windows Form application. This will get user-displayable strings out to a grid for you within its GUI. Now, perhaps a professional translator could use to translate the words if your programmers don't know the language for which the applicaiton have to be translated. Then, you simply save the project when you're done. This will create a DLL file which you simply add to your binary deployment directory, then your application will automatically set itself to the right language depending on the current culture information on which the app. is installed or so. This saves a lot of programming time and headaches.
Hope this helps even though it is not resource-based solution.
This will extract the the value of Home keyword and populate into the Text1 Box.
Text1.Text= Resource.Home.ToString();
Try this:
someButton.DataBindings.Add("Text", CommonTexts, "SomeString");
Your way is the best way to do this if you have developers who are not personally fluent in the languages you're translating your application into. I've done this before with an English application that had to be translated into Spanish, Portuguese and Chinese (I only speak one of these semi-fluently). The original forms were all created in English, and in the form's Load event the code iterated through every control and searched for each control's Text property in a translations spreadsheet, and replaced it with the appropriate translation.
The built-in way of internationalizing a form (which is basically a variant of form inheritance) assumes that the programmer is fluent in the language you need to translate to, which is pretty much of a stretch, and it requires you to manually enter all the translated text values for each form and each language. It also makes your binary larger (potentially much larger), since it adds a .resx file for each form for each language that you support.
Alright, so I'm working on programming my own installer in C#, and what I'd like to do is something along the lines of put the files in the .exe, so I can do
File.Copy(file, filedir);
Or, if this isn't possible, is there another way of doing what I am attempting to do?
I wouldn't code my own installer, but if you truely want to embed files into your assembly you could use strongly typed resources. In the properties dialog of your project open up the "Resources" tab and then add your file. You'll then be able to get the file using:
ProjectNamespace.Properties.Resources.MyFile
Then you'll be able to write the embedded resource to disk using:
System.IO.File.WriteAllBytes(#"C:\MyFile.bin", ProjectNamespace.Properties.Resources.MyFile);
Honestly, I would suggest you NOT create your own installer. There are many many issues with creating installers. Even the big installer makers don't make their own actual installers anymore, they just create custom MSI packages.
Use Mirosoft Installer (MSI). It's the right thing to do. Make your own custom front-end for it, but don't recreate the already very complex wheel that exists.
UPDATE: If you're just doing this for learning, then I would shy away from thinking of it as "an installer". You might be tempted to take your "research" and use it someday, and frankly, that's how we end up with so many problems when new versions of Windows come out. People create their own wheels with assumptions that aren't valid.
What you're really trying to do is called "packaging", and you really have to become intimately familiar with the Executable PE format, because you're talking about changing the structure of the PE image on disk.
You can simulate it, to a point, with putting files in resources, but that's not really what installers, or self-extractors do.
Here's a link to Self-Extractor tutorial, but it's not in C#.
I don't know enough about the .NET PE requirements to know if you can do this in with a managed code executable or not.
UPDATE2: This is probably more of what you're looking for, it embeds files in the resource, but as I said, it's not really the way professional installers or self-extractors do it. I think there are various limitations on what you can embed as resources. But here's the like to a Self-Extractor Demo written in C#.
I'm guessing here, but if you are trying to store resources in your application before compilation, you can in the Project Explorer, right click a file you would like to add, chose properties and change the type to Embedded Resource.
You can then access the embedded resources later by using the instructions from this KB:
http://support.microsoft.com/kb/319292
in case you simply want to store multiple files in a single file storage (and extract files from there, interact etc.) you might also want to check out NFileStorage, a .net file storage. written in 100% .NET C# with all sources included. It also comes with a command line interpreter that allows interaction from the command line.