openfiledialog results in file is being used by another process [duplicate] - c#

This question already has an answer here:
System.IO.IOException: 'The process cannot access the file because it is being used by another process
(1 answer)
Closed 2 years ago.
I would like use C# to upload multiple files to google drive
this is my upload button function
private void bt_upload_Click(object sender, EventArgs e)
{
Filedialog_init();
DialogResult check_upload = MessageBox.Show("Want to upload these files ?", "Upload", MessageBoxButtons.OKCancel);
if (check_upload == DialogResult.OK)
{
for (int i = 0; i < result.Count; i++)
{
UploadFilesDrive(service, result[i], filePath[i], Datatype[i]);
tx_state.AppendText(result[i] + "Upload Done");
}
}
}
This is my Filedialog_init function
private static void Filedialog_init()
{
Stream myStream = null;
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = "c:\\";
openFileDialog.Filter = "bin files (*.bin)|*.bin|All files (*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
openFileDialog.Multiselect = false;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filename = null;
string _datatype = null;
try
{
if ((myStream = openFileDialog.OpenFile()) != null)
{
foreach (String file in openFileDialog.FileNames)
{
filename = Path.GetFileName(file);
result.Add(filename);
// only show the name of file
Datatype.Add(_datatype);
}
filePath = openFileDialog.FileNames;
Datatype.ForEach(Console.WriteLine);
}
openFileDialog.Dispose();
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
else
MessageBox.Show("Upload Cancel");
}
I can upload the file successfully by assigning the filename and its datatype and path directly
But when I used openfiledialog,it went wrong with "my file is being used by another process"
How can I solve this problem?

Issue lies in your code here,
(myStream = openFileDialog.OpenFile()) This line is keeping lock on the file because your myStream does not get disposed. you need to dispose the stream as soon as you are done with it.
So try with using as it will dispose the stream as soon as your end using line gets executed. More details on using.
you can try as below,
using(Stream myStream = openFileDialog.OpenFile())
{
//Your code here...
}

Related

I am trying to create an upload file button, but whenever I try and use a file I get the error "Empty path name is not legal"

Every time I click on a file, I get the error
Empty path name is not legal
I need a user to upload a .txt or .csv file and have the contents of that file to display in the data grid view. Everything works fine except for this one error that occurs on this line:
var sr = new StreamReader(openFileDialog1.FileName);
Full code.
private void selectButton_Click (object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
var sr = new StreamReader(openFileDialog1.FileName);
SetText(sr.ReadToEnd());
}
catch (SecurityException ex)
{
MessageBox.Show($"Security error.\n\nError message{ex.Message}\n\n" +
$"Details:\n\n{ex.StackTrace}");
}
}
}
try to add filter on openFileDialog1 like.
openFileDialog1.Filter = "text file(*.txt)|*.txt|csv file(*.csv)|*.csv";
Check the FileName before open file:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if (string.IsNullOrEmpty(openFileDialog1.FileName) {
// ..
return;
}
try
{
var fileStream = openFileDialog1.OpenFile();
using (StreamReader reader = new StreamReader(fileStream))
{
SetText(sr.ReadToEnd());
}
}
catch (SecurityException ex)
{
MessageBox.Show($"Security error.\n\nError message{ex.Message}\n\n" +
$"Details:\n\n{ex.StackTrace}");
}
}

other process is still using this file

