Share This Using Popular Bookmarking Services

Google ads


network monitoring software

Programs & websites tailormade for you.

Introducing ResxToDocx2  - a program to maintain translations of .resx files in .net

Newest release is version 2.0.1 - the downloadable file is at the bottom of this page.

What is it?

  • A simple program that finds and compares all your resx files in a .net project with text in a MS Word document in order to maintain track of your translation and text changes. New text pieces can easily be added to the Word document, and new translations can easily be added to your resx files.
  • The Word document can be given to translators or proofreaders - for proofreading it contains both the English (or master language) text in one column and the local translation in another, so it is easy to compare if the translation says the same as the master language. Using Word's track changes ability, you can also spot when/where the master language (English) text has changed, so you can verify just those pieces of translations.
  • Allows detecting unused and orphaned resources, so you can remove text that is no longer used, or spot translations that does not match the current code.

Who is it for?

  • .net developers - only the developer of his own program should do the actual text update verification, since updating the labels of your code should be done with understanding of your own program.
  • It is not a tool to do the actual translation - translators can do that using Word or another program that can read Word files.

Minimum requirements:

  • .net 3.5 runtime
  • Microsoft Word on development machine (tested with 2010 edition)
  • A fast computer


This program is copyright © 2012 Allan Kindberg Nielsen,

It is released as Shareware - by which I mean: You get the full program (no limitations) and if you like it and use it, you are encouraged to give me a small donation as sign of your appreciation.

The program can freely be used for any kind of projects, open source or commercial.

I might one day decide to release a paid for version of the program, which uses a different (commercial) library to manipulate the Word files, which would make the program 100 times faster... But until then, the current shareware version is the best version I got.

I'll look at the legal license documents some other time, but until then there is the usual warning:

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Use at your own risk!

You are licensed to use this program on any amount of computers that you need it on, but you are not allowed to distribute it, repackage it or take it apart in any way. If you want to promote the program, just promote a link to where others can download it.

Known limitations:

Localization resources can be used in many different ways - the program covers the ways I am doing it in those program/websites I have been doing during the past 3 years, but if you do it differently, then the program's ability to detect unused text will not work.

Word automation have always been slow, buggy and unreliable - but it is very easy to code, and does not cost anything (provided you already have Word on your computer), so considering the price of this program: please don't complain

Installation instructions

Download and extract the zip file.

Click "Setup.exe" to install the program - note: If you have installed a previous version, then you either have to uninstall it first, or you have to place the unzipped files the exact same place as your previous download.

Take a look at the Samples folder where you unzipped the download.

Copy the xml file from the Samples to where you want to use it (such as the root of your own solution), edit it to fit your project (see details below) and create an new Word document to contain the translation. (Repeat this XML+Word file setup for each language you need to cover.)

Future plans

I might add a possibility to also extract and compare content of database tables - in at least one project I store longer texts like automated emails in the database, and I basically need the same extract and compare functionality to update the translations.

And as said earlier, if there is a demand for it, I might make a payment-only version of the program that uses something faster than Word automation for manipulating Word documents...

Otherwise the program will be developed and updated based on my own needs for the different international projects that I manage.


How to use the program


Here is a screen shot of the program, with numbers that refer to descriptions below:

  1. Choose the Word file that contains the translation (for first time use: make a new empty Word document).
  2. Choose the xml file that describes your .net project and how the comparison should be performed (see details later)
  3. Click "Start comparison" to begin comparing
  4. After specifying whatever actions the program should do, click "Save changes"
  5. To get the program to check your code to see if you actually uses the text, check this.
  6. Normally the program will only display differences and programs - to also see all the perfect matches check this.
  7. In this area status messages are written - mainly just so you know the program is still doing something...
  8. All found resx files will be listed in this dropdown list. Choose one to get it displayed in the grid below.
  9. A shortcut button to get all text copied from resx files to the word document.
  10. A shortcut button to get all text copied from the word documen to your resx file.
  11. If the status area warns about not finding a resx file in the word document, check this and press save - the program will add new tables to your word document covering all the missing files.
  12. A shortcut button to get rid of unused or orphaned text (see details later)
  13. N/A
  14. A grid listing all the labels and text differences - the "Action" column is where you for each line can specify what the program should do (see details later)
  15. For the currently selected line in the grid, this area shows the text that is written in the word document - if it is different than the text in the resx file, then the differences are highlighted.
  16. For the currently selected line in the grid, this area shows the text that is written in the resx file - if it is different than the text in the word document, then the differences are highlighted.
  17. For the currently selected line in the grid,this area shows the comment from the resx file, if any.
 Configuration file:

