I have created something that grabs all file names that have the extension .lua with them. This will then list them in a CheckListBox. Everything goes well there but I want to know which one of the CheckListBox's are ticked/checked and then open them in notepad.exe.
To dynamically add the files Code (works perfectly, and adds the files i want)
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = appData + "\\Lua";
string[] fileArray = Directory.GetFiles(path, "*.lua");
for (int i = 0; i < fileArray.Length; i++)
{
string Name = Path.GetFileName(fileArray[i]);
string PathToLua = fileArray[i];
ScriptsBoxBox.Items.AddRange(Name.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
Console.WriteLine(fileArray[i]);
}
Then when i check the items i want to open in notepad i use `
System.Diagnostics.Process.Start("notepad.exe", ScriptsBoxBox.CheckedItems.ToString());
Or
System.Diagnostics.Process.Start("notepad.exe", ScriptsBoxBox.CheckedItems);
Neither works and im pretty sure it's on my end. So my problem is that i cannot open the file that is ticked/checked in checklistbox and want to resolve this problem. However when I do
System.Diagnostics.Process.Start("notepad.exe", PathToLua);
It opens the files with .lua extension ticked or not which makes sense.
I don't think there are any arguments that you can pass to notepad to open a list of specific files. However, you can use a loop to open each file.
foreach (var file in ScriptsBoxBox.CheckedItems)
{
System.Diagnostics.Process.Start("notepad.exe", file);
}
I don't know WinForms as well as WPF but here goes
You need an object that contains your values
public class LuaFile
{
public string FileName { get; set; }
public string FilePath { get; set; }
public LuaFile(string name, string path)
{
FileName = name;
FilePath = path;
}
public override string ToString()
{
return FileName;
}
}
Replace your for loop with
foreach (var file in files)
{
ScriptsBoxBox.Items.Add(new LuaFile(Path.GetFileName(file), file));
}
And to run the checked files
foreach (var file in ScriptsBoxBox.CheckedItems)
{
System.Diagnostics.Process.Start("notepad.exe", ((LuaFile)file).FilePath);
}
Thanks everyone that helped but I solved it on my own (pretty easy when you read :P)
For anyone in the future that wants to do this here is how i accomplished it.
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = appData + "\\Lua";
string[] fileArray = Directory.GetFiles(path, "*.lua");
for (int i = 0; i < fileArray.Length; i++)
{
string Name = Path.GetFileName(fileArray[i]);
string PathToLua = fileArray[i];
//ScriptsBoxBox.Items.AddRange(Name.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
// Console.WriteLine();
Console.WriteLine(ScriptsBoxBox.CheckedItems.Contains(Name));
var pathname = ScriptsBoxBox.CheckedItems.Contains(Name);
if (ScriptsBoxBox.CheckedItems.Contains(Name))
{
System.Diagnostics.Process.Start("notepad.exe", fileArray[ScriptsBoxBox.CheckedItems.IndexOf(Name)]); // I supposed this would get the correct name index, and it did! fileArray by default seems to get the path of the file.
}
Related
:)
So I have a hw (I have to run project from console): I have to count the number of sub directories in specific directory (the user writes in this way " [path] [extension] [-r] ")
So if user writes the directory and doesn't write the extension, my program just counts the number of sub directories.
BUT if user writes the parameter, for example, .exe, .txt, .cs, I have to count the number of files with this specific extension in the specific directory and return this number.
Sooo, everything is good with the first part - my program works correctly and count the number of sub directories, recursively (if I write the parameter -r) or not (if I don't). The problem is with counting files with extension.
Here is my function for counting sub directories:
class Data
{
public string curDir = Directory.GetCurrentDirectory();
public string Extension = "";
public bool isRecursive;
}
public static int CountDir(Data data)
{
string[] dirs = Directory.GetDirectories(data.curDir);
int res = dirs.Length;
int resFiles = files.Length;
try
{
if (data.isRecursive)
{
foreach (string subdir in dirs)
{
Data d = new Data();
d.curDir = subdir;
d.Extension = data.Extension;
d.isRecursive = data.isRecursive;
res += CountDir(d);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
return res;
}
So I tried to do the similar thing in this method, but for files and I'm a bit confused:
string[] files = Directory.GetFiles(data.curDir);
int resFiles = files.Length;
foreach (string ext in files)
{
FileInfo fi = new FileInfo(ext);
if (data.Extension != "")
{
if (fi.Extension == data.Extension)
{
//res = 0;
//++res;
//what am I supposed to do here?..
}
}
}
I also wonder if I can do this in the same method (CountDir).
Thank you so much in advance!
Edit: I know about SearchOptions.AllDirectories method, but I don't know in advance which extension user will write
I would put the file count logic in its own method since the goal is to get the number of files for a specific directory rather than all sub-directories. Here's an example based on your sample code:
public static int countFiles(Data data)
{
string[] files = new string[0];
try
{
files = Directory.GetFiles(data.curDir, $"*{data.Extension}");
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
return files.Length;
}
I have many .cshtml pages available in view folder of my MVC project. In my layout page there is search option available, so when someone search by any word, then I want to search that word in all .cshtml pages and return view name.
how can i achieve this in MVC?
A possible way to do this:
string path = Server.MapPath("~/Views"); //path to start searching.
if (Directory.Exists(path))
{
ProcessDirectory(path);
}
//Loop through each file and directory of provided path.
public void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (string fileName in fileEntries)
{
string found = ProcessFile(fileName);
}
//Recursive loop through subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
{
ProcessDirectory(subdirectory);
}
}
//Get contents of file and search specified text.
public string ProcessFile(string filepath)
{
string content = string.Empty;
string strWordSearched = "test";
using (var stream = new StreamReader(filepath))
{
content = stream.ReadToEnd();
int index = content.IndexOf(strWordSearched);
if (index > -1)
{
return Path.GetFileName(filepath);
}
}
}
I want to find all files in whole harddrive (.jpg, .png, .apk and a few other formats) but this code is not working..all it does is : for example if in my 'D:\' drive I have: 1)a image file 'i1', 2)a folder 'f1' which has image file and 3) another folder 'f2' which has image file and 'f2' contains folder 'f3' which has image file .It only performs 'calcFile()' on contents inside f1 and f2 but not on contents of f3 and i1 same happens with all other partitions .What is wrong here? Any help is appreciated.
I hope you understand what is happening because that's the easiest way I could explain my situation, if more info is required just tell me. thanks :)
public void calcDirectory(string token)
{
var validExtensions = new[]
{
".jpg", ".png", ".apk"
};
foreach (string s in Directory.GetLogicalDrives())
{
DriveInfo driveInfo = new DriveInfo(s);
if (driveInfo.IsReady)
{
foreach (string d in Directory.GetDirectories(s))
{
FileAttributes attrs1 = File.GetAttributes(d);
if (!attrs1.HasFlag(FileAttributes.ReparsePoint))
{
if (!attrs1.HasFlag(FileAttributes.System))
{
string[] allFilesInDir = Directory.GetFiles(d);
for (int i = 0; i < allFilesInDir.Length; i++)
{
string file = allFilesInDir[i];
string extension = Path.GetExtension(file);
if (validExtensions.Contains(extension))
{
string p = Path.GetFullPath(file);
FileAttributes attrs = File.GetAttributes(p);
if (attrs.HasFlag(FileAttributes.ReadOnly))
{
File.SetAttributes(p, attrs & ~FileAttributes.ReadOnly);
calcFile(file, token);
}
else
{
calcFile(file, token);
}
}
}
}
}
}
}
}
}
and I call the calcDirectory() here
public void start()
{
string token = File.ReadAllText(tokencalcalculated);
calcDirectory(token);
}
I created a function based on your code that will recursively search the directory for anything matching your pattern. You'll have to call this from your loop of the base directories.
public static void crawlDirectory(string token,string directory)
{
if (string.IsNullOrEmpty(directory)) return;
var validExtensions = new[]
{
".jpg", ".png", ".apk"
};
foreach (string d in Directory.GetDirectories(directory))
{
FileAttributes attrs1 = File.GetAttributes(d);
if (!attrs1.HasFlag(FileAttributes.ReparsePoint) && !attrs1.HasFlag(FileAttributes.System))
{
string[] allFilesInDir = Directory.GetFiles(d);
for (int i = 0; i < allFilesInDir.Length; i++)
{
string file = allFilesInDir[i];
string extension = Path.GetExtension(file);
if (validExtensions.Contains(extension))
{
string p = Path.GetFullPath(file);
FileAttributes attrs = File.GetAttributes(p);
if (attrs.HasFlag(FileAttributes.ReadOnly))
{
File.SetAttributes(p, attrs & ~FileAttributes.ReadOnly);
calcFile(file, token);
}
else
{
calcFile(file, token);
}
}
}
}
crawlDirectory(d, token);
}
}
You are only enumerating the root directories but no subdirectories. Instead of Directory.GetDirectories(s) use
foreach(string d in Directory.GetDirectories(s, "*", SearchOption.AllDirectories))
But be aware of infinite loops due to links in your subdirectories (see MSDN on SearchOption.AllDirectories).
And you should be aware of user access rights. You should put a try...catch around your GetFiles part in case you don't have access rights for a specific directory (See this question).
Ok, so I have made some code here
which will list all the directories and what I want to do is to display the folder names but when selected and push save it saves the file path not just the name
codes
the file look folder
FolderBrowserDialog elfenliedtopfan5wins = new FolderBrowserDialog();
// elfenliedtopfan5wins.RootFolder = Environment.SpecialFolder.ProgramFiles;
if (elfenliedtopfan5wins.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// test 1
// Example #1: Write an array of strings to a file.
// Create a string array that consists of three lines. //raw = 0 \\raw\\images = 1 \\raw\\weapons = 2 \\raw\\weapons = 3 \\raw\\xmodel = 4 \\raw\\xmodelparts = 5 \\raw\\xmodelsurfs = 6
string[] lines = { elfenliedtopfan5wins.SelectedPath + "\\raw" };
// and then closes the file.
System.IO.File.WriteAllLines(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\elfenlied_weapons\\path.txt", lines);
string rawsave = elfenliedtopfan5wins.SelectedPath;
Properties.Settings.Default.rawpath = rawsave;
Properties.Settings.Default.Save();
listbox();
copyfilealais();
public void listbox()
{
LOADMOD.Items.Clear();
string[] getfiles = Directory.GetFiles(Properties.Settings.Default.rawpath + "\\mods");
string[] dirs = Directory.GetDirectories(Properties.Settings.Default.rawpath + "\\mods");
foreach(string file in getfiles)
{
LOADMOD.Items.Add(file);
}
foreach (string dir in dirs)
{
LOADMOD.Items.Add(dir);
}
}
this way it works file but I don't want to show the path in the listbox. I just want the name of the folders which I added.
foreach(string file in getfiles)
{
LOADMOD.Items.Add(path.getfilename(file));
}
foreach (string dir in dirs)
{
LOADMOD.Items.Add(path.getfilename(dir));
}
Which shows like this which is what I want but when I push save it just saves name of the folder aka this
so I was wording is their a way to have it like this picture with all folder names shown but when I push save it saves the file path not just the name?
image of what i want it to be like but to save the path instead of the folder name
the save button
private void buttonX7_Click(object sender, EventArgs e)
{
Properties.Settings.Default.modpath = LOADMOD.SelectedItem.ToString();
// testing to see if it saves file path
MessageBox.Show(Properties.Settings.Default.modpath);
richTextBoxEx1.LoadFile(Properties.Settings.Default.modpath + "//mod.csv", RichTextBoxStreamType.PlainText);
}
and I still want it to save the path but only way it does that if i don't include path.getfilename
does anyone have any-idea how i would be able to do this ?
Instead of keep File name or File path in each Listbox item, you can keep an object in it, then play with DisplayMember and ValueMember properties of the ListBox.
In this scenario you need define just one simple class for your all Listbox items and create an instance of it for each item. In the following sample this class is MyType.
Inside MyType.cs file:
public class MyType
{
public string Name {get; set;}
public string Path {get; set;}
}
Inside your main class:
public void listbox()
{
LOADMOD.Items.Clear();
string[] getfiles = Directory.GetFiles(Properties.Settings.Default.rawpath + "\\mods");
string[] dirs = Directory.GetDirectories(Properties.Settings.Default.rawpath + "\\mods");
LOADMOD.DisplayMember = "Name";
LOADMOD.ValueMember = "Path";
foreach(string file in getfiles)
{
// Create an item for the list
var thisItem = new MyType {
Name = path.getfilename(file),
Path = file
};
LOADMOD.Items.Add(thisItem);
}
foreach (string dir in dirs)
{
// Create an item for the list
var thisItem = new MyType {
Name = path.getfilename(dir),
Path = dir
};
LOADMOD.Items.Add(thisItem);
}
}
Now you can use it with Text and SelectedValue properties of the ListBox. When you select an item you can write some codes like these:
string MyName = LOADMOD.Text;
string MyPath = LOADMOD.SelectedValue;
// Now You have both Name and Path of your file or directory here
MessageBox.Show(MyName);
MessageBox.Show(MyPath);
I am rookie in C#, but I need solve one Problem.
I have several text files in Folder and each text files has this structure:
IdNr 000000100
Name Name
Lastname Lastname
Sex M
.... etc...
Load all files from Folder, this is no Problem ,but i need delete "zero" in IdNr, so delete 000000 and 100 leave there. After this file save. Each files had other IdNr, Therefore, it is harder :(
Yes, it is possible each files manual edit, but when i have 3000 files, this is not good :)
Can C# one algorithm, which could this 000000 delete and leave only number 100?
Thank you All.
Vaclav
So, thank you ALL !
But in the End I have this Code :-) :
using System.IO;
namespace name
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Browse_Click(object sender, EventArgs e)
{
DialogResult dialog = folderBrowserDialog1.ShowDialog();
if (dialog == DialogResult.OK)
TP_zdroj.Text = folderBrowserDialog1.SelectedPath;
}
private void start_Click(object sender, EventArgs e)
{
try
{
foreach (string file in Directory.GetFiles(TP_zdroj.Text, "*.txt"))
{
string text = File.ReadAllText(file, Encoding.Default);
text = System.Text.RegularExpressions.Regex.Replace(text, "IdNr 000*", "IdNr ");
File.WriteAllText(file, text, Encoding.Default);
}
}
catch
{
MessageBox.Show("Warning...!");
return;
}
{
MessageBox.Show("Done");
}
}
}
}
Thank you ALL ! ;)
You can use int.Parse:
int number = int.Parse("000000100");
String withoutzeros = number.ToString();
According to your read/save file issue, do the files contain more than one record, is that the header or does each record is a list of key and value like "IdNr 000000100"? It's difficult to answer without these informations.
Edit: Here's a simple but efficient approach which should work if the format is strict:
var files = Directory.EnumerateFiles(path, "*.txt", SearchOption.TopDirectoryOnly);
foreach (var fPath in files)
{
String[] oldLines = File.ReadAllLines(fPath); // load into memory is faster when the files are not really huge
String key = "IdNr ";
if (oldLines.Length != 0)
{
IList<String> newLines = new List<String>();
foreach (String line in oldLines)
{
String newLine = line;
if (line.Contains(key))
{
int numberRangeStart = line.IndexOf(key) + key.Length;
int numberRangeEnd = line.IndexOf(" ", numberRangeStart);
String numberStr = line.Substring(numberRangeStart, numberRangeEnd - numberRangeStart);
int number = int.Parse(numberStr);
String withoutZeros = number.ToString();
newLine = line.Replace(key + numberStr, key + withoutZeros);
newLines.Add(line);
}
newLines.Add(newLine);
}
File.WriteAllLines(fPath, newLines);
}
}
Use TrimStart
var trimmedText = number.TrimStart('0');
This should do it. It assumes your files have a .txt extension, and it removes all occurrences of "000000" from each file.
foreach (string fileName in Directory.GetFiles("*.txt"))
{
File.WriteAllText(fileName, File.ReadAllText(fileName).Replace("000000", ""));
}
These are the steps you would want to take:
Loop each file
Read file line by line
for each line split on " " and remove leading zeros from 2nd element
write the new line back to a temp file
after all lines processed, delete original file and rename temp file
do next file
(you can avoid the temp file part by reading each file in full into memory, but depending on your file sizes this may not be practical)
You can remove the leading zeros with something like this:
string s = "000000100";
s = s.TrimStart('0');
Simply, read every token from the file and use this method:
var token = "000000100";
var result = token.TrimStart('0');
You can write a function similar to this one:
static IEnumerable<string> ModifiedLines(string file) {
string line;
using(var reader = File.OpenText(file)) {
while((line = reader.ReadLine()) != null) {
string[] tokens = line.Split(new char[] { ' ' });
line = string.Empty;
foreach (var token in tokens)
{
line += token.TrimStart('0') + " ";
}
yield return line;
}
}
}
Usage:
File.WriteAllLines(file, ModifiedLines(file));