Loading files in default Internet browser programmatically - c#

I used this to load a file (html_file.html) from Resources
//string myFile = "C:\\Users\\...\\Resources\\html_file.html"; // this works
var myFile = Path.GetFullPath("html_file.html"); // this doesn't works
//myFile = myFile.ToString();
//myFile = myFile.Replace(#"\", #"\\");
//MessageBox.Show(myFile);
try
{
Process.Start(myFile);
}
catch (Win32Exception noBrowser)
{
if (noBrowser.ErrorCode == -2147467259)
MessageBox.Show(noBrowser.Message);
}
catch (System.Exception other)
{
MessageBox.Show(other.Message);
}
Can someone tell me what's wrong?
EDIT : This works
Build Action = Embedded Resource and Copy to Output Directory = Copy always
string myFile = #".\Resources\html_file.html";
but I still need to have the path Resources with the file. Is there any way to have the 'html_file' inside my .EXE file?

Quite obviously it cannot find the file in the current directory. Make sure the following are correct:
The file is included in your project and its Copy to Output Directory property is set to Copy always or Copy if newer.
Use Application.StartupPath to make sure you are pointing to correct directory, so the first line would become:
Code:
var myFile = Path.Combine(Application.StartupPath, "html_file.html");

In the first method you specify the exact path to your file.
In the second one you ask the framework to create a fullpath.
The framework need to start from somewhere and it choose to start from your current directory but the file is not present there

Related

How to get path of a specific folder inside solution

