StartupPath not taking 9 characters off in c# - c#

i am currently trying to redirect a path to save an image in a folder.
The Startup path is:
C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication\bin\Debug
I am trying to change it so its like:
C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication
The code i am currently using is:
private void browseBtn_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
//open directory
open.Filter = "JPG Files (*.jpg)|*.jpg|PNG Files (*.png)|*.png|ALL Files (*.*)|*.*";
open.FilterIndex = 1;
if(open.ShowDialog() == DialogResult.OK)
{
if(open.CheckFileExists)
{
string paths = Application.StartupPath.Substring(0, (Application.StartupPath.Length - 10));
System.IO.File.Copy(open.FileName, paths + "\\Images\\sss.jpg");
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Any help or ideas on the matter? why isnt it taking off the characters so i can use images as the path

There is nothing wrong with your code:
string source =
#"C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication\bin\Debug";
string path = source.Substring(0, source.Length - 10);
Console.WriteLine(path);
//resulting in C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication
....If:
You build the project as "Debug", not "Release"
The image directory and the sss.jpg image do exist.
But the way to get the path the way you do now is just... unsafe (at the very least). Try to use Path.Combine and string.Split("\\") instead:
string source = #"C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication\bin\Debug";
string[] items = source.Split('\\');
string path = Path.Combine(string.Join("\\", items.Take(items.Length - 2)), "Images\\sss.jpg");

It seems, that you actually want to cut 2 subdirectories off and then combine with \Images\sss.jpg:
String source =
#"C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication\bin\Debug";
String[] items = source.Split(new Char[] {
Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
String path = String.Join(
Path.DirectorySeparatorChar.ToString(), items.Take(items.Length - 2));
String result = Path.Combine(path, #"Images\sss.jpg");

There's nothing wrong with your code and should work just fine so long as the Images directory exists. Just use
if (!Directory.Exists(Path.Combine(path, "Images")))
Directory.Create(Path.Combine(path, "Images")))

Is there any reason not to just leverage DirectoryInfo? It looks like you just want to go up two directories. You should be able to use DirectoryInfo.Parent to get the path you need without needing to do string manipulation.
DirectoryInfo startupDirectory = new DirectoryInfo(Application.StartupPath);
DirectoryInfo twoDirectoriesUp = startupDirectory.Parent.Parent;
string fullDirectoryName = twoDirectoriesUp.FullName;

Related

How can I access a local folder inside a WPF project to load and store files?

I need a library of vector files, where the same files have to be used every time. I want to load them from a folder and have the option to store new ones.
I tried having a library folder inside the WPF project that contains the files:
Solution/Project/Library/file1.dxf
I load them like this:
string currentDir = Directory.GetCurrentDirectory();
var cutOff = currentDir.LastIndexOf(#"\bin\");
var folder = currentDir.Substring(0, cutOff) + #"\Library\";
string[] filePaths = Directory.GetFiles(folder, "*.dxf");
This worked when running on the PC the project was buid, but the program crashes when the .exe is run on another PC. How do I fix this or is there a better approach to this?
Create a subfolder under Environment.SpecialFolder.ApplicationData, read the files in the library folder if it exists. If not create it and save the existing library files to it (here from resources):
string appFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = appFolder + #"\MyAppLibrary\";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
// Add existing files to that folder
var rm = Properties.Resources.ResourceManager;
var resSet = rm.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (var res in resSet)
{
var entry = ((DictionaryEntry)res);
var name = (string)entry.Key;
var file = (byte[])rm.GetObject(name);
var filePath = path + name + ".dxf";
File.WriteAllBytes(filePath, file);
}
}
// Load all files from the library folder
string[] filePaths = Directory.GetFiles(path, "*.dxf");
Thanks Jonathan Alfaro and Clemens!

Application: Application Launcher, can't Move directory, it's being used by another process

I'm writing application launcher as a Window Application in C#, VS 2017. Currently, having problem with this piece of code:
if (System.IO.Directory.Exists(extractPath))
{
string[] files = System.IO.Directory.GetFiles(extractPath);
string[] dirs = Directory.GetDirectories(extractPath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
var fileName = System.IO.Path.GetFileName(s);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.File.Move(s, destFile);
}
foreach (string dir in dirs)
{
//var dirSplit = dir.Split('\\');
//var last = dirSplit.Last();
//if (last != "Resources")
//{
var fileName = System.IO.Path.GetFileName(dir);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.Directory.Move(dir, destFile);
//}
}
}
I'm getting well known error
"The process cannot access the file 'XXX' because it is being used by another process."
I was looking for solution to fix it, found several on MSDN and StackOvervflow, but my problem is quite specific. I cannot move only 1 directory to another, which is Resources folder of my main application:
Here is my explanation why problem is specific:
I'm not having any issues with moving other files from parent directory. Error occurs only when loop reaches /Resources directory.
At first, I was thinking that it's beeing used by VS instantion, in which I've had main app opened. Nothing have changed after closing VS and killing process.
I've copied and moved whole project to another directory. Never opened it in VS nor started via *.exe file, to make sure that none of files in new, copied directory, is used by any process.
Finally, I've restarted PC.
I know that this error is pretty common when you try to Del/Move files, but in my case, I'm sure that it's being used only by my launcher app. Here is a little longer sample code to show what files operation I'm actually doing:
private void RozpakujRepo()
{
string oldPath = #"path\Debug Kopia\Old";
string extractPath = #"path\Debug Kopia";
var tempPath = #"path\ZipRepo\RexTempRepo.zip";
if (System.IO.File.Exists(tempPath) == true)
{
System.IO.File.Delete(tempPath);
}
System.IO.Compression.ZipFile.CreateFromDirectory(extractPath, tempPath);
if (System.IO.Directory.Exists(oldPath))
{
DeleteDirectory(oldPath);
}
if (!System.IO.Directory.Exists(oldPath))
{
System.IO.Directory.CreateDirectory(oldPath);
}
if (System.IO.Directory.Exists(extractPath))
{
string[] files = System.IO.Directory.GetFiles(extractPath);
string[] dirs = Directory.GetDirectories(extractPath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
var fileName = System.IO.Path.GetFileName(s);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.File.Move(s, destFile);
}
foreach (string dir in dirs)
{
//var dirSplit = dir.Split('\\');
//var last = dirSplit.Last();
//if (last != "Resources")
//{
var fileName = System.IO.Path.GetFileName(dir);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.Directory.Move(dir, destFile);
//}
}
}
string zipPath = #"path\ZipRepo\RexRepo.zip";
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
And now, my questions:
Can it be related to file types (.png, .ico, .bmp) ?
Can it be related to fact, that those resources files are being used like, as, for example .exe file icon in my main application? Or just because those are resources files?
Is there anything else what I'm missing and what can cause the error?
EDIT:
To clarify:
There are 2 apps:
Main Application
Launcher Application (to launch Main Application)
And Resources folder is Main Application/Resources, I'm moving it while I'm doing application version update.
It appeared that problem is in different place than in /Resources directory. Actually problem was with /Old directory, because it caused inifinite recurrence.

How to find image path in c#?

I want to find image path but I didn't.
my image path : C:\Works\Web5.1.0\Src\Works.WebNext\Password\assets\img
my image name : reset_password.jpg
I tried this : string path2 = Path.GetFullPath("reset_password.jpg"); but it's wrong path (output: C:\Windows\System32\inetsrv)
and tried this :
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
string a = Path.Combine(path, "reset_password.jpg");
output : (C:\Works\Web5.1.0\Src\Works.WebNext\bin )
I think, output should be like this : C:\Works\Web5.1.0\Src\Works.WebNext\Password\assets\img
one more thing : image path may not be same another computer so I think give a specific path is not right (for example : C:\Works\Web5.1.0\Src\Works.WebNext\Password\assets\img )
X computer : C:\Works\Web5.1.0\Src\Works.WebNext\Password\assets\img
Y computer : C:\Works\Web\Src\Works.WebNext\Password\assets\img
By the way, I am writing with c#.
How can I do ?
Any ideas please.
I'm not sure I've understood the issue but an idea of how to find the same file on many systems is:
AppDomain.CurrentDomain.BaseDirectory
This will give you the location of the folder that your running executable is in. The output is in the format of
"C:\Folder\Folder\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug\".
So, you can put the image in the same folder as the .exe, add "imagefilename.type" and you should find it.
Please clarify if this doesn't answer your question.
Following code will give you your desired output
string folderPath = #"C:\Works\Web5.1.0\Src\Works.WebNext\Password\assets\img";
string imgFilePath = Path.Combine(folderPath, "reset_password.jpg")
Assembly.GetExecutingAssembly() gives the path of the current working directory i.e. the path from where your executables are being run (in your case its 'bin' folder)
Try this for Web Applications.
string imagePath = "/Password/"; /* Your Image folder */
string path = Server.MapPath(#"ImagePath" + imagePath);
In Windows Application:
try
{
System.IO.DirectoryInfo directory = new DirectoryInfo(#"Your local Image directory inside bin/debug");
FileInfo result = null;
var list = directory.GetFiles(); // Stackoverflow Exception occurs here
if (list.Count() > 0)
{
result = list.OrderByDescending(f => f.LastWriteTime).First();
}
return result;
}
catch (Exception ex)
{
throw ex;
}

Directory could not be found

I have recently started to get an error which states my directory can not be found I have tried a number of ways to solve this but have yet to find a solution.
The method should allow the user to select an image for their computer and add it to a folder called images inside the applications folder structure. The problem is that when using the File.copy(imageFilename, path); it throws the error. I have tried changing the path and you will see from the code snip it. It is even doing it when the program itself has passed the file path for the application and is still throwing me the error.
this is the method.
private void btnImageUpload_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog imageFile = new OpenFileDialog();
imageFile.InitialDirectory = #"C:\";
imageFile.Filter = "Image Files (*.jpg)|*.jpg|All Files(*.*)|*.*";
imageFile.FilterIndex = 1;
if (imageFile.ShowDialog() == true)
{
if(imageFile.CheckFileExists)
{
string path = AppDomain.CurrentDomain.BaseDirectory;
System.IO.File.Copy(imageFile.FileName, path);
}
}
}
I am using VS2013 and have included the using Microsoft.win32
Any further information needed please ask.
Thanks
There are 2 things need to be taken into consideration
private void btnImageUpload_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog imageFile = new OpenFileDialog();
imageFile.InitialDirectory = #"C:\";
imageFile.Filter = "Image Files (*.jpg)|*.jpg|All Files(*.*)|*.*";
imageFile.FilterIndex = 1;
if (imageFile.ShowDialog() == true)
{
if(imageFile.CheckFileExists)
{
string path = AppDomain.CurrentDomain.BaseDirectory; // You wont need it
System.IO.File.Copy(imageFile.FileName, path); // Copy Needs Source File Name and Destination File Name
}
}
}
string path = AppDomain.CurrentDomain.BaseDirectory; You won need this because the default directory is your current directory where your program is running.
Secondly
System.IO.File.Copy(imageFile.FileName, path); Copy Needs Source File Name and Destination File Name so you just need to give the file name instead of path
so your updated code will be
private void btnImageUpload_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog imageFile = new OpenFileDialog();
imageFile.InitialDirectory = #"C:\";
imageFile.Filter = "Image Files (*.jpg)|*.jpg|All Files(*.*)|*.*";
imageFile.FilterIndex = 1;
if (imageFile.ShowDialog() == true)
{
if(imageFile.CheckFileExists)
{
System.IO.File.Copy(imageFile.FileName, SomeName + ".jpg"); // SomeName Must change everytime like ID or something
}
}
}
I'm not sure if that's the problem, but the File.Copy method expects a source file name and a target file name, not a source file name and directory: https://msdn.microsoft.com/en-us/library/c6cfw35a(v=vs.110).aspx
So, to make this work, in your case you'd have to do something like the following (namespaces omitted):
File.Copy(imageFile.FileName, Path.Combine(path, Path.GetFileName(imageFile.FileName));
Note that this will fail if the destination file exists, to overwrite it, you need to add an extra parameter to the Copy method (true).
EDIT:
Just a note, the OpenFileDialog.CheckFileExists does not return a value indicating if the selected file exists. Instead, it is a value indicating whether a file dialog displays a warning if the user specifies a file name that does not exist. So instead of checking this property after the dialog is closed, you should set it to true before you open it (https://msdn.microsoft.com/en-us/library/microsoft.win32.filedialog.checkfileexists(v=vs.110).aspx)

Get Folder Path

I want to get the path of the folder to a textbox and the name of the folder is Images12345. I tried this.
//Inside the folder "Images12345"
string[] pics = { "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg" };
int i = 0;
Then in my form load
//I tried this but it is given me wrong path
textBox1.Text = Path.GetFullPath(#"Images12345");
//then slideshow
pictureBox1.Image = Image.FromFile(textBox1.Text+"/"+pics[0]);
timer1.Enabled = true;
timer1.Interval = 5000;
i = 0;
First, use this to get the application folder plus your images folder:
string applicationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images12345");
Second, always use Path.Combine to work with paths:
pictureBox1.Image = Image.FromFile(Path.Combine(myFolderPath, pics[0]));
NOTE
You'll need to copy images folder where the executable is. That's your bin/Degub while you're debugging. You can navigate two folders up, but you must to implement this like you were in production, when the executable will be right next to your image folder.
EDIT
Maybe it's a better approach to use the current user's pictures folder. Like this:
string userPicturesFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
string imagesFolder = Path.Combine(userPicturesFolderPath, "Images12345");
You already found Path.GetFullPath... you should also look at Path.Combine to make a path out of multiple pieces, instead of just using string concatenation.

Categories