Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Iam trying to get all drives, folders, subfolders and files in treeview control using winforms. I have seen the following article.
http://codehill.com/2013/06/list-drives-and-folders-in-a-treeview-using-c/
but this only shows drives, folders and sub folders but not the files containing in these folders.
Please anyone help and guide that how can i view all these files under these folders in treeview, thanks in advance.
EDIT:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GetDrives
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
//get a list of the drives
string[] drives = Environment.GetLogicalDrives();
foreach (string drive in drives)
{
DriveInfo di = new DriveInfo(drive);
int driveImage;
switch (di.DriveType) //set the drive's icon
{
case DriveType.CDRom:
driveImage = 3;
break;
case DriveType.Network:
driveImage = 6;
break;
case DriveType.NoRootDirectory:
driveImage = 8;
break;
case DriveType.Unknown:
driveImage = 8;
break;
default:
driveImage = 2;
break;
}
TreeNode node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage);
node.Tag = drive;
if (di.IsReady == true)
node.Nodes.Add("...");
dirsTreeView.Nodes.Add(node);
}
}
private void dirsTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Nodes.Count > 0)
{
if (e.Node.Nodes[0].Text == "..." && e.Node.Nodes[0].Tag == null)
{
e.Node.Nodes.Clear();
//get the list of sub direcotires
string[] dirs = Directory.GetDirectories(e.Node.Tag.ToString());
foreach (string dir in dirs)
{
DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1);
try
{
//keep the directory's full path in the tag for use later
node.Tag = dir;
//if the directory has sub directories add the place holder
if (di.GetDirectories().Count() > 0)
node.Nodes.Add(null, "...", 0, 0);
foreach (var file in di.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
node.Nodes.Add(n);
}
}
catch (UnauthorizedAccessException)
{
//display a locked folder icon
node.ImageIndex = 12;
node.SelectedImageIndex = 12;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "DirectoryLister",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
e.Node.Nodes.Add(node);
}
}
}
}
}
}
}
I have now updated my code in application and using only one treeview, but the problem still exists. You can see in image, in my C drive i have a file name "courses outline.html" and ab.txt which are not showing in application, which i need to see. Please see iamge below to easily understand my requirement.
Change the code in the try block (from: List Drives and Folders in a TreeView Using C#) as following:
EDIT:
Added following code, because the files of the root-directory were ignored:
//add files of rootdirectory
DirectoryInfo rootDir = new DirectoryInfo(e.Node.Tag.ToString());
foreach (var file in rootDir.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
e.Node.Nodes.Add(n);
}
Full class:
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Nodes.Count > 0)
{
if (e.Node.Nodes[0].Text == "..." && e.Node.Nodes[0].Tag == null)
{
e.Node.Nodes.Clear();
//get the list of sub direcotires
string[] dirs = Directory.GetDirectories(e.Node.Tag.ToString());
//add files of rootdirectory
DirectoryInfo rootDir = new DirectoryInfo(e.Node.Tag.ToString());
foreach (var file in rootDir.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
e.Node.Nodes.Add(n);
}
foreach (string dir in dirs)
{
DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1);
try
{
//keep the directory's full path in the tag for use later
node.Tag = dir;
//if the directory has sub directories add the place holder
if (di.GetDirectories().Count() > 0)
node.Nodes.Add(null, "...", 0, 0);
foreach (var file in di.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
node.Nodes.Add(n);
}
}
catch (UnauthorizedAccessException)
{
//display a locked folder icon
node.ImageIndex = 12;
node.SelectedImageIndex = 12;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "DirectoryLister",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
e.Node.Nodes.Add(node);
}
}
}
}
}
This look like following picture:
You can use the enumerate files method to get the name of each file inside a directory location.
string sourceDirectory = #"C:\current";
var files = Directory.EnumerateFiles(sourceDirectory);
foreach (string file in files)
{
// Do Something with file
}
Related
As you can see in code, folders are created during move file button. my question is that how to moves files in that particular folders, I have tens of millions of files and want to moves in that particulars. I am new in c#.
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace File2Folders
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<string> fileName = null;
List<string> fileNames = null;
private void btn_browse_Click(object sender, EventArgs e)
{
using (FolderBrowserDialog fbd = new FolderBrowserDialog())
{
if (fbd.ShowDialog() == DialogResult.OK)
{
listBox1.Items.Clear();
fileName = Directory.GetFiles(fbd.SelectedPath).ToList();
fileNames = fileName.Select(item => Path.GetFileNameWithoutExtension(item).Substring(1, 4)).OrderBy(n=>n).ToList();
listBox1.DataSource = fileName.Select(f => Path.GetFileName(f)).ToList();
listBox2.DataSource = fileNames;
}
}
}
private void btn_move_Click(object sender, EventArgs e)
{
using (FolderBrowserDialog fbd = new FolderBrowserDialog())
{
if (fbd.ShowDialog() == DialogResult.OK)
{
fileNames.ForEach(item => Directory.CreateDirectory(Path.Combine(fbd.SelectedPath, item)));
}
Try to use this fuction that I use sometimes.
bool FileCopyPasteRename(string source, string destination, string renameTo)
{
bool res = false;
string renameDestination = Path.Combine(destination, renameTo.ToLower());
try
{
if (File.Exists(source))
{
File.Copy(source, renameDestination, true);
}
}
catch (Exception ex)
{
//cath error ex.Message
}
return res;
}
Once its a bool function, you can check if returns true and the delete source file.
To move a file you can use method Move in File. It takes as parameter the path of the file you want to move and the destination including and the file name
here is an example
string filePath = #"C:\Users\HP\source\repos\ConsoleApp1\ConsoleApp1\fileToMove.txt";
string destination = #"C:\Users\HP\source\repos\ConsoleApp1\ConsoleApp1\Dummy\fileToMove.txt";
try
{
File.Move(filePath, destination);
}
catch (Exception e)
{
Console.WriteLine("We coudnt move the file becouse of: " + e.Message);
}
For more https://learn.microsoft.com/en-us/dotnet/api/system.io.file.move?view=net-6.0
I have started learning C# recently. Presently am working on creating "Windows Explorer".
Actual requirement is as follows
In list View Double Click function.
When I click on a folder in list view, it should display the files which are present in the folder in list view , but as per my code its being opened in another window.
Below is the code. Requesting for your help & guidance
alert(false);
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Configuration;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Security.Principal;
namespace New_Demo
{
public partial class WindowsExplorer : Form
{
string SelectedPath = string.Empty;
double size;
string filelength;
Login formPopup;
private FileAttributes attr;
public WindowsExplorer()
{
InitializeComponent();
PopulateTreeView();
}
private void PopulateTreeView()
{
TreeNode rootNode;
{
DirectoryInfo info = new DirectoryInfo(#"C:\Users\4076\Desktop\");
if (info.Exists)
{
rootNode = new TreeNode(info.Name);
rootNode.Tag = info;
GetDirectories(info.GetDirectories(), rootNode);
treeView.Nodes.Add(rootNode);
LoadFiles(info.FullName, rootNode);
}
else
MessageBox.Show("Please select a path");
}
}
private void LoadFiles(string dir, TreeNode td)
{
string[] Files = Directory.GetFiles(dir, "*.*");
// Loop through them to see files
foreach (string file in Files)
{
FileInfo fi = new FileInfo(file);
TreeNode tds = td.Nodes.Add(fi.Name);
tds.Tag = fi.FullName;
tds.StateImageIndex = 1;
//UpdateProgress();
}
}
private void GetDirectories(DirectoryInfo[] subDirs, TreeNode nodeToAddTo)
{
TreeNode aNode;
DirectoryInfo[] subSubDirs;
foreach (DirectoryInfo subDir in subDirs)
{
aNode = new TreeNode(subDir.Name, 0, 0);
aNode.Tag = subDir;
aNode.ImageKey = "folder";
subSubDirs = subDir.GetDirectories();
if (subSubDirs.Length != 0)
{
GetDirectories(subSubDirs, aNode);
}
nodeToAddTo.Nodes.Add(aNode);
}
}
private void treeView_NodeMouseClick_1(object sender, TreeNodeMouseClickEventArgs e)
{
TreeNode newSelected = e.Node;
listView.Items.Clear();
DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;
if (!string.IsNullOrEmpty(nodeDirInfo.FullName.ToString()))
{
SelectedPath = nodeDirInfo.FullName.ToString();
}
ListViewItem.ListViewSubItem[] subItems;
ListViewItem item = null;
foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
{
item = new ListViewItem(dir.Name, 0);
subItems = new ListViewItem.ListViewSubItem[]{new ListViewItem.ListViewSubItem(item, "File Folder"),
new ListViewItem.ListViewSubItem(item,dir.LastAccessTime.ToShortDateString())};
item.SubItems.AddRange(subItems);
listView.Items.Add(item);
item.BackColor = SystemColors.Window;
item.ForeColor = SystemColors.WindowText;
}
foreach (FileInfo file in nodeDirInfo.GetFiles())
{
long B = 0, KB = 1024, MB = KB * 1024, GB = MB * 1024;
string suffix = nameof(B);
if (file.Length >= GB)
{
size = Math.Round((double)file.Length / GB, 2);
suffix = nameof(GB);
filelength = size + " " + suffix;
}
else if (file.Length >= MB)
{
size = Math.Round((double)file.Length / MB, 2);
suffix = nameof(MB);
filelength = size + " " + suffix;
}
else if (file.Length >= KB)
{
size = Math.Round((double)file.Length / KB, 2);
suffix = nameof(KB);
filelength = size + " " + suffix;
}
item = new ListViewItem(file.Name, 1);
subItems = new ListViewItem.ListViewSubItem[]{ new ListViewItem.ListViewSubItem(item, "File"),
new ListViewItem.ListViewSubItem(item,file.LastAccessTime.ToShortDateString()),
new ListViewItem.ListViewSubItem(item,filelength.ToString())};
item.SubItems.AddRange(subItems);
listView.Items.Add(item);
}
listView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
}
private void listView_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (ListViewItem item in listView.Items)
{
item.BackColor = SystemColors.Window;
item.ForeColor = SystemColors.WindowText;
}
}
private void listView_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (listView.SelectedItems.Count > 0)
{
if (!string.IsNullOrEmpty(listView.SelectedItems[0].Text))
{
string SelectedPath_Combine = #"" + SelectedPath + "\\" + listView.SelectedItems[0].Text + "";
FileAttributes attr = File.GetAttributes(#"" + SelectedPath_Combine + "");
if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
{
System.Diagnostics.Process.Start(SelectedPath_Combine);
}
else if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
{
// What to code here to display the files which are present in the folder??
}
}
}
}
You need to make three changes in the code to achieve what you want
Make PopulateTreeView method to take path argument from outside
If Directory info check is successful in above method, empty all nodes before adding new
Call PopulateTreeView with selectedCombine path
Here is updated code
private void PopulateTreeView(string path)
{
TreeNode rootNode;
{
DirectoryInfo info = new DirectoryInfo(path);
if (info.Exists)
{
treeView.Nodes.Clear();
rootNode = new TreeNode(info.Name);
rootNode.Tag = info;
GetDirectories(info.GetDirectories(), rootNode);
treeView.Nodes.Add(rootNode);
LoadFiles(info.FullName, rootNode);
}
else
MessageBox.Show("Please select a path");
}
}
private void ListView_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (listView.SelectedItems.Count > 0)
{
if (!string.IsNullOrEmpty(listView.SelectedItems[0].Text))
{
string SelectedPath_Combine = #"" + SelectedPath + "\\" + listView.SelectedItems[0].Text + "";
FileAttributes attr = File.GetAttributes(#"" + SelectedPath_Combine + "");
if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
{
System.Diagnostics.Process.Start(SelectedPath_Combine);
}
else if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
{
PopulateTreeView(SelectedPath_Combine);
}
}
}
}
I'm working on a windows application using C# on Microsoft Visual C# 2010.
The application is to help the user change the names of multiple files in a directory at once. For example:
I have five files in a directory c:/temp named:
rainmoon.txt
terrain.txt
things.txt
pipe.txt
temp.txt
If I try to rename "rainmoon.txt" to say, "rainsun.txt", then I just have to type that I only want to replace "moon" with "sun". My application is in such a way that it will browse through all the files that contains "moon" and then proceed to replace it with "sun"
The problem comes when both a file name (temp.txt) and a folder (also named temp) that the file is in have the same name. So for the example given above, if I try to rename even part of "temp.txt", I get a DirectoryNotFoundException.
Below is the code that I used. I've tried my best to troubleshoot this area, and I strongly feel it is due to File.Move.
for (int x = 0; x <= filesCheckList.CheckedItems.Count - 1; x++)
{
globalvar.fName = filesCheckList.CheckedItems[x].ToString();
DirectoryInfo mydir = new DirectoryInfo(globalvar.DIR);
FileInfo[] filesx = mydir.GetFiles(".", SearchOption.AllDirectories);
FileInfo[] f = mydir.GetFiles();
foreach (FileInfo file in filesx)
{
//try
{
if (file.Name == globalvar.fName)
{
if (file.Name != "History.txt")
File.Move(file.FullName, file.FullName.ToString().Replace(globalvar.FIL, globalvar.REP));
}
}
}
}
My full code is below in case anyone wants to take a look. I won't rule out that maybe somewhere in the coding is causing this issue.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace TOMOD_W_A
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
applyButton.Enabled = false;
}
private void applyButton_Click(object sender, EventArgs e)
{
globalvar.FIL = filTxt.Text;
globalvar.REP = repTxt.Text;
if (string.IsNullOrWhiteSpace(dirTxt.Text))
MessageBox.Show("Please Key in a Directory");
else if (globalvar.FIL == String.Empty)
MessageBox.Show("Please give a file name");
else
{
try
{
if (filesCheckList.CheckedItems.Count != 0)
{
for (int x = 0; x <= filesCheckList.CheckedItems.Count - 1; x++)
{
globalvar.fName = filesCheckList.CheckedItems[x].ToString();
DirectoryInfo mydir = new DirectoryInfo(globalvar.DIR);
//DirectoryInfo[] directories = mydir.GetDirectories(".", SearchOption.TopDirectoryOnly);
FileInfo[] filesx = mydir.GetFiles(".", SearchOption.AllDirectories);
FileInfo[] f = mydir.GetFiles();
foreach (FileInfo file in filesx)
{
//try
{
if (file.Name == globalvar.fName)
{
if (file.Name != "History.txt")
File.Move(file.FullName, file.FullName.ToString().Replace(globalvar.FIL, globalvar.REP));
}
}
/*****************************
globalvar.DIR = dirTxt.Text;
DirectoryInfo mydir = new DirectoryInfo(globalvar.DIR);
FileInfo[] filesx = mydir.GetFiles(".", SearchOption.AllDirectories);
FileInfo[] f = mydir.GetFiles();
filesCheckList.Items.Clear();
foreach (FileInfo file in filesx)
{
if (file.Name != "History.txt")
filesCheckList.Items.Add(file.Name);
}
* */
/* catch (IOException)
{
MessageBox.Show("File names cannot be the same in the same folder");
MessageBox.Show("File name cannot be empty");
}
catch (ArgumentException)
{
MessageBox.Show("Cannot contain symbols / \\ : * ? < > | \" \n File name cannot be con");
}*/
}
}
}
}
catch (ArgumentNullException)
{
MessageBox.Show("Please key in a directory");
}
//if (File.Exists(globalvar.DIR + #"\History.txt"))
try
{
string content = File.ReadAllText(globalvar.DIR + #"\History.txt");
File.WriteAllText(globalvar.DIR + #"\History.txt", String.Empty);
/* using (System.IO.StreamWriter files = new System.IO.StreamWriter(globalvar.DIR + #"\History.txt", true))
{
files.WriteLine("For multiple files:");
files.WriteLine("Changed " + "\"" + globalvar.FIL + "\"" + " to " + "\"" + globalvar.REP + "\"");
DirectoryInfo mydir = new DirectoryInfo(globalvar.DIR);
FileInfo[] f = mydir.GetFiles();
globalvar.clear = 1;
foreach (FileInfo file in f)
{
if (file.Name != "History.txt")
files.WriteLine(file.Name);
}
for (int x = 0; x <= filesCheckList.CheckedItems.Count - 1; x++)
{
files.WriteLine("in " + filesCheckList.CheckedItems[x].ToString() + "\n");
}
files.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
files.WriteLine("\n");
files.WriteLine(content);
} */
}
catch (FileNotFoundException)
{
using (System.IO.StreamWriter files = File.CreateText(globalvar.DIR + #"\History.txt"))
{
files.WriteLine("For multiple files:");
files.WriteLine("Changed " + "\"" + globalvar.FIL + "\"" + " to " + "\"" + globalvar.REP + "\"");
files.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
files.WriteLine("\n");
}
}
MessageBox.Show("Your selected files have been changed");
}
}
private void cancelButton_Click(object sender, EventArgs e)
{
this.Close();
}
public static class globalvar
{
public static string DIR;
public static string FIL;
public static string REP;
public static string OPT;
public static string fName;
public static int clear = 0;
public static int proceed = 0;
public static int filpro = 0;
public static int cignm = 0;
public static int mngic = 0;
}
private void browseButton_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
dirTxt.Text = folderBrowserDialog1.SelectedPath;
}
private void shfilButton_Click(object sender, EventArgs e)
{
applyButton.Enabled = true;
try
{
globalvar.DIR = dirTxt.Text;
DirectoryInfo mydir = new DirectoryInfo(globalvar.DIR);
FileInfo[] filesx = mydir.GetFiles(".", SearchOption.AllDirectories);
FileInfo[] f = mydir.GetFiles();
filesCheckList.Items.Clear();
foreach (FileInfo file in filesx)
{
if (file.Name != "History.txt")
filesCheckList.Items.Add(file.Name);
}
}
catch (DirectoryNotFoundException)
{
MessageBox.Show("Directory not found");
}
catch (ArgumentException)
{
MessageBox.Show("Directory not found");
}
catch (IOException)
{
MessageBox.Show("Directory is invalid");
}
}
private void filChk_CheckedChanged(object sender, EventArgs e)
{
if (filChk.Checked)
{
for (int i = 0; i < filesCheckList.Items.Count; i++)
{
filesCheckList.SetItemChecked(i, true);
}
}
else
{
for (int i = 0; i < filesCheckList.Items.Count; i++)
{
filesCheckList.SetItemChecked(i, false);
}
}
}
private void dirTxt_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
try
{
globalvar.DIR = dirTxt.Text;
DirectoryInfo mydir = new DirectoryInfo(globalvar.DIR);
FileInfo[] f = mydir.GetFiles();
globalvar.clear = 1;
filesCheckList.Items.Clear();
foreach (FileInfo file in f)
{
if (file.Name != "History.txt")
filesCheckList.Items.Add(file.Name);
}
}
catch (DirectoryNotFoundException)
{
MessageBox.Show("Directory not found");
}
catch (ArgumentException)
{
MessageBox.Show("Directory not found");
}
catch (IOException)
{
MessageBox.Show("Directory is invalid");
}
}
}
private void dirTxt_TextChanged(object sender, EventArgs e)
{
}
}
}
Problem is there
file.FullName.ToString().Replace(globalvar.FIL, globalvar.REP)
file.FullName is full path like C:\Temp\Temp.txt so when You replace string 'Temp' by 'abc' you got C:\abc\abc.txt. But there is no such folder 'abc'
You should combine new path like that:
file.Directory.FullName.ToString() + file.Name.ToString().Replace(globalvar.FIL, globalvar.REP)
I strongly feel it is due to File.Move.
Old citation: "if you think .net or the JVM is broken, it's time for a break".
Also your code is not pretty, I would definitely recommend you to read this kind of book: http://www.amazon.fr/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882
But let's forget about that for now.
Please put a break point on this line:
File.Move(file.FullName, file.FullName.ToString().Replace(globalvar.FIL, globalvar.REP));
Now run your code with an example where your file and folder have the same name.
What do you see?
Yes, file.FullName actually contains the name of the folder AND the name of the file. Now what happens if you do:
file.FullName.ToString().Replace(globalvar.FIL, globalvar.REP))
You will rename both the file AND the folder.
For example, with an initial file:
c:/temp/temp.txt
Replace temp by sun and you got c:/sun/sun.txt
As you need to create the folder first, .NET says "c:/sun" does not exist.
As I understand your usecase, what you want is only the filename:
file.Name.Replace(globalvar.FIL, globalvar.REP))
So you should record the folder name, just rename the file and move it into folder + newfileName.
Hope it helps.
I Made an application to download a folder from a given sharepoint site, but its consuming memory above 600,000K once i click on Connect button, anyone can give suggestion to improve my code ?
I Tried to debug my form and problem is coming at method " private void MapWebs(SPWebCollection webList, TreeNode webparentNode)" where its calling itself again and again to go through each single web and its sub web, however I checked in the start when i click on connect and it goes through code line
using (SPSite CurrentSite = new SPSite(tbSite.Text))
The memory usage goes from 20,000 K to 40,000 K (approx)
In order to run this application you must have sharepoint installed on yur PC, an example of this type of app is on this link ,
enter link description here
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using System.IO;
namespace WindowsFormsApplication3
{
public partial class MainWindow : Form
{
public MainWindow()
{
InitializeComponent();
}
//Connects to Sharepoint site provided and populates Webs and Subwebs and subwebs....
private void bConnect_Click(object sender, EventArgs e)
{
//Getting current site
using (SPSite CurrentSite = new SPSite(tbSite.Text))
{
//Opening TopLevel Web for Site given
using (SPWeb TopLevelWeb = CurrentSite.OpenWeb())
{
//Clearing all the nodes in TreeWeb
TreeWeb.Nodes.Clear();
//Creating a root (First Node for webtree) which will be Top Level web's title
TreeNode rootWebNode = new TreeNode(TopLevelWeb.Title);
//Giving node a tag, which will be used later on in order to get value of node
rootWebNode.Tag = TopLevelWeb;
//Check if Top Level Web got any Sub webs if it does, it will create a new node for them
//Calls Map Webs to check for more sub webs + mapping them on webtree as nodes
foreach (SPWeb CurrentWeb in TopLevelWeb.Webs)
{
try
{
TreeNode webNode = new TreeNode(CurrentWeb.Title);
webNode.Tag = CurrentWeb;
MapWebs(CurrentWeb.Webs, webNode);
TreeWeb.Nodes.Add(webNode);
}
finally
{
if (CurrentWeb != null)
CurrentWeb.Dispose();
}
}
}
}
}
// Maps Webs and there sub webs on webtree
private void MapWebs(SPWebCollection webList, TreeNode webparentNode)
{
for (var i = 0; i < webList.Count; i++)
{
TreeNode node = new TreeNode(webList[i].Name);
using (SPWeb web = webList[i])
{
node.Tag = webList[i];
webparentNode.Nodes.Add(node);
if (webList[i].Webs.Count > 0)
MapWebs(webList[i].Webs, node);
}
}
GC.Collect();
}
//when the form loads it clears the list and create new cloumns to be used
private void MainWindow_Load(object sender, EventArgs e)
{
bFolder.Enabled = false;
bConnect.Enabled = false;
lvFiles.GridLines = true;
lvFiles.View = View.Details;
lvFiles.Columns.Add("Name", lvFiles.Width/4, HorizontalAlignment.Left);
lvFiles.Columns.Add("Date Created", lvFiles.Width/3, HorizontalAlignment.Left);
lvFiles.Columns.Add("Size", lvFiles.Width / 5, HorizontalAlignment.Left);
lvFiles.Columns.Add("Time Last Modified", lvFiles.Width / 5, HorizontalAlignment.Left);
if (lvFiles.View == View.Details && lvFiles.Columns.Count > 0)
this.Width = lvFiles.Columns.Count * (lvFiles.Width / 2);
lvFiles.Columns[lvFiles.Columns.Count - 1].Width = -2;
}
//creates directory for downloading folder
private bool CreateDirectoryStructure(string baseFolder, string filepath)
{
if (!Directory.Exists(baseFolder)) return false;
var paths = filepath.Split('/');
for (var i = 0; i < paths.Length - 1; i++)
{
baseFolder = System.IO.Path.Combine(baseFolder, paths[i]);
Directory.CreateDirectory(baseFolder);
}
return true;
}
//opens an dialog box for selecting path where selected folder will be downloaded
private void bBrowse_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
this.tbDirectory.Text = folderBrowserDialog1.SelectedPath;
}
}
//when a node is selected in webtree it checks for folders in it , + sub folders + folders......
private void TreeWeb_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeFolder.Nodes.Clear();
TreeNode currentNode = TreeWeb.SelectedNode;
using (SPWeb oWeb = (SPWeb)currentNode.Tag)
{
foreach (SPList list in oWeb.Lists)
{
if (list is SPDocumentLibrary && !list.Hidden)
{
TreeNode folderNode = new TreeNode(list.Title);
folderNode.Text = string.Format("{0} ({1})", list.Title, list.ItemCount);
folderNode.Tag = list.RootFolder;
foreach (SPListItem listItem in list.Folders)
{
if (listItem.Folder != null)
{
TreeNode node = new TreeNode(listItem.Folder.Name);
node.Tag = listItem.Folder;
node.Text = string.Format("{0} ({1})", listItem.Folder.Name,
GetFilesCount(listItem.Folder));
MapFolders(listItem.Folder.SubFolders, node);
folderNode.Nodes.Add(node);
}
}
TreeFolder.Nodes.Add(folderNode);
}
}
}
}
//Maps folder on foldertree
private void MapFolders(SPFolderCollection folderList, TreeNode parentNode)
{
for (var i = 0; i < folderList.Count; i++)
{
TreeNode node = new TreeNode(folderList[i].Name);
node.Text = string.Format("{0} ({1})", folderList[i].Name,
GetFilesCount(folderList[i]));
node.Tag = folderList[i];
parentNode.Nodes.Add(node);
if (folderList[i].SubFolders.Count > 0)
MapFolders(folderList[i].SubFolders, node);
}
}
//Maps files in a folder to listview
private void TreeFolder_AfterSelect(object sender, TreeViewEventArgs e)
{
lvFiles.Items.Clear();
TreeNode currentNode = TreeFolder.SelectedNode;
//if (currentNode != rotnode)
//{
double TotalSize = 0;
SPFolder oFolder = (SPFolder)currentNode.Tag;
foreach (SPFile oFile in oFolder.Files)
{
TotalSize += (oFile.Length)/1024/1024;
ListViewItem LTI = new ListViewItem(oFile.Name.ToString());
LTI.SubItems.Add(oFile.TimeCreated.ToString());
LTI.SubItems.Add(oFile.Length.ToString());
LTI.SubItems.Add(oFile.TimeLastModified.ToString());
lvFiles.Items.Add(LTI);
}
label4.Text = TotalSize.ToString();
//}
}
//download selected folder + validation
private void bFolder_Click(object sender, EventArgs e)
{
TreeNode currentNode = TreeFolder.SelectedNode;
SPFolder oFolder = (SPFolder)currentNode.Tag;
foreach (SPFile file in oFolder.Files)
{
if (CreateDirectoryStructure(tbDirectory.Text, file.Url))
{
var filepath = System.IO.Path.Combine(tbDirectory.Text, file.Url);
byte[] binFile = file.OpenBinary();
System.IO.FileStream fstream = System.IO.File.Create(filepath);
fstream.Write(binFile, 0, binFile.Length);
fstream.Close();
}
}
}
//calculates files in selected folder
private int GetFilesCount(SPFolder folder)
{
int fileCount = folder.Files.Count;
foreach (SPFolder subfolder in folder.SubFolders)
{
fileCount += GetFilesCount(subfolder);
}
return fileCount;
}
//validation
private void tbSite_TextChanged(object sender, EventArgs e)
{
if (tbSite.Text != "")
bConnect.Enabled = true;
else
bConnect.Enabled = false;
}
//validation
private void tbDirectory_TextChanged(object sender, EventArgs e)
{
if (tbDirectory.Text != "" && TreeFolder.Nodes.Count != 0)
bFolder.Enabled = true;
else
bFolder.Enabled = false;
}
}
}
Already checked with SP Dispose checker but it says this (at MapWebs method line "node.tag = weblist[i]... and if statement")
Notes: Call to Microsoft.SharePoint.SPWebCollection.get_Item and no variable to catch return value
More Information: http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx#SPDisposeCheckID_130
I see two issues here:
You are disposing the SPWeb while iterating over the SPWeb.Webs, but you keep a reference on the TreeNode.Tag. When accessing the disposed SPWeb via the tag of the node SharePoint will "open" the web again. => Memory Leak
Since you are calling the MapWebs method recursive you have a lot of SPWeb objects opened simultaneously:
Root -> open
Child 1 -> open
Child 1.1 -> open
Child 1.1.1 -> open
Child 1.2
Child 1.3
Child 1.4
Child 2
Child 3
I found this code online. It works, but for some reason it loads the file directory twice.
namespace DockSample.Controls
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using Microsoft.VisualBasic.FileIO;
using DockSample;
//TODO: Add options for filtering by robot
public class SolutionExplorer : TreeView
{
public SolutionExplorer()
{
this.BeforeExpand += customBeforeExpand;
this.Nodes.Clear();
CreateTree(this);
}
private bool CreateTree(TreeView treeView)
{
bool returnValue = false;
try
{
// Create Desktop
TreeNode desktop = new TreeNode();
// desktop.Text = "Desktop";
// desktop.Tag = "Desktop";
// desktop.Nodes.Add("");
// treeView.Nodes.Add(desktop);
// Get driveInfo
foreach (DriveInfo drv in DriveInfo.GetDrives())
{
TreeNode fChild = new TreeNode();
if (drv.DriveType == DriveType.CDRom)
{
fChild.ImageIndex = 1;
fChild.SelectedImageIndex = 1;
}
else if (drv.DriveType == DriveType.Fixed)
{
fChild.ImageIndex = 0;
fChild.SelectedImageIndex = 0;
}
fChild.Text = drv.Name;
fChild.Nodes.Add("");
treeView.Nodes.Add(fChild);
returnValue = true;
}
}
catch
{
returnValue = false;
}
return returnValue;
}
/* Method :EnumerateDirectory
* Author : Chandana Subasinghe
* Date : 10/03/2006
* Discription : This is use to Enumerate directories and files
*
*/
public TreeNode EnumerateDirectory(TreeNode parentNode, List<string> thisFilter)
{
try
{
DirectoryInfo rootDir;
// To fill Desktop
Char[] arr = { '\\' };
string[] nameList = parentNode.FullPath.Split(arr);
string path = "";
if (nameList.GetValue(0).ToString() == "Desktop")
{
path = SpecialDirectories.Desktop + "\\";
for (int i = 1; i < nameList.Length; i++)
{
path = path + nameList[i] + "\\";
}
rootDir = new DirectoryInfo(path);
}
// for other Directories
else
{
rootDir = new DirectoryInfo(parentNode.FullPath + "\\");
}
parentNode.Nodes[0].Remove();
foreach (DirectoryInfo dir in rootDir.GetDirectories())
{
TreeNode node = new TreeNode();
node.Text = dir.Name;
node.Nodes.Add("");
parentNode.Nodes.Add(node);
}
//Fill files
foreach (FileInfo file in rootDir.GetFiles())
{
if (isValidFilter(getExtention(file.Name)))
{
TreeNode node = new TreeNode();
node.Text = file.Name;
node.ImageIndex = 2;
node.SelectedImageIndex = 2;
parentNode.Nodes.Add(node);
}
}
}
catch
{
}
return parentNode;
}
private bool isValidFilter(string ext)
{
bool result = false;
foreach(string s in filter)
{
if (ext == s)
result = true;
}
return result;
}
private string getExtention(string filename)
{
return filename.Substring(filename.IndexOf("."));
}
private void customBeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Nodes[0].Text == "")
{
TreeNode node = this.EnumerateDirectory(e.Node,filter);
}
}
private List<string> filter = new List<string>();
public List<string> Filter
{
get { return filter; }
set { filter = value; }
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
}
The constructor of your control runs at both design time and run time. So as soon as you drop the control on the form, it will fill the tree view. Problem is, the nodes will be serialized to InitializeComponent(). Take a look at the Designer.cs file for your form, you'll find them back there. When you run the form, the constructor runs again, doubling the list.
You need to prevent the constructor from adding the nodes at design time. That's a bit difficult to do, you'd normally use the DesignMode property but it isn't set to true yet in the constructor. Do it like this instead:
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
if (!DesignMode && treeView.Nodes.Count == 0) {
CreateTree(this);
}
}
Or do it explicitly by adding a public method that you call in the form's constructor or OnLoad method. Which is rather wise, you might want to catch exceptions. Always likely when you tinker with the file system.