The xml configuration file selected as #2 above describes how the text comparison should work, and how your source code should be scanned.

The following sample file is included in the zip file, and it has lots of comments to describe the different possible options.

Most likely you only need to change two things: The SolutionRoot should be adjusted to the root of your project/solution, and the LocalLanguageCode should be adjusted to the .net culture you want the translation document prepared for. Specify the culture exactly as in your resx file naming.

The sample xml file looks like this:

<?xml version="1.0" encoding="utf-8" ?>
     Path to the root of the solution or the individual project to be checked.
     See note under GlobalResourcesFolders - you need to specify the path to them
     for each project, if a top level Solution folder is choosen here.
      MasterLanguageCode can be set to a value such as: en-GB, but is usually empty which means
      compare to the special language-code free version of the resx file.
      LocalLanguageCode should always be set to the specific language or language+country
      code that you want to compare against the master language.
    <GlobalFolder CompiledNamespace="Translation" CodePattern='GetResource("{0}")'>\Translation</GlobalFolder>
    <GlobalFolder CompiledNamespace="Resources" CodePattern='GetGlobalResourceObject("{1}","{0}"'>\App_GlobalResources</GlobalFolder>
      These folders must be directly under the SolutionRoot (if not, give the full relative path to them).
      For use when "Detect unused text pieces" is selected, the CompiledNamespace attribute should specify how they
      get compiled.
      Example: \App_GlobalResources contains a file called MyTexts.da-DK.resx with a label called "Title",
      and with CompiledNamespace="Resources" this program will look for the presense of: Resources.MyTexts.Title
      (which is how you would refer to it in code behind or databinding statements to automatically get
      the correct translated version of "Title".)
      If you access the resources by different means than the strong name, you need to specify CodePattern which
      is the name of the function which you call to get a label. The standard pattern for global resources
      is:  CodePattern='GetGlobalResourceObject("{1}","{0}"' - note no ending ")" so it will catch overloaded variants too.
      In the CodePattern {2} gets replaced with the CompiledNamespace, {1} gets replaced with the file/class name
      and {0} gets replaced with the label name.
      If the label contain a "." then a third search is done for: resourcekey="xxxx"
      where the resx file contains "xxxx.Text" and/or "xxxx.ToolTip" - but note that
      this will not detect if the ending is valid.
      If the label contain a "." then a fourth is done search for: GetString("xxxxx
      followed by any non-letter (such as . or ")
      Note that use of ' in code gets normalized to " before comparison with the CodePattern.

      The IgnorePathPatterns is used both to exclude App_LocalResources folders that should not be processed
      and to exclude directories/files of code that should not be checked when "Detect unused text pieces" is selected
      (such as backup and code revision/history folders).
      If you have excluded folders/files from compilation in VisualStudio
      (such as an directory of legacy code that is no longer needed)
      then you should edit this list to also exclude those from being checked!
      If the master language contains text pieces that SHOULD NOT be translated (such as text that is
      purely for administrators - if an english speaking guy is administering a website in Russian he might
      get lost if all his administrative menus and commands were suddently translated too!), then you
      can use the comment field in the resx document to put a special value that means this item should
      not be translated.
      Note: I suggest that you put comments that identify which revision of the program that the text was introduced in.
      Note: It is only the comments of the Master language that matters - no comments is needed or used in the local resx files.
      Note: Besides an empty <Comment></Comment>, the comment of the resx file must just include the comment text as part of it to be a match.
      Note that App_LocalResources folders anywhere below SolutionRoot is automatically detected,
      unless blocked by one of the IgnorePathPatterns.
      When "Detect unused text pieces" is selected, the code is scanned for the presense of: <%$ Resources:xxxxx %>
      (where "xxxxx" is the labels found in the resx file matching the aspx/ascx page name)
      And for the following CodePattern: GetLocalResourceObject("{0}"      
      If the label contain a "." then a third search is done for: resourcekey="xxxx"
      where the resx file contains "xxxx.Text" and/or "xxxx.ToolTip" - but note that
      this will not detect if the ending is valid.
      If the label contain a "." then a fourth is done search for: GetString("xxxxx
      followed by any non-letter (such as . or ")
      Note that use of ' in code gets normalized to " before comparison with the CodePattern.
    <Ext CleanLineComments="true">.cs</Ext>
    <Ext CleanLineComments="true">.ashx</Ext>
      Remember to include all file endings that should be scanned when "Detect unused text pieces" is selected.
      Note: Besides an empty <Comment></Comment>, the comment of the resx file must just include the comment text as part of it to be a match.
      Add this text to the comment for those labels where ResxToDocx for some reason does not autodetect that they are in use
      (for example because it is used by a code lookup instead of strong naming).


Actions drop down choices & the grid of labels:

Note that what Visual Studio's resx editor calls "Name", I call "Label" - which is the name/label that identifies each resource, so that the translation can be put back in under the correct name.

The actions possible in the dropdown choices in the grid is:

"1 - copy to word" - copies whatever is in the resx file for the current label to word.

"2 - copy to resx" - copies whatever is in the word document for the current label to your resx file.

"3 - delete from word" - deletes the label row from the Word document, without changing the resx file.

"9 - delete/mark unused" - will delete the label row from word, and will rename the label in your resx file to start with "UNUSED__". Check if your project still compiles compiles, and if you incorrectly marked something as unused, simply open the resx file and rename the label to its old name. Note that you should not delete unused records before you have checked all languages (and the compilation and functionality of your program).

"x - no nothing" - do nothing, use to cancel other dropdown choices.

Note: The numbers works as shortcuts - you can go down through a grid by pressing enter, and change an action by pressing the number of the action you want. Or use the shortcut "All to xxx" buttons above the grid if all labels should have the same action applied.


The typical use of the program

Run the comparison and start by checking all your master language resx files - are new texts added that should be copied to word? Are some of the labels unused? Did the translator spot an error in the English text that should be copied to your resx files? Etc.

If there was any changes, then click save and then do a new comparison.

Now go though all the local language resx files - if you just added a bunch of new English text, then translations will be missing. Do not copy the missing/empty text to your local resx files! If you do, then the user would see empty text instead of the fallback English/master text.

In other words: You have to think and decide what you want to do with the comparison, before just blindly copying it!

But once you got a translation back, mark the differences to be copied to the local resx files.


Once in a while you might choose "Detect unused resx labels" to spot unused resources. Here again first look at all the English/master language files - and if you know a label is used in some undetectable manner by your code, you should maybe manually add a comment to your resx file so it will be ignored from future checks (see the xml file above for how to make exceptions).

Once you have saved the result of checking the master language for unused text, you can run the check again, and then look at the local resources - all other languages does not do a full detection, they just check the master language resx file to see if the label has been marked as unused.

Local language labels might also be orphaned - that is, one language contains a label that does not exist in the master language, which will make it impossible to ever use it.


When looking at the comparison, always think if what you see makes sense. If a translation document contains a label that does not exist in your master resx file, then it might be an error in the translation document. Or if a local language resx file contains a label that is not already in the word document, then you can suspect that it is an orphan and run the detection for unused text.


Before giving the word document to a translator, you should select all the tables and format them so the table edges are visible.


There is probably a lot of other advice I could give, but after using version 1 of this program for 3 years at my work, I probably take thinks for granted that you need explained - so feel free to go to the forum and ask me questions!


Version history

  • Was rewritten between version 1.0 and version 2.0.0 to add automatic detection of weather labels are used, and automatic detection of which resx files are in the project.

  • From version 2.0.0 to 2.0.1 was fixed bugs regarding disabling spell check in Word (if you used version 2.0.0 you have to manually re-enable spell and grammar check in Word), as well as some bugs regarding detecting use.


Notes & known bugs

  • Linefeed is replaced by space - as this is what fits my use for websites. I might later on add some configuration value to keep it or to replace it with something else...

  • There is so many ways of using localization that the "Detect use" functionality will not cover all possibilities. As I get feedback, or need to detect other kinds of use, I will improve the functionality.


Shareware, remember?

If this shareware program is of help to you, then show your appreciation here: Donate via PayPal

  File Name Description Size(KB) Downloaded Modified

Windows installer + sample setup of translation

608 574 3/27/2012 9:31:10 PM
2 object(s)