How to read a text file in project's root directory? - c#

I want to read the first line of a text file that I added to the root directory of my project. Meaning, my solution explorer is showing the .txt file along side my .cs files in my project.
So, I tried to do:
TextReader tr = new StreamReader(#"myfile.txt");
string myText = tr.ReadLine();
But this doesn't work since it's referring to the Bin Folder and my file isn't in there... How can I make this work? :/
Thanks

From Solution Explorer, right click on myfile.txt and choose "Properties"
From there, set the Build Action to content
and Copy to Output Directory to either Copy always or Copy if newer

You can use the following to get the root directory of a website project:
String FilePath;
FilePath = Server.MapPath("/MyWebSite");
Or you can get the base directory like so:
AppDomain.CurrentDomain.BaseDirectory

Add a Resource File to your project (Right Click Project->Properties->Resources). Where it says "strings", you can switch to be "files". Choose "Add Resource" and select your file.
You can now reference your file through the Properties.Resources collection.

private string _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
The method above will bring you something like this:
"C:\Users\myuser\Documents\Visual Studio 2015\Projects\myProjectNamespace\bin\Debug"
From here you can navigate backwards using System.IO.Directory.GetParent:
_filePath = Directory.GetParent(_filePath).FullName;
1 time will get you to \bin, 2 times will get you to \myProjectNamespace, so it would be like this:
_filePath = Directory.GetParent(Directory.GetParent(_filePath).FullName).FullName;
Well, now you have something like "C:\Users\myuser\Documents\Visual Studio 2015\Projects\myProjectNamespace", so just attach the final path to your fileName, for example:
_filePath += #"\myfile.txt";
TextReader tr = new StreamReader(_filePath);
Hope it helps.

You can have it embedded (build action set to Resource) as well, this is how to retrieve it from there:
private static UnmanagedMemoryStream GetResourceStream(string resName)
{
var assembly = Assembly.GetExecutingAssembly();
var strResources = assembly.GetName().Name + ".g.resources";
var rStream = assembly.GetManifestResourceStream(strResources);
var resourceReader = new ResourceReader(rStream);
var items = resourceReader.OfType<DictionaryEntry>();
var stream = items.First(x => (x.Key as string) == resName.ToLower()).Value;
return (UnmanagedMemoryStream)stream;
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
string resName = "Test.txt";
var file = GetResourceStream(resName);
using (var reader = new StreamReader(file))
{
var line = reader.ReadLine();
MessageBox.Show(line);
}
}
(Some code taken from this answer by Charles)

You have to use absolute path in this case. But if you set the CopyToOutputDirectory = CopyAlways, it will work as you are doing it.

In this code you access to root directory project:
string _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
then:
StreamReader r = new StreamReader(_filePath + "/cities2.json"))

Related

Creating parameter named text files C#