public void button1_Click(object sender, EventArgs e)
{
//string item = ofd.FileName;
ofd.InitialDirectory = "c:\\";
ofd.Filter = "exe files (*.exe)|*.exe";
ofd.Multiselect = true;
ofd.RestoreDirectory = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
listBox1.Items.Clear();
string tmp = Path.Combine(Path.GetDirectoryName(listBox2.GetItemText(listBox2.Items)), "\\inputdata.txt");
File.Create(tmp);
using (File.Open(tmp, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
;
foreach (string item in ofd.FileNames)
{
string date = Path.GetFileName(item.Substring(10, 16));
string ite = item.Substring(0, item.IndexOf(".h2"));
listBox1.Items.Add(item);
if (File.ReadAllText(tmp).Contains(Path.GetFileName(item).Substring(10, 16)))
{
File.AppendAllText(tmp, Environment.NewLine);
}
if (item.IndexOf("MOD10A") >= 0)
{
if (File.ReadAllText(tmp).IndexOf(date) < 0)
{
File.AppendAllText(tmp, ite.Replace("MOD10A1.A", "ter_"));
}
}//
if (item.IndexOf("MYD10A") >= 0)
{
if (File.ReadAllText(tmp).IndexOf(date) < 0)
{
File.AppendAllText(tmp, ite.Replace("MYD10A1.A", "Aqu_"));
}
}
File.AppendAllText(tmp, ", " + item);
}
}
}
}
listbox2 has filename which i get from openfiledialog. like C:\Program Files (x86)\Microsoft\file.exe
when i debug this program. error happens. message is that The process cannot access the "c:\inputdata.txt" because it is being used by another process.
I don't understand why inputdata.txt is located in c:\ and why error is happening.
What is the reason for this error?
You must close the FileStream after use it.
Look at this :
Closing a file after File.Create
https://msdn.microsoft.com/en-us/library/aa328800(v=vs.71).aspx
First read the text file then after update the file.
using (File.Open(tmp, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
/// Not right here a append txt logic
}
// Code File.AppendAllText
Then after right here appned or update logic here.bcz, If file is already open you can't write or update the file.

C# WPF FileSaving Exception encountered

My issue is that I keep seeing a recurring theme with trying to allow my Notepad clone to save a file. Whenever I try to save a file, regardless of the location on the hard disk, the UnauthorizedAccess Exception continues to be thrown. Below is my sample code for what I've done, and I have tried researching this since last night to no avail. Any help would be greatly appreciated.
//located at base class level
private const string fileFilter = "Text Files|*.txt|All Files|*.*";
private string currentPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
private void MenuFileSaveAs_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.DefaultExt = "*.txt";
sfd.Filter = fileFilter;
sfd.AddExtension = true;
sfd.InitialDirectory = currentPath;
sfd.RestoreDirectory = true;
sfd.OverwritePrompt = true;
sfd.ShowDialog();
try
{
System.IO.File.WriteAllText(currentPath,TxtBox.Text,Encoding.UTF8);
}
catch (ArgumentException)
{
// Do nothing
}
catch(UnauthorizedAccessException)
{
MessageBox.Show("Access Denied");
}
}
Change the following lines.
...
if (sfd.ShowDialog() != true)
return;
try
{
using (var stream = sfd.OpenFile())
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
writer.Write(TxtBox.Text);
}
}
...
I hope it helps you.
You need to get the correct path context and file object from the dialog box once the user has hit 'ok'. Namely verify the user actually hit ok and then use the OpenFile property to see what their file selection is:
if (sfd.ShowDialog.HasValue && sfd.ShowDialog)
{
if (sfd.OpenFile() != null)
{
// convert your text to byte and .write()
sfd.OpenFile.Close();
}
}

display file instead of RSC version

Whenever I try to open a custom file to a textbox or something which will display code. it never works, I'm not sure what I am doing wrong.
I want my program to display what is inside the file when I open it, I have this below:
private void button1_Click(object sender, EventArgs e)
{
//Show Dialogue and get result
Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "rbt files (*.rbt)|*.rbt|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
File.WriteAllText("", CodeBox.Text);
}
}
}
catch (Exception ex)
{
MessageBox.Show("RBT7 file open");
}
}
}
It only displays the RBT7 in a messagebox which is not what I want, I want the file to open and display its information to some sort of textbox which displays code.
Please read the documentation for File.WriteAllText.
The first parameter:
path: The file to write to.
You're passing it "". That is not a path. Are you trying to write all the text from the file into CodeBox.Text or write all the text from CodeBox.Text into a file?
In your comment, you indicate the former. Try this:
string[] lines = System.IO.File.ReadAllLines(#"your file path");
foreach (string line in lines)
{
CodeBox.Text += line;
}
You haven't shown the code for CodeBox so I can't guarantee the results of this.
Try this:
Replace this code
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
File.WriteAllText("", CodeBox.Text);
}
}
with this
{
CodeBox.Text = File.ReadAllText(openFileDialog1.FileName);
}

