How do I get resource file values in Visual Basic? - vb.net

I'm new to Visual Basic, and I'm having issues accessing the resource file for my project.
Dim rm As Resources.ResourceManager = New Resources.ResourceManager("MyProjectName.My.Resources.Resources", [Assembly].GetExecutingAssembly())
Dim myValue = rm.GetString(lookUpKey) 'boom Object reference not set to an instance of an object.
I think the issue is with the string "MyProjectName.My.Resources.Resources".
Would I be better off moving the strings into their own resource file?

I thought it was something similar to:
my.Resource.whateverhere
Is that not the kind of resources you are looking for?

Try
Global.<MyNamespace>.My.Resources.<ResourceStringName>
to access Resource Strings

Try ResourceManager("MyProjectName.Resources", ...), otherwise if it's the application resources you can simply use My.Resources.HD (see here:My.Resources Object)
or
Open Reflector, load your assembly there, go to resources, a list of resources appears, search for the one containg 'HD', copy the name (it's like MyProjectName.Resources.resources), remove the last .resources and try with that.

Refer to the MSDN article Retrieving Resources with the ResourceManager Class for naming convetions:
Dim myManager As New _
System.Resources.ResourceManager("ResourceNamespace.myResources", _
myAssembly)

If you load an external .resx file and want it to show up under intellisense My.Resources then you need to do 2 things.
First the file should be in the root of your project. Simply right click the project and do "Add Existing Item", and give it your .resx file. You should notice that there is no chevron to expand the resx file like your built-in resource file.
The last step is to highlight your resx file and go to the properties window. Under Custom Tool put "ResXFileCodeGenerator" and under the Custom Tool NameSpace put "My.Resources". You should now be able to programmatically access this resource under My.Resources.[name of the resx file].resource_item.

I was unable to access the resource file until I moved the .resx file into its own project and referenced that project from my main one. I also had to create a dummy class in that project so that it would compile into a DLL file.
The code for accessing the resource file is actually located in the generated Resource.resx.vb file.
I was able to access the resource file using the following code.
'Name of Class Library where I moved the resx file
Dim classLibraryName As String = "ResourceProj"
'Name of Resource File without the .resx suffix
Dim resourceFileName As String = "Mappings"
'Finding the assembly of the resx file, ResourceProjClass is a dummy class I created so that the dll would build.
Dim myAssembly As Assembly = GetType(ResourceProj.ResourceProjClass).Assembly
Dim rm As Resources.ResourceManager = Nothing
rm = New Resources.ResourceManager(classLibraryName & "." & resourceFileName, GetType(myAssembly)
Return rm.GetString(lookUpKey)

Simply:
Dim loginMessage As String = Global.Resources.NameOfYourResxFile.NameOFVariable

Related

VB.NET open a Text File within the same folder as my Forms without writing Full Path

I found a similar question but it was 5 years 8 months old, had 2 replies and neither worked for me (VB.Net Read txt file from current directory)
My issue is that when I use the following code:
Dim fileReader As String
fileReader = My.Computer.FileSystem.ReadAllText(Application.StartupPath & "\Username_And_Password_Raw.txt")
Dim usernameAndPassword = Split(fileReader, ",")
I get an error saying:
System.IO.FileNotFoundException: 'Could not find file 'C:\Users\wubsy\source\repos\NEA Stock Page System\NEA Stock Page System\bin\Debug\net6.0-windows\Username_And_Password_Raw.txt'.'
I have tried using all the different Applications.BLANKPath options I can find (ie; StartupPath, CommonAppDataPath, etc.) and they all return essentially the same error only with a different location.
This is the folder layout of my TXT File - I know it's a terrible, incredibly insecure and generally awful way of storing login information but this is just for a NEA so will never ever actually be used
This is the actual path of the TXT File if it helps
C:\Users\wubsy\source\repos\NEA Stock Page System\NEA Stock Page System\Username_And_Password_Raw.txt
The startup path is where your exe is located. That and all supporting files get copied to a binary directory when you compile in visual studio, in your case
C:\Users\wubsy\source\repos\NEA Stock Page System\NEA Stock Page System\bin\Debug\net6.0-windows
But what you're trying to do, reference the file where it sits in your solution, is probably not the best way to do it, and your code above will work (with a change, will mention later) if you change the properties of the file in the solution.
Right click on the file in the Solution Explorer Username_And_Password_Raw.txt, select Properties. Modify Copy to Output Directory to either Copy always / Copy if newer, depending on your requirement. Now that file will copy to the same directory your exe is in, and the code above should work.
Note, when creating a path, don't use string concatenation because you may have too many or too few \; use Path.Combine:
Dim filePath = Path.Combine(Application.StartupPath, "Username_And_Password_Raw.txt"
Dim fileContents = My.Computer.FileSystem.ReadAllText(filePath)

How can I copy resource files from my Visual Studio VB NET application onto the local system when it's executed?

I want to be able to copy resources I've compiled into the program to a location on the local machine where the application is run. Mostly a few DLLs that my program will not use, but others will (think Installer type of application).. But I can't find a way to reference the resources by path in order to do a File.Copy, for instance:
File.Copy(My.Resources.conversion, BinPath & "conversion.dll")
...tells me "Value of type 'Byte()' cannot be converted to 'String'". And I get why, obviously the first parameter needs to be a string path and not the resource itself. Is there a better way to copy resources or how can I obtain a reference path to the resource so I can use File.Copy?
For what it's worth, I've also tried
File.WriteAllBytes(BinPath & "conversion.dll", My.Resources.conversion)
...which "works" to copy it where I want it, but then I get errors when I try to call regsvr32 on the
new dll: "The module ... was loaded but the entry-point DLLRegisterServer was not found."
If there's a better way altogether, I'm open to any idea.
The following steps work for me:
Change the 'Build Action' of the dll in 'Resources' file to 'Embedded Resource'.
Use the following method to save resource file to disk.
Public Sub WriteResourceToFile(ByVal resourceName As String, ByVal fileName As String)
Using resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)
Using file = New FileStream(fileName, FileMode.Create, FileAccess.Write)
resource.CopyTo(file)
End Using
End Using
End Sub
Example of usage:
WriteResourceToFile("yournameSpace.conversion.dll", BinPath & "conversion.dll")

Embedding and referencing XML file in VB.NET project

In a VS2013 VB.NET WinForms project I need to include an XML file in the deployed application that will be read from and written to at run time.
I have the file as an embedded resource, and have "Copy Always" selected for output. The file name is "Settings.xml" and the resource name is Settings.
Looking at this example I did the following to reference it in my code:
Private xmlFile as XmlDocument ' In the general declaration area, before the Load event
xmlFile.LoadXml(My.Resources.Settings) ' In the Load event, in a Try/Catch
But I get an "Object reference not set to an instance of an object" on the second line.
In the code I plan on accessing the xml with something like this:
Dim xmlDoc as New XmlDocument
xmlDoc = xmlFile
I'm not sure yet how to save any changes I make, as initial attempts of something like xmlDoc.Save(xmlFile) didn't work.
What am I missing?
First of all, you need to use the constructor for xmlFile:
Private xmlFile As New XmlDocument
Then, all you need to do is use the resource name, i.e. "Settings.xml" if the resource is embedded:
xmlFile.LoadXml("Settings.xml")
You shouldn't even need to set the resource as "CopyAlways".

Can't save to embedded xml document

In a VB.NET project I have an xml document as an embedded resource. I am accessing it with
Private xmlFile as New XmlDocument()
in the General Declaration area. And then I am loading it in the form load method:
xmlFile.LoadXml(My.Resources.Settings)
In a method I'm finding specific nodes and updating them from user input:
'Dim xmlDoc as XmlDocument
'xmlDoc = xmlFile
Dim settingNodes As XmlNodeList = xmlFile.SelectNodes("//Program/ProgramTitle")
For Each setting As XmlNode In settingNodes
If setting.InnerText = title Then
setting.ParentNode.Item("ProgramSaveFolder").InnerText = programFolder
setting.ParentNode.Item("PrimaryBackupFolder").InnerText = primBackup
setting.ParentNode.Item("SecondaryBackupFolder").InnerText = secBackup
End If
Next
' Neither of these work
xmlFile.Save("Settings.txt")
'xmlDoc.Save("GameSettings.txt")
The xmlDoc code is from when I was led to believe at one point that it's not saving because xmlFile was in use (I've been trying a lot different things!).
But, as noted in the code, neither of those work. This is very similar to what I see all over for examples of how to do this, but when I run the program it doesn't change the file at all.
You cannot modify an embedded resource. You can include the XML file as content and it will appear in your build folder as a normal file that can be loaded and updated using the File.IO namespace or XMLDocument.Load().
One catch to look out for is that a file in the Program Files folder being modified will require administrator rights which a user may not have. If this is the case, it's best to copy the file to the AppData folder.

How do I get a text file to be a part of my build?

I wrote a program that reads from text files and can create them to load and save data. I have a few files that are the "default" data that are loaded as soon as the program start. The files are loaded by a static reference. My code runs fine before I publish it, but obviously when I publish it, the static references no longer work. I don't know how to add the default data to the build as distinct text files so that I can still reference it after the build.
I imagine being able to build the program and have some sort of folder that accompanies the executable with the default data files in them that I can easily reference, but I don't know how to do that (or if there is a better way).
Below is the start of the code I use to read from the file. Currently, the default data's file name is passed statically into the sub and is used to identify the file to read from, so I'd like to have a published file that I can do the same thing with.
Try
Dim sr As New IO.StreamReader(FileName)
Dim strLine As String = ""
Do Until sr.EndOfStream
strLine = sr.ReadLine
'Code that interprets the data in the file
Note: I've tried adding the files as "Resources" but I can't seem to reference the file as a text file; I can only retrieve the massive wall of text contained within the document which won't work with the above code (unless of course I'm missing something).
If you could clarify:
How do I add a file to a build so that I can still access it
collectively by a file name?
How will my code reference the files (e.g. by
"My.Resources.filename"?) in the final build?
You can add the file to the build as either a content file or an embedded resource.
For a content file, set the Build Action of the file to 'content', and Copy to Output Directory to 'Copy Always' in the file properties. You can then access the file like this:
FileName = Application.StartupPath() = + FileName
Dim sr As New IO.StreamReader(FileName)
...
To embed the file as a resource you have to set the Build Action of the file to 'Embedded Resource' and Copy to Output Directory to false.
This Microsoft support page has a walkthough about accessing embedded resources. The code would be something like this:
Dim sr As StreamReader
Dim thisAssembly As Assembly
thisAssembly = Assembly.GetExecutingAssembly()
sr = New StreamReader(thisAssembly.GetManifestResourceStream("NameSpace." + FileName))
Dim strLine As String = ""
Do Until sr.EndOfStream
strLine = sr.ReadLine
'Code that interprets the data in the file
...
Replace NameSpace with the namespace of your application (Project Properties -> Application -> root namespace)
You also have to add Imports System.Reflection at the top of your code file.
Using an embedded resource has the advantage of less files to manage, and you don't have to keep track of paths.