I have to create a directory and then a text file inside this directory with name come from parameter. E.g. _year is a parameter and I tried as:
var _root = "C:\\Users\\~\\DirichletProcessClustering\\Results";
var _clusterFilename = _year.ToString() + "cluster.txt";
var _path = Path.Combine(_root, _year.ToString(), _clusterFilename);
if(!Directory.Exists(_path))
{
Directory.CreateDirectory(_path);
}
// output topk file
TextWriter _twClus = File.CreateText(_path);
foreach (// loop )
{
_twClus.WriteLine("Cluster");
//... rest of the implementation...
}
This code is creating a folder named 2005 at specified path and then inside this folder, there is another folder named 2005cluster.txt while I want to create a text file named 2005cluster.txt inside folder 2005.
Where I am getting wrong in creating correct folder and file names?
An UnauthorizedAccessException generated at undermentioned line of
code i.e. access is denied. Why is this happening?
TextWriter _twClus = File.CreateText(_path);
Try this so that your path has a slash before the file name:
var _root = "C:\\Users\\~\\DirichletProcessClustering\\Results\\";
As you are defining fileName separately, You could try this:
var _root = "C:\\Users\\~\\DirichletProcessClustering\\Results";
var _clusterFilename = _year.ToString() + "cluster.txt";
var _path = Path.Combine(_root, _year.ToString());
if(!Directory.Exists(_path))
{
Directory.CreateDirectory(_path);
}
// output topk file
TextWriter _twClus = File.CreateText(Path.Combine(_path, _clusterFilename));
foreach (// loop )
{
_twClus.WriteLine("Cluster");
//... rest of the implementation...
}
Remove the file name from your path as:
var _path = Path.Combine(_root, _year.ToString());
For defining the filename you have to modify this line of code as:
TextWriter _twClus = File.CreateText(Path.Combine(_path, _clusterFilename));

Copying/over-writing one source to another in TFS?

Question Background:
Within my TF Server I have two folders, one is a simple 'HelloWorld.sln' in a folder called 'HelloWorldDev' and the other is a 'HelloWorld.sln' in a folder called 'HelloWorldQA'. Each folder contains its respective .cs files etc.
I want to checkout a file from the HelloWorld QA folder, replace - or update it - with a version from the HelloWorldDev folder with the same file name, then check this file back into the HelloWorldQA folder with the relevant changes.
Question:
I am very new to the TFS API so I'm not 100% if what I'm trying to ask is the correct way to proceed, or if its even possible. Can someone give me an example of achieving this?
Code so far:
string fileName = #"C:\Users\Me\Documents\TfsServer\HelloWorldQA\IHelloWorld.cs";
string fileNameQA = #"C:\Users\Me\Documents\TfsServer\HelloWorld\IHelloWorld.cs";
string uri = #"https://tfsServer.visualstudio.com/";
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
FileInfo fi = new FileInfo(fileName);
var workspaceInfoQA = Workstation.Current.GetLocalWorkspaceInfo(fileNameQA);
var serverQA = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspaceQA = workspaceInfo.GetWorkspace(serverQA);
workspace.PendEdit(fileNameQA);
FileInfo fiQA = new FileInfo(fileNameQA);
First, instead of using 2 workspaces, you can simply map both folders in the same workspace.
Then you're looking for a merge operation:
var sourcePath = workspace.GetServerItemForLocalItem(fileName);
var targetPath = workspace.GetServerItemForLocalItem(fileNameQA);
var getStatus = workspace.Merge(sourcePath, targetPath, null, null);
if (getStatus.NumUpdated > 0)
{
//OK
}

Accessing Resources in a C# WPF Application (Same Assembly)

(Before I jump into the nitty-gritty, I want to set the context: I'm trying to load a WPF frame with the contents of an .html file that I'm including in my project as a resource.)
I create a new WPF Application; I add a new folder called 'foofiles' to the project, and I add a couple of files (page1.foo and page2.foo) to that folder.
For each newly added .foo file, I right-click on it, go to "Properties," and set the Build Action to 'Resource,' and the Copy To Output Directory to "Copy always."
I want to be able to access those files both in XAML:
<Frame x:Name="bar" Source="/foofiles/page1.foo"/>
And in procedural code:
private void someFunc()
{
bar.Source = new Uri("/foofiles/page1.foo");
}
But I just can't figure out why this doesn't work -- I get a "Format of the URI could not be determined."
In the code-behind, I tried doing this:
private void someFunc()
{
bar.Source = new Uri("pack://application:,,,/foofiles/page1.foo");
}
which didn't throw an exception, but my main window crashed.
In my thinking, if I add a file of any type to my project, and if I mark it as "Resource" in "Build Action," I should be able to use that file per my examples above. Also, I would like to use that file like this:
private void someOtherFunc()
{
System.IO.StreamReader reader = new System.IO.StreamReader("/foofiles/page1.foo");
string bar = reader.ReadToEnd();
}
Any help would be appreciated... thanks in advance!
Try adding the component-part to your Pack URI like this
pack://application:,,,/AssemblyName;component/ResourceName
where AssemblyName is the name of your assembly. So for your case, the following statement should work:
bar.Source = new Uri("pack://application:,,,/AssemblyName;component/foofiles/page1.foo");
More practically, try the relative pack uri notation:
bar.Source = new Uri("AssemblyName;component/foofiles/page1.foo", UriKind.Relative));
For stream reading resources use
var streamResourceInfo = Application.GetResourceStream(uri);
using (var stream = streamResourceInfo.Stream)
{
// do fancy stuff with stream
}

Create designer.cs file from ResXRersourcewriter generated resource file

I got a programm that generates .resx resource files. Those resource files are used in other projects, that isnt in the same solution as the project that generates the resource files.
I wonder now, if its possible to generate a designer.cs file from the resource file, so that you can access the resources directly without using the resxresourcereader.
Open the resx file and on its toolbar there's an Access Modifier menu. Set this to Public. This will generate a *.Designer.cs file.
Right click on the Resources.resx and select "Run Custom Tool".
If the file is added to a Visual Studio Project you have to set the Custom Tool property of the .resx file to ResXFileCodeGenerator. Then will VS automatically create the needed designer file.
In one project I made a T4 script that scans the folder within the project for all images and let create a corresponding ressource file at a click.
Here is the needed part out of the T4 script:
var rootPath = Path.GetDirectoryName(this.Host.TemplateFile);
var imagesPath = Path.Combine(rootPath, "Images");
var resourcesPath = Path.Combine(rootPath, "Resources");
var pictures = Directory.GetFiles(imagesPath, "*.png", SearchOption.AllDirectories);
EnvDTE.DTE dte = (EnvDTE.DTE)((IServiceProvider)this.Host)
.GetService(typeof(EnvDTE.DTE));
EnvDTE.Projects projects = dte.Solution.Projects;
EnvDTE.Project iconProject = projects.Cast<EnvDTE.Project>().Where(p => p.Name == "Icons").Single();
EnvDTE.ProjectItem resourcesFolder = iconProject.ProjectItems.Cast<EnvDTE.ProjectItem>().Where(item => item.Name == "Resources").Single();
// Delete all existing resource files to avoid any conflicts.
foreach (var item in resourcesFolder.ProjectItems.Cast<EnvDTE.ProjectItem>())
{
item.Delete();
}
// Create the needed .resx file fore each picture.
foreach (var picture in pictures)
{
var resourceFilename = Path.GetFileNameWithoutExtension(picture) + ".resx";
var resourceFilePath = Path.Combine(resourcesPath, resourceFilename);
using (var writer = new ResXResourceWriter(resourceFilePath))
{
foreach (var picture in picturesByBitmapCollection)
{
writer.AddResource(picture.PictureName, new ResXFileRef(picture, typeof(Bitmap).AssemblyQualifiedName));
}
}
}
// Add the .resx file to the project and set the CustomTool property.
foreach (var resourceFile in Directory.GetFiles(resourcesPath, "*.resx"))
{
var createdItem = resourcesFolder.Collection.AddFromFile(resourceFile);
var allProperties = createdItem.Properties.Cast<EnvDTE.Property>().ToList();
createdItem.Properties.Item("CustomTool").Value = "ResXFileCodeGenerator";
}
I have flattened the above code a little bit, cause in my real solution i use a custom class for each picture instead of the simple filename to also support the same filename in different sub folders (by using a part of the folder structure for the namespace generation). But for a first shot the above should help you.
You can also do this in code:
(Taken from here: msdn)
StreamWriter sw = new StreamWriter(#".\DemoResources.cs");
string[] errors = null;
CSharpCodeProvider provider = new CSharpCodeProvider();
CodeCompileUnit code = StronglyTypedResourceBuilder.Create("Demo.resx", "DemoResources",
"DemoApp", provider,
false, out errors);
if (errors.Length > 0)
foreach (var error in errors)
Console.WriteLine(error);
provider.GenerateCodeFromCompileUnit(code, sw, new CodeGeneratorOptions());
sw.Close();
You need to reference system.design.dll
This also worked for me: double click and open the resx file, add a dummy resource, click save. the .designer.cs file is generated.
If you deleted it or added it to .gitignore because you thought you didn't need it. this is how you regenerate the file.
Go to the Access modifier and change it from (Public/Internal) to "No Code Generation"
Now put it back to Public/Internal.
VS will regenerate the Designer file for you.

read string from .resx file in C#

How to read the string from .resx file in c#? please send me guidelines . step by step
ResourceManager shouldn't be needed unless you're loading from an external resource.
For most things, say you've created a project (DLL, WinForms, whatever) you just use the project namespace, "Resources" and the resource identifier. eg:
Assuming a project namespace: UberSoft.WidgetPro
And your resx contains:
You can just use:
Ubersoft.WidgetPro.Properties.Resources.RESPONSE_SEARCH_WILFRED
This example is from the MSDN page on ResourceManager.GetString():
// Create a resource manager to retrieve resources.
ResourceManager rm = new ResourceManager("items", Assembly.GetExecutingAssembly());
// Retrieve the value of the string resource named "welcome".
// The resource manager will retrieve the value of the
// localized resource using the caller's current culture setting.
String str = rm.GetString("welcome");
Try this, works for me.. simple
Assume that your resource file name is "TestResource.resx", and you want to pass key dynamically then,
string resVal = TestResource.ResourceManager.GetString(dynamicKeyVal);
Add Namespace
using System.Resources;
Open .resx file and set "Access Modifier" to Public.
var <Variable Name> = Properties.Resources.<Resource Name>
Assuming the .resx file was added using Visual Studio under the project properties, there is an easier and less error prone way to access the string.
Expanding the .resx file in the Solution Explorer should show a .Designer.cs file.
When opened, the .Designer.cs file has a Properties namespace and an internal class. For this example assume the class is named Resources.
Accessing the string is then as easy as:
var resourceManager = JoshCodes.Core.Testing.Unit.Properties.Resources.ResourceManager;
var exampleXmlString = resourceManager.GetString("exampleXml");
Replace JoshCodes.Core.Testing.Unit with the project's default namespace.
Replace "exampleXml" with the name of your string resource.
Followed by #JeffH answer, I recommend to use typeof() than string assembly name.
var rm = new ResourceManager(typeof(YourAssembly.Properties.Resources));
string message = rm.GetString("NameOfKey", CultureInfo.CreateSpecificCulture("ja-JP"));
If for some reason you can't put your resources files in App_GlobalResources, then you can open resources files directly using ResXResourceReader or an XML Reader.
Here's sample code for using the ResXResourceReader:
public static string GetResourceString(string ResourceName, string strKey)
{
//Figure out the path to where your resource files are located.
//In this example, I'm figuring out the path to where a SharePoint feature directory is relative to a custom SharePoint layouts subdirectory.
string currentDirectory = Path.GetDirectoryName(HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"]));
string featureDirectory = Path.GetFullPath(currentDirectory + "\\..\\..\\..\\FEATURES\\FEATURENAME\\Resources");
//Look for files containing the name
List<string> resourceFileNameList = new List<string>();
DirectoryInfo resourceDir = new DirectoryInfo(featureDirectory);
var resourceFiles = resourceDir.GetFiles();
foreach (FileInfo fi in resourceFiles)
{
if (fi.Name.Length > ResourceName.Length+1 && fi.Name.ToLower().Substring(0,ResourceName.Length + 1) == ResourceName.ToLower()+".")
{
resourceFileNameList.Add(fi.Name);
}
}
if (resourceFileNameList.Count <= 0)
{ return ""; }
//Get the current culture
string strCulture = CultureInfo.CurrentCulture.Name;
string[] cultureStrings = strCulture.Split('-');
string strLanguageString = cultureStrings[0];
string strResourceFileName="";
string strDefaultFileName = resourceFileNameList[0];
foreach (string resFileName in resourceFileNameList)
{
if (resFileName.ToLower() == ResourceName.ToLower() + ".resx")
{
strDefaultFileName = resFileName;
}
if (resFileName.ToLower() == ResourceName.ToLower() + "."+strCulture.ToLower() + ".resx")
{
strResourceFileName = resFileName;
break;
}
else if (resFileName.ToLower() == ResourceName.ToLower() + "." + strLanguageString.ToLower() + ".resx")
{
strResourceFileName = resFileName;
break;
}
}
if (strResourceFileName == "")
{
strResourceFileName = strDefaultFileName;
}
//Use resx resource reader to read the file in.
//https://msdn.microsoft.com/en-us/library/system.resources.resxresourcereader.aspx
ResXResourceReader rsxr = new ResXResourceReader(featureDirectory + "\\"+ strResourceFileName);
//IDictionaryEnumerator idenumerator = rsxr.GetEnumerator();
foreach (DictionaryEntry d in rsxr)
{
if (d.Key.ToString().ToLower() == strKey.ToLower())
{
return d.Value.ToString();
}
}
return "";
}
I added the .resx file via Visual Studio. This created a designer.cs file with properties to immediately return the value of any key I wanted. For example, this is some auto-generated code from the designer file.
/// <summary>
/// Looks up a localized string similar to When creating a Commissioning change request, you must select valid Assignees, a Type, a Component, and at least one (1) affected unit..
/// </summary>
public static string MyErrorMessage {
get {
return ResourceManager.GetString("MyErrorMessage", resourceCulture);
}
}
That way, I was able to simply do:
string message = Errors.MyErrorMessage;
Where Errors is the Errors.resx file created through Visual Studio and MyErrorMessage is the key.
Once you add a resource (Name: ResourceName and Value: ResourceValue) to the solution/assembly, you could simply use "Properties.Resources.ResourceName" to get the required resource.
I added my resource file to my project directly, and so I was able to access the strings inside just fine with the resx file name.
Example: in Resource1.resx, key "resourceKey" -> string "dataString".
To get the string "dataString", I just put Resource1.resourceKey.
There may be reasons not to do this that I don't know about, but it worked for me.
The easiest way to do this is:
Create an App_GlobalResources system folder and add a resource file to it e.g. Messages.resx
Create your entries in the resource file e.g. ErrorMsg = This is an error.
Then to access that entry: string errormsg = Resources.Messages.ErrorMsg
The Simplest Way to get value from resource file.
Add Resource file in the project.
Now get the string where you want to add like in my case it was text block(SilverLight).
No need to add any namespace also.Its working fine in my case
txtStatus.Text = Constants.RefractionUpdateMessage;
Constants is my resource file name in the project.
Create a resource manager to retrieve resources.
ResourceManager rm = new ResourceManager("param1",Assembly.GetExecutingAssembly());
String str = rm.GetString("param2");
param1 = "AssemblyName.ResourceFolderName.ResourceFileName"
param2 = name of the string to be retrieved from the resource file
This works for me.
say you have a strings.resx file with string ok in it. to read it
String varOk = My.Resources.strings.ok
ResourceFileName.ResourceManager.GetString(ResourceFileName.Name)
2.return Resource.ResponseMsgSuccess;

Categories