How to save last folder in openFileDialog?

How do I make my application store the last path opened in openFileDialog and after new opening restore it?
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
acc_path = openFileDialog1.FileName;
Settings.Default.acc_path = acc_path;
foreach (string s in File.ReadAllLines(openFileDialog1.FileName))
{
accs.Enqueue(s);
}
label2.Text = accs.Count.ToString();
}
This is the easiest way: FileDialog.RestoreDirectory.
After changing Settings you have to call
Settings.Default.Save();
and before you open the OpenFileDialog you set
openFileDialog1.InitialDirectory = Settings.Default.acc_path;
I think it would be enough for you to use SetCurrentDirectory to ste the current directory for the OS. So on the next dialog opening it would pick that path.
Or simply save path into some variable of your application and use
FileDialog.InitialDirectory property.
The following is all you need to make sure that OpenFileDialog will open at the directory the user last selected, during the lifetime off your application.
OpenFileDialog OpenFile = new OpenFileDialog();
OpenFile.RestoreDirectory = false;
I find that all you have to do is NOT set the initial directory and the dialog box remembers your last save/open location. This remembers even after the application is closed and reopened. Try this code with the initial directory commented out. Many of the suggestions above will also work but if you are not looking for additional functionality this is all you have to do.
private void button1_Click(object sender, EventArgs e)
{
Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
//openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
// Insert code to read the stream here.
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
}
I know this is a bit of an old thread, but I was not able to find a solution I liked to this same question so I developed my own. I did this in WPF but it should work almost the same in Winforms.
Essentially, I use an app.config file to store my programs last path.
When my program starts I read the config file and save to a global variable. Below is a class and function I call when my program starts.
public static class Statics
{
public static string CurrentBrowsePath { get; set; }
public static void initialization()
{
ConfigurationManager.RefreshSection("appSettings");
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CurrentBrowsePath = ConfigurationManager.AppSettings["lastfolder"];
}
}
Next I have a button that opens the file browse dialog and sets the InitialDirectory property to what was stored in the config file. Hope this helps any one googling.
private void browse_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog open_files_dialog = new OpenFileDialog();
open_files_dialog.Multiselect = true;
open_files_dialog.Filter = "Image files|*.jpg;*.jpeg;*.png";
open_files_dialog.InitialDirectory = Statics.CurrentBrowsePath;
try
{
bool? dialog_result = open_files_dialog.ShowDialog();
if (dialog_result.HasValue && dialog_result.Value)
{
string[] Selected_Files = open_files_dialog.FileNames;
if (Selected_Files.Length > 0)
{
ConfigWriter.Update("lastfolder", System.IO.Path.GetDirectoryName(Selected_Files[0]));
}
// Place code here to do what you want to do with the selected files.
}
}
catch (Exception Ex)
{
MessageBox.Show("File Browse Error: " + Environment.NewLine + Convert.ToString(Ex));
}
}
You can use the InitialDirectory property : http://msdn.microsoft.com/fr-fr/library/system.windows.forms.filedialog.initialdirectory.aspx
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1.InitialDirectory = previousPath;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
previousPath = Path.GetDirectoryName(openFileDialog1.FileName);
acc_path = openFileDialog1.FileName;
Settings.Default.acc_path = acc_path;
foreach (string s in File.ReadAllLines(openFileDialog1.FileName))
{
accs.Enqueue(s);
}
label2.Text = accs.Count.ToString();
}
if your using
Dim myFileDlog As New OpenFileDialog()
then you can use this to restore the last directory
myFileDlog.RestoreDirectory = True
and this to not
myFileDlog.RestoreDirectory = False
(in VB.NET)

Categories

Resources