locked
Is it possible to update a resource file at run time??? RRS feed

  • Question

  • User1606391904 posted
    Hi All,
    Just wanted to know if it is possible to update a resource file at runtime.
    I am creating labels dynamically and want it to be updated in my resource file for both Japanese and English locale.

    Waiting for a Quick reply!!!!

    Regards
    Friday, September 23, 2005 2:28 AM

All replies

  • User1183903743 posted

    Not without recompiling.

    In v1.x There are a number of command-line steps to redeploy using Resgen.exe and Al.exe

    In v2.0 yes but with a lot of caveats especially for a newbie, and probably shouldn't be done unless you really know what you are doing.

    It involves good knowledge of XmlDocument and its schema and System.IO and security.
    Also care must be taken to update values in all the other localized resx files.



    Wednesday, October 12, 2005 1:38 PM
  • User1424575140 posted
    This doesn't compile them, but it does write them...
    System.Resources.ResourceWriter
    http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemResourcesResourceWriterClassTopic.asp?frame=true
    Thursday, October 13, 2005 11:05 PM
  • User1183903743 posted
    This doesn't compile them, but it does write them...
    System.Resources.ResourceWriter

    Beware this is for .resource file not for .resx
    Thursday, October 13, 2005 11:24 PM
  • User1424575140 posted
    I have code that uses the ResourceWriter to write resx files. In fact I do it at design time in VS.net

    Here is a couple of the relevant lines from it.

     System.ComponentModel.Design.IResourceService resourceService = (System.ComponentModel.Design.IResourceService) Site.GetService(typeof(System.ComponentModel.Design.IResourceService));


    IResourceReader sourceReader = resourceService.GetResourceReader(new System.Globalization.CultureInfo(sourceCulture));
     IResourceWriter writer = resourceService.GetResourceWriter(new System.Globalization.CultureInfo(targetCulture));
     foreach(DictionaryEntry de in sourceReader)
      {
       writer.AddResource(de.Key.ToString(),de.Value.ToString());
      }
      writer.Close();
    Friday, October 14, 2005 9:12 AM
  • User1183903743 posted
    That's very interesting.
    Are you using this code in a windows forms app or web app?

    If you look at the resheader of a resx it is a wrapper for these reader and writer classes. I presume resheader is for the IDE resource editor tool to use these two classes.

    <resheader name="reader">
       <
    value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
    </
    resheader>
    <
    resheader name="writer">
       <
    value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
    </
    resheader>

    What is worse is the System.Resources.Tools namespace is pretty worthless. I was on the verge of writing my own Xml based resource tool so I am very interested.

    Would you mind posting some FULL code?



    Friday, October 14, 2005 10:29 AM
  • User1424575140 posted
    Its in an asp.net app, but the code runs at design time. In windows forms there is much better support for resources during design. 


    That snippet is the functional part of the code; the chunk is just used to create the resource file for a culture if it is missing or if it has no items.  The rest of the code just performs the checks.

    I have some very complicated code to provide localization of web controls at design time. It serializes property values into the resource file in a way similar to windows forms. I'll have a look to see if there is something I can extract from it.

    I got the feeling that Localization and resources were one of the things that didn't quite get finished in 1.x there is a lot of stuff under the covers that almost works. If I remember correctly, many controls use the Serializable attribute, but the system doesn't seem to use them.

    Friday, October 14, 2005 2:34 PM
  • User1183903743 posted
    v2.0 localizations is much nicer and I am talking about that. As a factoid the resx schema is unchanged so it should work in v2.0.

    I think the design tools are still unfinished even in v2.0.

    See if you have a tip for this:
    http://forums.asp.net/1080443/ShowPost.aspx

    I couldn't get any response and couldn't google up anything so I sat down to do my own and the code is quickly balooning to several thousand lines.

    TIA

    Rob
    Friday, October 14, 2005 4:46 PM
  • User1424575140 posted

    I load the resources into a hash table, manipulate the hashtable and then write the resource back out.

    These methods are from a utility class, they don't use all the usings, but better too many than none ;)

     using System.ComponentModel.Design.Serialization;
    using System;
    using System.CodeDom;
    using System.Collections;
    using System.Web.UI;
     using System.Web.UI.Design;
     using System.Web.UI.WebControls;
     using System.Web.UI.Design.WebControls;
     using System.Globalization;
     using System.ComponentModel;

     using System.ComponentModel.Design;
     using System.Drawing.Design;
    using System.Resources;

      private Hashtable ReadResource(CultureInfo cultureInfo)
      {
       //Utilities.MsgBox("ReadResource " + cultureInfo.Name);
       IResourceService resourceService = (IResourceService)Site.GetService(typeof(IResourceService));
       IResourceReader reader=  resourceService.GetResourceReader(cultureInfo);

       Hashtable source = new Hashtable();
       foreach(DictionaryEntry item in reader)
       {
        source.Add(item.Key,item.Value);
       }
       return source;//(Hashtable)savedHashTable[key];
      }

      public void SynchUpdateResx2(string memberLocalizationItemName,object newValue)
       {
       

       Hashtable source = ReadResource(DesignTimeCulture);
       
       if(memberLocalizationItemName.Length!=0
        &&
        !source.ContainsKey(memberLocalizationItemName))
       {
        source.Add(memberLocalizationItemName,newValue);
       }
       IResourceWriter writer = Util.GetResourceWriter(DesignTimeCulture);
       foreach(DictionaryEntry item in source)
       {
         if(item.Key.ToString() == memberLocalizationItemName)//TypedComponent.TextLocalizationItemName)
         {
          writer.AddResource(item.Key.ToString(),newValue);
         }

         else
         {
          writer.AddResource(item.Key.ToString(),item.Value);
         }
       }
       writer.Close();
      }

    Friday, October 14, 2005 6:09 PM
  • User1183903743 posted
    Thanks,

    I have a deadline but I wil look at it asap.
    Saturday, October 15, 2005 1:12 PM
  • User1183903743 posted
    Would you mind spoon-feeding me a tad?

    I follow the manipulations in memory via the hashtable.

    However I am not clear about these two.

    Site.GetService(typeof(IResourceService));

    Util.GetResourceWriter(DesignTimeCulture);



    How do you start from a file ~/App_GlobalResources/MyRes.resx
    which has say two pairs "key1"="Hello", "key2"="World"
    and add  "key3"="Eureka" in MyRes.resx

    How do yo start whole new resx ~/App_GlobalResources/Folder/MyRes2.resx ,say with the same 3 keys but blank values?

    I can figure out the rest about uniqeness etc.

    BTW an ordered set would perform much faster, not that it matters at design time.

    Saturday, October 15, 2005 7:10 PM
  • User1424575140 posted
    The components all have a a Site property that provides access to the context.
    http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodelcomponentclasssitetopic.asp?frame=true

    http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelComponentClassGetServiceTopic.asp?frame=true

    For the design time culture, I've got a blog entry about getting config values at design time. http://weblogs.asp.net/andrewseven/archive/2004/09/08/WebConfigDesignTime.aspx

    Oops on Util.GetResourceWriter it actualy didn't do much:
    IResourceService resourceService = (IResourceService)Site.GetService(typeof(IResourceService));
    IResourceWriter writer = resourceService.GetResourceWriter(DesignTimeCulture);

    You should be able to create the files with a ResxWriter, it takes a filename in the construtor. I copy the entries "by hand" from one culture reader to annother culture writer. http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemResourcesResXResourceWriterClassTopic.asp?frame=true 

    The doc has sample in the normal writer that mostly apply: http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemResourcesResourceWriterClassTopic.asp?frame=true






    Sunday, October 16, 2005 10:17 AM
  • User1183903743 posted
    Thanks for the link

    http://weblogs.asp.net/cnagel/archive/2003/07/06/9751.aspx

    It's a gem.

    I am doing exactly what he is but xml storage and trying as much as I can to duplicate the existing model.

    This kind of data is pretty static so it is perfect for xml.

    They could have easily done a db for it in v2.0, just like profile and personalization but they didn't and I agree.
    Monday, October 17, 2005 7:14 PM