I want to get the path of a specific folder inside the solution.
Ive tried to find answers on stack overflow, but i guess my concentration is already near the end and i cant find a real usefull answer.
Here is the folder i want (KeePassFiles):
I had those 2 files on the desktop before and reading them worked. But now i have to add those files into one of the solution folder and i only want to get the path for that.
It should work for different users who download that project.
My code right now for the desktop solution is:
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var dbpath = #$"{desktopPath}\KeePassDatabase\Database.kdbx";
var keypath = #$"{desktopPath}\KeePassDatabase\Database.key";
Now it should be something like:
string solutionKPPath = Environment.GetFolderPath(path for solution);
var dbpath = #$"{solutionKPPath}\KeePassFiles\Database.kdbx";
var keypath = #$"{solutionKPPath}\KeePassFiles\Database.key";
Environment.CurrentDirectory will return the Debug directory or the Release directory depending on your run configuration. As far as I know, there is no easy way to get a specific folder or file in your solution. The best solution I could think of is using something like the following to get the solution directory:
public static DirectoryInfo TryGetSolutionDirectoryInfo(string currentPath = null)
{
var directory = new DirectoryInfo(
currentPath ?? Directory.GetCurrentDirectory());
while (directory != null && !directory.GetFiles("*.sln").Any())
{
directory = directory.Parent;
}
return directory;
}
And then use that path to dig into your folders and find the specific file you're looking for using something like Path.Combine(...).
In your case, don't pass any parameters to this method if you want it to retrieve the Debug/Release directory and search up from there
Edit: Note that this will actually not work for production since there will be no .sln file to find. As suggested by the comments on your question, you should configure your project to copy the necessary files into the output folder and therefore Environment.CurrentDirectory will do the trick
I think you should not get the files from the project source, you should copy them to the output during build and then get them from output location.
I would recommend to use "Copy to Output directory= Copy Allways" and than identify the "Execution Path" by use of AppDomain.CurrentDomain.BaseDirectory or Assembly.GetEntryAssembly().Location
If you using Unit Test, especially MS UnitTests it may be necessary to use `[DeploymentItem(#"\Shared\Keepassfiles\Database.kdbx")]

How can i replace path with file name?

Hello i have to finish school project after another student.
And in whole program he used absolute path to file, the problem is it only works at one computer. Cuz this path is unique.
Could anybody tell me how can i replace this path just with file name?
string content = File.ReadAllText(filePath);
this.DocumentXml = XDocument.Parse(content);
this.xmlInfo = XDocument.Parse(content);
var groups = this.DocumentXml.Root.Elements("group");
foreach (var group in groups)
{
checkedListBox1.Items.Add(group.Attribute("name").Value);
}
// Adding data from your DNSFile to dataGridView1
hostsDataSet.Clear();
hostsDataSet.ReadXml(filePath);
dataGridView1.DataSource = hostsDataSet;
dataGridView1.DataMember = "item";
In this case "filepath" is text file with absolute path with file that he used.
Can you help me?
This is whole path to the file, that i create with Application.LocalUserAppDataPath: C:\Users\praktykant1\AppData\Local\WindowsFormsApplication1\WindowsFormsApplication1\1.0.0.0\test.txt
Problem in my case is that i have to create file that i use in program in AppData/Local folder.So on every computer the path will be different. And this program must work on every computer. Im just beginner so i am green in this subject.
This is precisely what config files are for... differences between environments in which the same code might execute.
Presumably the problem is that filePath is hard-coded, yes? Something like this?:
var filePath = #"c:\some\path\to\a\file.xml";
Instead, make that a configuration value. First add an entry to the App.config (or Web.config if this is a web application) in the appSettings node:
<appSettings>
<add key="filePath" value="c:\some\path\to\a\file.xml" />
<!-- any other settings already in place... -->
</appSettings>
Then use ConfigurationManager to get that setting. (You may need to add a reference to the System.Configuration assembly in the project.) Something like this:
var filePath = ConfigurationManager.AppSettings["filePath"];
You might also perform some error checking to make sure there's a value there at all (make sure filePath doesn't end up as a null or empty string, that is), make sure the file exists, etc.
At this point you can change the value in the config file without having to re-compile the code. So any new environment can set the config setting and use the application.
To get the file name of a path, just do this.
For example if your path is "C:\hello.txt", it becomes "hello.txt"
string fileName = Path.GetFileName(filepath);
If you do not like your file name to have any extensions
string fileNameNoEx = Path.GetFileNameWithoutExtension(fileName);
That way it becomes "hello"
If you set the variable filepath to be just the filename - it would look for this file in the directory where the executable file was started from (by default). This is called the working directory and you can find how to change the working directory online.
If you want to avoid using a full (or relative) path and just use the filename - expect it to be in that working directory.
In case of ASP.net you can do this,
if(FileUploadControl.HasFile)
{
try
{
string filename = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(Server.MapPath("~/") + filename);
StatusLabel.Text = "Upload status: File uploaded!";
}
catch(Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
}

Checking if resource file exists

I have an image file in my project's folder in visual studio and it is set to build action "resource" so it is included in my exe file.
I can link to this file in xaml no problem, for example <Image Source="images/myimage.png"> and it works.
But if I try to check the existence of the file, with File.exists("images/myimage.png") it always returns false. What am i doing wrong here?
If you do not want to have it bundled to the output folder additionally - you do not have to do anything. It is build into your exe, not need to check. Would always be true.
Okay, I understand because you dynamically build the name of your embedded resource you want to check it.
See here: WPF - check resource exists without structured exception handling
They basically check against Assembly.GetExecutingAssembly().GetManifestResourceNames()
You can use that as a starting point. But note that the resource name is not images/myimage.png but constructed from your namespace like YourApp.images.myimage.png. You might like to take a look at the contents of the built resourceNames array from that answer.
Xamarin.Forms
From a working code, checks if auto-generated filename exists in embedded resources in the shared project (as described here https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/#Embedded_Images)
var assembly = typeof(App).GetTypeInfo().Assembly;
var AssemblyName = assembly.GetName().Name;
var generatedFilename = AssemblyName+".Images.flags.flag_" + item.CountryCode?.ToLower() + #".png";
bool found = false;
foreach (var res in assembly.GetManifestResourceNames())
{
if (res == generatedFilename)
{
found = true;
break;
}
}
if (found)
UseGeneratedFilename();
else
UseSomeOtherPlaceholderImage;
Have you set the "Copy to the Output" property to "Always"? And make sure that you use the correct path. The path of your executing assembly can be detected by using following code:
private string GetExecutingAssemblyPath()
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
Cheers.

How to know which process will be fired by a certain file in c#

I would like to know which process will be fired before a file is started with:
Process.Start("PathToFile");
Then I would like to have the path to the process.
Thank you.
You can look at the MainModule property of the Process returned from Process.Start:
Process p = Process.Start(#"D:\\test.txt");
string executableStarted = p.MainModule.FileName; // full path to notepad.exe
However, you should remember that the return value from Proces.Start might be null - according to MSDN, the return value is:
A new Process component that is
associated with the process resource,
or null, if no process resource is
started (for example, if an existing
process is reused).
Update
In order to know the executable prior to launching the process, you will have to look under HKEY_CLASSES_ROOT in the registry. This would be the code for going from a file name to the command the shell will execute when opening the file:
string extension = Path.GetExtension(path);
var regClasses = Microsoft.Win32.Registry.ClassesRoot;
var extensionKey = regClasses.OpenSubKey(extension);
var typeKey = extensionKey.GetValue(String.Empty);
var cmdKey = regClasses.OpenSubKey(typeKey + #"\shell\open\command");
string command = cmdKey.GetValue(null) as string;
It returns a Process object containing more information. MainModule might be the right property for you.
http://msdn.microsoft.com/en-US/library/system.diagnostics.process.mainmodule(v=VS.80).aspx
EDIT:
Do you want to know it before/without
starting the process? -Yes
You could lookup the registered file handler in the registry - for .doc, .txt, etc.
Documents that you want to use the windows file association to open
I found this link here that explains how to create a file association. This may help. Of course you'll need to read the registry. There are two formats that I know of.
Programs to which you don't know the path
The path environment variable is consulted after the current directory as default paths to look in when the path is not provided.
The Path environment variable can help you here.
public static string GetPath (string pathToFile)
{
string fileNameOnly = Path.GetFileName(pathToFile);
List<string> folders = Environment.GetEnvironmentVariable("Path").Split(';').ToList ();
folders.Insert(0, Environment.CurrentDirectory);
foreach (string folder in folders)
{
string fileName;
try
{
// Can't trust that the Path environment variable is constructed correctly.
fileName = Path.Combine(folder, fileNameOnly);
}
catch
{
continue;
}
if (File.Exists(fileName))
return fileName;
}
return null;
}
Edit: Added link to MS: path.
Edit: Added another link.

problem with opening a file in C#

What am I doing wrong in the following code?
public string ReadFromFile(string text)
{
string toReturn = "";
System.IO.FileStream stream = new System.IO.FileStream(text, System.IO.FileMode.Open);
System.IO.StreamReader reader = new System.IO.StreamReader(text);
toReturn = reader.ReadToEnd();
stream.Close();
return toReturn;
}
I put a text.txt file inside my bin\Debug folder and for some reason, each time when I enter this file name ("text.txt") I am getting an exception of System.IO.FileNotFoundException.
It is not safe to assume that the current working directory is identical to the directory in which your binary is residing. You can usually use code like the following to refer to the directory of your application:
string applicationDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
string filename = System.IO.Path.Combine(applicationDirectory, text);
This may or may not be a solution for your given problem. On a sidenote, text is not really a decent variable name for a filename.
If I want to open a file that is always in a folder relative to the application's startup path, I use:
Application.StartupPath
to simply get the startuppath, then I append the rest of the path (subfolders and or file name).
On a side note: in real life (i.e. in the end user's configuration) the location of a file you need to read is seldom relative to the applications startup path. Applications are usually installed in the Program Files folder, application data is stored elsewhere.
File.ReadAllText(path) does the same thing as your code. I would suggest using rooted path like "c:......\text.txt" instead of the relative path. The current directory is not necessarily set to your app's home directory.
You can use Process Monitor (successor to FileMon) to find out exactly what file your application tries to read.
My suggestions:
public string ReadFromFile(string fileName)
{
using(System.IO.FileStream stream = new System.IO.FileStream(fileName, System.IO.FileMode.Open))
using(System.IO.StreamReader reader = new System.IO.StreamReader(stream))
{
return = reader.ReadToEnd();
}
}
or even
string text = File.OpenText(fileName).ReadToEnd();
You can also check is file exists:
if(File.Exists(fileName))
{
// do something...
}
At last - maybe your text.txt file is open by other process and it can't be read at this moment.

Categories