I'm getting an unhandled exception of type System.IO.IOException occurring in mscorlib.dll because the file I'm trying to delete is being used by another process.
I want it to skip the used files.
private void button1_Click(object sender, EventArgs e)
{
System.IO.DirectoryInfo directory =
new System.IO.DirectoryInfo(#"C:\Users\fatih\AppData\Local\Temp");
foreach (System.IO.FileInfo file in directory.GetFiles()) file.Delete();
foreach (System.IO.DirectoryInfo subDirectory in directory.GetDirectories())
subDirectory.Delete(true);
}
If it's not important that you delete everything, use:
private void button1_Click(object sender, EventArgs e)
{
string directory = #"C:\Users\fatih\AppData\Local\Temp";
deleteDirectory(directory);
}
private void deleteDirectory(string directory){
foreach (string file in Directory.GetFiles(directory))
{
try{
File.Delete(file);
}
catch(Exception e0){
Console.WriteLine(e0.Message+"\n"+e0.Source);//not necessary but nice to learn from
}
}
foreach (string direc in Directory.GetDirectories(directory)) {
deleteDirectory(direc);
Directory.Delete(direc,true);
}
}
This will simply skip over any file or directory that has a problem and delete everything else.
Use the static versions of the directory and file methods, you cannot use a foreach on file.delete the way you are doing it because you are trying to do a delete operation on the thing you are looping through.
foreach (var file in Directory.GetFiles(directory))
{
File.Delete(file);
}
Update: I did not notice the subdirectory delete, that is your issue, if you want to just delete everything including the directory you are on, then you are working too hard.
Directory.Delete(Directory, true);
Will wipe out the directory and all the subdirectories and files in the directory passed in.
Since you are still having issues, and everyone seems to think I am wrong here, I will give you the code to past into your solution.
private void button1_Click(object sender, EventArgs e)
{
string directory = #"C:\Users\fatih\AppData\Local\Temp")
Directory.Delete(directory, true);
}
IF there is an outside process hanging on to the file this will not work, otherwise it will do what you want it to do
Related
I am attempting to have ListView in my WPF application, which accepts drag and drop - both files and directories, but in case of directories it is supposed to get files from them, not them themselves.
My XAML:
<ListView ... AllowDrop="True" Drop="importListView_Drop">
...
</ListView>
My code behind:
private void importListView_Drop(object sender, DragEventArgs e)
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
core.AddIntoImport(files);
}
This now produces outputs including directories and omitting files in them, f.e.
C:/Example/Files/MyFile.mp3
C:/Example/Files/SubDirectory/
...
While I'd like it to actually get all files from SubDirectory and not include SubDirectory itself. I could do this by myself: "is directory? - yes: exclude it and get all files from it instead" but the question is, is there some nicer way included in f.e. event args already?
Just to make myself more clear, following code does the job perfectly in WinForms app. Is there an alternative in WPF?
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
InsertImport(files);
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
}
You could use this
var allFiles = files.Where(Directory.Exists)
.SelectMany(dir => Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories))
.ToList();
Just be aware, this is will throw if you have don't have appropriate permissions on the sub directories. in such case you will have to do this more manually, and check-for / ignore errors
Managed to do this in this way in the end btw...:
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
var importList = new List<string>();
foreach (string s in files)
{
if (Directory.Exists(s))
foreach (var f in Directory.GetFiles(s, "*.*", SearchOption.AllDirectories))
importList.Add(f);
else if (File.Exists(s))
importList.Add(s);
}
What should be in (???)
I want to open for example 3 selected files in my simple file explorer
private void Open_Click(object sender, System.EventArgs e)
{
foreach (???)
{
string ImageViewName = listView1.SelectedItems[0].Text;
System.Diagnostics.Process.Start(#textBox1.Text.Remove(3, 1) + "/" + ImageViewName);
}
}
in textbox1 is my path to the files
Assuming each File is in a List called Files
foreach (File myFile in Files){
//Do something with myFile
}
The foreach block will iterate through each File in Files. The current selected file, which can be accessed from within the foreach block, is called 'myFile' in this instance.
I am new to stackoverflow so I'm open to advice about my answer too!
The button1_Click Event (Copy PDF's to new location) works perfectly when the button is clicked and the code is executed the 1st time;
however, upon clicking the button a second time (with same text box entry), it throws the following error:
System.UnauthorizedAuthorizedAccessException: Access to the path "\share\drive....
Obviously, I don't want this to be able to execute twice during a session, given the same text box entry. Before I tackle that, I would like to fix this exception error. Am I erroneously leaving the path open?
Code updated to show solution:
public static string Case_No;
namespace CEB_Process
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//===============================
// TEXT BOX ENTRY
//===============================
private void textBox1_TextChanged(object sender, EventArgs e)
{
Form1.Case_No = textBox1.Text;
}
//==============================
// CHECK if Direcotry Exists
//==============================
public void CreateIfMissing(string path)
{
if (!Directory.Exists(path))
{
DirectoryInfo di = Directory.CreateDirectory(path);
//Added
var permissions = new DirectoryInfo(path);
permissions.Attributes &= ~FileAttributes.ReadOnly;
MessageBox.Show("The directory was created successfully");
}
}
//=================================
// MOVE Violation PDF's Button Click
//==================================
private void button1_Click(object sender, EventArgs e)
{
//Declare Source path directory from text box entry
string sourcePath = string.Format(#"\\share\drive\etc{0}", Case_No);
string targetPath = string.Format(#"\\share\drive\etc{0}", Case_No);
try
{
//Call Method to Check/Create Path
CreateIfMissing(targetPath);
//Get TRAKiT Violation PDF's from source
foreach (var sourceFilePath in Directory.GetFiles(sourcePath, "*.pdf"))
{
string fileName = Path.GetFileName(sourceFilePath);
string destinationFilePath = Path.Combine(targetPath, fileName);
System.IO.File.Copy(sourceFilePath, destinationFilePath, true);
File.SetAttributes(destinationFilePath, FileAttributes.Normal);
}//End For Each Loop
MessageBox.Show("Files Copied Successfully!");
}//end try
catch (Exception x)
{
MessageBox.Show("The process failed", x.ToString());
}
}//End Button Module
}//End Namespace
}//End Class
I also had the problem I added the following line of code before and after a Copy / Delete.
File.Copy(file, dest, true);
File.SetAttributes(dest, FileAttributes.Normal);
(PS: Taken from Why is access to the path denied?)
I suppose you're using File.Copy without overwriting the selected file.
That means the file is getting copied and it's temporarily locked by OS, and then it's not open to modifications (read-only). This is the reason of your UnauthorizedAccessException.
Check if you can accessthe file first.
So basically what I'm trying to accomplish is being able to select a file from a displayed list and open that file. Right now I have it set up in a CheckBoxList that displays the .docx, .mov, and .txt files that exist in the selected folder. The problem is I can't get it to open the file. I've seen most people suggesting-
Process.Start(filename);
But the problem with that is that it requires a specific file name and I'm trying to pull that name from a variable. Any ideas?
Here's my current code -
private void Form1_Load(object sender, EventArgs e)
{
const string path = #"C:\Users\Haxelle\Documents\Journal";
List<string> extensions = new List<string> { "DOCX", "MOV", "TXT" };
string[] files = GetFilesWithExtensions(path, extensions);
ckbEntry.Items.AddRange(files);
}
private string[] GetFilesWithExtensions(string path, List<string> extensions)
{
string[] allFilesInFolder = Directory.GetFiles(path);
return allFilesInFolder.Where(f => extensions.Contains(f.ToUpper().Split('.').Last())).ToArray();
}
private void btnOpen_Click(object sender, EventArgs e)
{
CheckedListBox.CheckedItemCollection selectedFiles = ckbEntry.CheckedItems;
}
Trying to open file in btnOpen_Click
It seems like all you are missing is iterating over the selected files names and opening them. Since the CheckedItemCollection.Item is typed as object, you will need to cast the items, which can be done using LINQ's Cast function.
private void btnOpen_Click(object sender, EventArgs e)
{
CheckedListBox.CheckedItemCollection selectedFiles = ckbEntry.CheckedItems;
foreach (var filename in selectedFiles.Cast<string>()) {
Process.Start(filename);
}
}
I'm not sure whether this topics has been disscussed before or not, but I'm not sure the exact word to search for it. What method/class should I use?
The program has 3 buttons: 1) for folder browsing, 2) scan for the selected folder content, and 3) open the file. When user browse the selected folder**(1), user click scan button to scan from the first file until the last available files and listed it text box(2)** and from that user can decide whether to open the files or not**(3)**.
Here are what have I done so far (no 1 and 3):
//For browse.
private void browse2()
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
this.txtDest.Text = folderBrowserDialog1.SelectedPath;
}
}
//For opening folder.
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
Process.Start(txtDest.Text);
}
catch
{
MessageBox.Show("Please select one file/folder");
}
}
If you are trying to just open a file you can directly use an Open File Dialog.
If you need to display the contents of a directory you can use the Directory Info Class.
Well my example is a WPF app that adds files/ folders in a directory to a treeview, but you should get the general idea:
Note: Code was written for a training exercise, and therefore only goes 3 levels deep, as a proof of concept kind of thing
private void Window_Loaded(object sender, RoutedEventArgs e)
{
foreach (DriveInfo di in DriveInfo.GetDrives())
{
TreeViewItem drive = new TreeViewItem();
drive.Header = di.Name;
treeView1.Items.Add(drive);
DirectoryInfo folders = new DirectoryInfo(di.Name);
// The depth count means that it only goes 3 levels deep, to make it quick to load
GetFoldersAndFiles(drive, folders, 3);
}
}
private static void GetFoldersAndFiles(TreeViewItem parent, DirectoryInfo folders, int depth)
{
if ((depth > 0)
{
foreach (DirectoryInfo dirI in folders.GetDirectories())
{
TreeViewItem dir = new TreeViewItem();
dir.Header = dirI.Name;
parent.Items.Add(dir);
GetFoldersAndFiles(dir, dirI, depth - 1);
}
foreach (FileInfo fileI in folders.GetFiles())
{
TreeViewItem file = new TreeViewItem();
file.Header = fileI.Name;
parent.Items.Add(file);
}
}
}