I'm a VB.NET programmer, but I'm new to C# and now I'm working with C# project which uses local resource files (.resx).
Using VB.NET I can access to variables in resource file via My.Resources.< LocalResourceFile >.< MyVariable > . But in C# I can't find any alternatives for My namespace, but I still can access to resource if I replace My namespace with < MyProjectNamespace >.
Maybe there are any other way to access my local resources?
If you absolutely must use the equivalent of the My namespace, there is actually such a thing in C#. It is the Microsoft.VisualBasic.Devices.MyServices namespace. To use that, you must add a reference to Microsoft.VisualBasic.dll and add using Microsoft.VisualBasic.Devices; to your code file. For this route, see here: http://msdn.microsoft.com/en-us/library/ms173136.aspx
I would not, however recommend doing that. Instead, to access resources, you simply use MyNamespace.Properties.Resources like this:
namespace SomeNamespace
{
...
var myFile = SomeNamespace.Properties.Resources.MyFile;
...
}
You can do this which is virtually the equivalent:
Bitmap image = Properties.Resources.picture000;
It still works the same way, just don't put "My.Resources" in front of the name. So if you added a .resx file named "Resource1" and put a string named "Foo" in the resource then the variable name is "Resource1.Foo".
If you put code in non-default namespaces then you may have to prefix it with the default project namespace. Like "WindowsFormsApplication1.Resource1.Foo". If you are lost then just look at the auto-generated code. In the Solution Explorer window open the node next to the .resx file and double-click the Designer.cs file. Don't edit it.
There is no built-in My namespace, but you can reference Microsoft.VisualBasic.dll and have it.
Check out: http://msdn.microsoft.com/en-us/library/ms173136(v=vs.80).aspx
Related
I have some scripts stored in files that I've marked as Embedded Resource. I nest each of these files under their associated .cs file. Unfortunately, for some reason, when you nest a file this way, the embedded resource name loses the file extension. This means that at runtime I have no way to identify which embedded resources are or aren't scripts. What can I do about this?
One thing I tried that did not work: getting the ManifestResourceInfo object, which has a FileName property. Unfortunately this property is null.
Another thing I tried was doubling up the extension. (like: filename.ext.ext). This didn't work, and everything after the first . is still missing.
I tried naming the resource with something very different, and noticed that the resource name didn't even change. It seems that it is generating the resource name for a nested embedded resource file based off of the "dependent upon" file, which in this case is just a regular .cs file. I tried doubling the extension of the .cs file to filename.extrastuff.cs but the resource name still doesn't change. It insists on clipping everything after the first ..
No, ok, I see now that it is actually naming the resource after the type defined in the .cs file, not the filename of either file. This is why the extension makes no difference. This means there is nothing I can do to either filename to help find the resource.
I discovered that the reason the file loses its extension is because for some reason when the file is nested, VS is naming the resource after the type instead of after the file.
The only thing I've found to allow me to still have an extension when nesting is to manually edit the .csproj file and add a LogicalName tag, which allows you to override the resource name.
<EmbeddedResource Include="Path\To\NestedFile.ext">
<LogicalName>NestedFile.ext</LogicalName>
<DependentUpon>ParentFile.cs</DependentUpon>
</EmbeddedResource>
Unfortunately, there is no IDE support for this, and the FileNesting extension I'm using doesn't support writing this tag either.
It's too cumbersome to have to do this for every file, so instead of relying on the file extension, I would have to do something like add an identifier inside my script files that identifies them as scripts.
Ultimately I realized that since in my case I'm validating script files from unit tests, I can simply scan the file system instead of the resource manifest and avoid this problem altogether.
I have a file I need to access at runtime, I've included it in my project and set it up as embedded resource (it's actually a source file, I changed the extension to .cs.txt to get around VS trying to compile it. That shouldn't matter, but I'm mentioning it anyway just in case).
When I try getting the file
var assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(resourceName);
I get a null. I've made sure I'm using the Namespace.Folder.Filename notation, but that didn't help. It appears the file is actually not there, because when I call
assembly.GetManifestResourceNames();
I get an empty string array. Any idea what could be the case?
I appreciate this is an old thread but what I found this morning might be useful to others.
I had a resource where the filename had multiple dots in it...
example filename: data.txt.dat
var resources = asm.GetManifestResourceNames(); // None found (empty array)
renamed to data.txt (still just an embedded resource in the project configuration
var resources = asm.GetManifestResourceNames(); // Entry found ("Assembly.Namespace.data.txt")
So maybe there is some limitation around multiple . characters in the name
So I got around this by using the VS resource manager. Now I can access the file directly like this:
MyNamespace.Properties.Resources.MyFile
I'd recommend this approach to anyone, as it seems not only much cleaner, but safer as well. Thanks Hans Passant for the advice.
Based on this pull request (https://github.com/dotnet/msbuild/pull/5824) you can add WithCulture="false" in your csproj on your EmbeddedResource tag :
<EmbeddedResource Include="a.cs.b" WithCulture="false"/>
It is working for me
Is there any way to add a file to an application's resources using code (not the visual designer)? I've tried the ResourceWriter class but it doesn't do what I want.
The ResourceManager class is only used for getting resources. If you want to add or edit resources, see the MSDN page on Adding and Editing Resources, or look at the Resource File Generator for dynamically creating resource files.
Edit: The ResourceWriter class will probably do what you want, too... did you read the remarks on how to use it? Generating resource files is simple, you would just have to programatically insert them into your project if that's where you wanted them ultimately.
I am experiencing some weird behavior of Visual Studio 2010 when developing Silverlight applications and using project resources (.resx)
Everytime I change a resource it sets itself to internal instead of public in the code behind, altough I can see it in the design mode as set to public it is not.
Any idea how to fix this?
I don't know if this affects only Silverlight projects or generaly all C# projects.
This link might help.
http://blogs.msdn.com/b/silverlight_sdk/archive/2010/09/08/ach-du-lieber-a-tour-of-some-localization-gotchas-in-silverlight.aspx
It says:
Turns out there's a flaw in the VS
build action logic here; unfortunately
changing this tool action will NOT
flip the access level of the class
constructor from internal to public
(at least not for a strongly typed
language). A public constructor is
another requirement of Silverlight
XAML usage of a class. You will have
to do this yourself manually in the
designer.cs file.
Hope this helps
EDIT:-
Here's another one http://www.wintellect.com/CS/blogs/jprosise/archive/2010/06/21/dynamic-localization-in-silverlight.aspx that says
Finally, Visual Studio suffers from a
long-standing bug that leaves the
constructor of the ResourceManager
wrapper class it generates marked
internal when you change the class's
access modifier to public. This means
that whenever you modify the primary
RESX file, forcing a code regen, you
have to manually change internal to
public on the constructor in the
generated code. It beats me why this
hasn't been fixed after all these
years, but it hasn't.
My approach consists in configuring a pre-build event that replaces "internal" with "public" in your .Designer.cs file. I have a post on my blog about the whole process, from creating the localized string to binding them and configuring the pre-build event command line.
The hearth of the process is to get a text-file replace utility (say it's called REPLACE.EXE) and set a pre-build action like this:
c:\utility\replace\replace.exe "$(ProjectDir)\LocalizedStrings.Designer.cs" "internal" "public"
$(ProjectDir) is a VS built-in macro that returns the path to your project folder.
I also gave an example of such a simple replace utility source code on same post.
The best solution is to switch the tool used to generate the resource code behind .cs file to one the automatically outputs the constructor as public instead of internal. The best one I have found is from Guy Smith-Ferrier. Download and run the installer and then change the "Custom Tool" property of your .resx resource file to "PublicResourceCodeGenerator".
Workaround:
Inherit another class from the generated one
public class TextRes2 : TextRes
{
public TextRes2() { }
}
and use that instead of the original
<ResourceDictionary>
<!--res:TextRes x:Key="Strings" /-->
<res:TextRes2 x:Key="Strings" />
</ResourceDictionary>
There's a problem with all of these solutions - at least in our case.
Our resource files are all modified by a 3rd party codegen tool which updates the resource files to match the changes made in the UIs. All it does is update the strings in the xml. we still have to go in to the VS and toggle the Access Modifier from Public to something else, and back to Public so VS will synchronize the code-behind to match the new string values. THEN we have to update the c# by changing internal to public.
So for us, we need both steps automated, rebuilding the code behind and the fixing internal.
I googled and someone found the answer and linked but it was dead. How can i find a specific class in a specific file? The poster i found ask that question and found how to do it in a namespace but i would like to find one specific to a file. This question is to answer my other question but now that i thought of this i would like to know the answer.
Something like this?
string path = "INSERT PATH HERE";
var assembly = Assembly.LoadFile(path);
foreach (var type in assembly.GetTypes())
{
Debug.WriteLine(type.Name);
// do check for type here, depending on how you wish to query
}
I am not sure how the file name shall be stored as part of compiled assembly. Other option is that you can use the PDB file generated by the VS IDE to get the source file at some extension.
Here is some internals of pdb file.
http://www.informit.com/articles/article.aspx?p=22685
Once you can parse the file, you can use the symbol and look at the source definition.
I am glad to know other ways as well.
If you want to find the source code for a class, use the Go To Definition option in Visual Studio.
Once the code is compiled, it's not arranged in files, it's arranged in name spaces and assemblies. If it's at all possible to find out from which source file a class originated, you would have to loop through all classes and look for it.