How to make generated resource class public

If you create managed application in Visual Studio 2005, you will notice that a resource class is generated when you add resources to the resx file. The class makes getting resource values much easier.  But some are troubled because the class is generated as Internal, which blocks you to access it in another assembly.  For people who create one assembly specially for resources, it could be a problem.

It is a limitation of the current code generator within VS.  However, the command line tool resgen.exe (in the Framework SDK) does support you to create a public class from your resource file.

We want to do is to disable the default code generator in the VS. To do that, we need show all hidden files in the solution explorer (from the toolbar). Select the resx file, and clear the "Custom Tool" property of this item.  However, if we are using VB, for the default resource.resx under "My Project", the resource designer will add "Custom Tool" back when we open it.  We would have to create a new resource file to the project, and do not use the default resource file.

Now, after editing the resx file, we can bring up a command window, and run the resgen.exe with property option, we will get the generated code, and of course, need to add it to the project.  It will be pain to do that everytime you edit the file.  However, we can put this in the project file, so it will be done automatically when we build the project.

Just save the project, and open the project file in notepad. Edit the file carefully (and backup one in case we mess it up.)  Just add those to project file (It is a sample with csproj, we need change some for VB):

  <Target Name="BeforeBuild" DependsOnTargets="CreateStrongTypeResource"/>
  <Target Name="CreateStrongTypeResource" DependsOnTargets="GenStrongTypeResource" >
    <CreateItem Include="Properties\Resources.cs">
      <Output TaskParameter="Include" ItemName="Compile" />
  <Target Name="GenStrongTypeResource" Inputs="Properties\Resources.resx" Outputs="Properties\Resources.cs">
                PropertyName="SdkPath" />
   <Exec Command="&quot;$(SdkPath)\bin\resGen.exe&quot; /str:c# /publicClass Properties\Resources.resx"/>

Save the csproj file, and reload it in the Visual Studio. Now, we can change the resx file with the new resource designer in VS2005, and build it, the generated type will be built into the assembly.


Comments (9)

  1. Note: in VS next version, VS supports to generate public strong type resource class directly.

  2. The feature (PublicResXFileCodeGenerator) is broken in beta 1 product, because one setup registry item hasn’t been updated after a version number update.  However, it is easy to patch the machine by updating a few registry items.

    It is mentioned in the readme document of beta1:

    in 1.4.14 section said you need update a few registries:

    [HKEY_LOCAL_MACHINESOFTWAREMicrosoft%SKU%9.0CLSID{74d398e9-7cc3-4ff2-9a4d-acd177f40b58}] "InprocServer32"="C:\WINDOWS\system32\mscoree.dll" "Class"="Microsoft.VisualStudio.Design.Serialization.PublicVBMyResXFileCodeGenerator" "Assembly"="Microsoft.VisualStudio.Design, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" "ThreadingModel"="Both" @="Microsoft.VisualStudio.Design.Serialization.PublicVBMyResXFileCodeGenerator"

    [HKEY_LOCAL_MACHINESOFTWAREMicrosoft%SKU%9.0CLSID{69b6a86d-ef43-4d9e-a758-8a18b38a7384}] "InprocServer32"="C:\WINDOWS\system32\mscoree.dll" "Class"="Microsoft.VisualStudio.Design.Serialization.PublicResXFileCodeGenerator" "Assembly"="Microsoft.VisualStudio.Design, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" "ThreadingModel"="Both" @="Microsoft.VisualStudio.Design.Serialization.PublicResXFileCodeGenerator"

    The %SKU% here should be picked up to match what SKU (vb express, visual studio, or other express) you installed.  Check the registry with regedit, you know where to fix it.  The only thing has been changed is the version number of the full qualified assembly name.

  3. MonoRail – Collocate your Strings

  4. MonoRail – Collocate your Strings

  5. amit_chat says:

    I have tried the same thing but when I try to access the resource (from other project) by using that class it gives me following error..

    "Could not find any resources appropriate for the specified culture or the neutral culture.  Make sure "SocResources.resources" was correctly embedded or linked into assembly "Rules Prototype" at compile time, or that all the satellite assemblies required are loadable and fully signed."

    Is there something I am missing?

  6. First, ensure that "Build Action" of the resx is set to "Embedded Resource", so it will be embedded into the assembly.

    Second, well, if you are using VB, the code generated by the resGen.exe doesn’t work well when root namespace is set.  The problem is that VB compiler automatically add a root namespace to the class, while resGen doesn’t expect it.  If you open the generated code, see how it creates the resource manager, the resource name used there does not contain the root namespace.

    To workaround this, you can set root namespace of your resource assembly to be empty.  Or, you can edit the project file again to ensure that the logicName of the resource item does not contain the rootNamespace.

    It would look like:

       <EmbeddedResource Include="Resource1.resx" >




    after you change it.

    Hope this could resolve your problem.

    BTW, generating public resource classes is working in Orcas beta 2.  

  7. snowjim says:


    I have some problems to implement this fine solution of yours.

    I have created a couple of resx files and I am have set them up as you have stated.

    The cs file are created on build but it is not included into the project?

    No errors are thrown on build!?

    This is how my project file looks like:

    <Import Project="$(MSBuildBinPath)Microsoft.CSharp.targets" />

     <!– To modify your build process, add your task inside one of the targets below and uncomment it.

          Other similar extension points exist, see Microsoft.Common.targets.–>

     <Target Name="BeforeBuild" DependsOnTargets="CreateStrongTypeResource" />

     <Target Name="CreateStrongTypeResource" DependsOnTargets="GenStrongTypeResource">

       <CreateItem Include="GUI.cs">

         <Output TaskParameter="Include" ItemName="Compile" />



     <Target Name="GenStrongTypeResource" Inputs="GUI.resx" Outputs="GUI.cs">


         <Output TaskParameter="Path" PropertyName="SdkPath" />


       <Exec Command="&quot;$(SdkPath)binresGen.exe&quot; /str:c# /publicClass GUI.resx" />



     <Target Name="AfterBuild">



    The resx file I am testing is GUI.resx

    This project are Teamfoundation sourcesafe controled.

    I have a reference from another project to this resx project but there is no namespaces or resources to get!?

    What have i missed?

  8. With those changes, the GUI class will be generated without any namespace, so you couldn’t see it in the default namespace of the class library. In that case, you want to change the command line to be:

      <Exec Command="&quot;$(SdkPath)binresGen.exe&quot; /str:c#,ClassLibrary1 /publicClass GUI.resx" />

    That also saves you time, so you don’t have to change the logicName of the resource item.

    You don’t need do this in a VB project, because the compiler will apply default namespace automatically. That is however, not done in C# projects.

  9. Generating public class is not directly supported in the Visual Studio 2008.  To enable this function, open the resource designer, and on the top of the designer(right side), "Access Modifier" will allow you to select whether to generate a public class.

    This function will resolve the most problem we talked here, so editing the project file is no longer needed.

Skip to main content