c# getting files form directory - c#

i have problem with my c# code, i want to list all files from mozilla user data folder, i was trying to do it with:
String dir = Directory.GetDirectories(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Mozilla\\Firefox\\Profiles\\")[0];
string[] fileEntries = Directory.GetFiles(Environment.GetEnvironmentVariable("AppData") + "\\Mozilla\\Firefox\\Profiles\\" + dir);
But when i execute this code i get error that tells me that format of this path is not supported. In error info i can see that my path is:
"C:\Users\Marcin\AppData\Roaming\Mozilla\Firefox\Profiles\4wrivbme.default"
Its because of \? I'm sure that i need this.

If I have understood correctly your code, then the second line should be just
string[] fileEntries = Directory.GetFiles(dir);
On my PC your second line gives back this path that is clearly wrong
C:\Users\steve\AppData\Roaming\Mozilla\Firefox\Profiles\C:\Users\steve\AppData.....
^^^^^
So a full fix of your code should be as this
string mozillaProfilePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"Mozilla\\Firefox\\Profiles");
string[] dirs = Directory.GetDirectories(mozillaProfilePath);
if(dirs.Length > 0)
{
string[] fileEntries = Directory.GetFiles(dirs[0]);
......
}
and, if your process the result directly here, then it is better to use Directory.EnumeratFiles instead of GetFiles (See remarks in the link posted)
.....
if(dirs.Length > 0)
{
foreach(string file in Directory.EnumerateFiles(dirs[0]))
{
.... process each file found ...
}
}

Use Path.Combine() instead of string concatenation.

Related

Ignore Empty files C#

I am trying to avoid empty files in my Program and the way i am doing it doesnt work.
I got a machschine that create logs, at Weekend is nobody here and but the maschine create a file with only 5,6 lines, the right one should have 20k lines.
I know there is FileInfo.Length but i dont know how to use it with this what a have right now.
public List<SystemLogFileData> ProcessSystemLogFiles(List<string> systemLogsFilePaths)
{
List<SystemLogFileData> systemLogFilesData = new List<SystemLogFileData>();
foreach (var filePath in systemLogsFilePaths)
{
string[] lines = System.IO.File.ReadAllLines(filePath);
var systemLogFileData = ProcessSystemLogFile(lines.ToList());
if (File.ReadAllText(systemLogFileData).Length > 100)
{
systemLogFilesData.Add(systemLogFileData);
}
}
return systemLogFilesData;
}
I solved it and it works well. Not in my main Program but in Autobackup.
insted of ignoring the the not important file i don't copy them and i reached my goal.
Thakns for the help!
//path of file
string pathToOriginalFile = #"C:\Users\Desktop\c#\Logging\Systemlog.bk66";
//duplicate file path
string PathForDuplicateFile = #"C:\\\Desktop\c#\Systemlog";
//rename fileName if Exists
FixFileName(ref PathForDuplicateFile, ".bk");
if (File.ReadAllText(pathToOriginalFile).Length > 2000)
{
File.Copy(pathToOriginalFile, PathForDuplicateFile);
}
else
{
}
//provide source and destination file paths

How to get the Full Path of a File?

I try to get the Full Path of a File. ie. calc
Input: calc
Expected output: C:\WINDOWS\system32\calc.exe
I could find out how to do it with PowerShell:
(Get-Command calc).Source
Or with CommandLine:
where.exe calc
But unfortunately I can not get it done with C#.
The documentation for Get-Command says:
Get-Command * gets all types of commands, including all of the non-PowerShell files in the Path environment variable ($env:Path), which it lists in the Application command type.
So we will need to get the Path environment variable and iterate over the directories it lists, looking for files with extensions that indicate the file is a program, for example "*.com" and "*.exe".
The problem with the Path environment variable is that it can become polluted with non-existent directories, so we will have to check for those.
The case of the filename and extension don't matter, so case-insensitive comparisons need to be made.
static void ShowPath(string progName)
{
var extensions = new List<string> { ".com", ".exe" };
string envPath = Environment.GetEnvironmentVariable("Path");
var dirs = envPath.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string d in dirs.Where(f => Directory.Exists(f)))
{
foreach (var f in (Directory.EnumerateFiles(d).
Where(thisFile => extensions.Any(h => Path.GetExtension(thisFile).Equals(h, StringComparison.InvariantCultureIgnoreCase)))))
{
if (Path.GetFileNameWithoutExtension(f).Equals(progName, StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine(f);
return;
}
}
}
Console.WriteLine("Not found.");
}
static void Main(string[] args)
{
ShowPath("calc");
Console.ReadLine();
}
Output:
C:\WINDOWS\system32\calc.exe
There is always the possibility that the current user does not have permission to list the files from somewhere in the path, so checks should be added for that. Also, you might want to use StringComparison.CurrentCultureIgnoreCase for the comparison.
You can get the Pathenvironment variable, split it with ; as delimiter and loop over that result. Then, check if the file path + #"\" + name + ".exe" exists.
var findMe = "calc";
var pathes = Environment.GetEnvironmentVariable("Path").Split(';');
foreach (var path in pathes)
{
var testMe = $#"{path}\{findMe}.exe";
if (File.Exists(testMe))
{
Console.WriteLine(testMe);
}
}
This outputs :
C:\WINDOWS\system32\calc.exe
I do not know about any way of doing that exact thing from C# either. However the paths are usually well known and can be retreived via the SpecialFolders Enumeration:
using System;
using System.Diagnostics;
using System.IO;
namespace RunAsAdmin
{
class Program
{
static void Main(string[] args)
{
/*Note: Running a batch file (.bat) or similar script file as admin
Requires starting the interpreter as admin and handing it the file as Parameter
See documentation of Interpreting Programm for details */
//Just getting the Absolute Path for Notepad
string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
string FullPath = Path.Combine(windir, #"system32\notepad.exe");
//The real work part
//This is the programm to run
ProcessStartInfo startInfo = new ProcessStartInfo(FullPath);
//This tells it should run Elevated
startInfo.Verb = "runas";
//And that gives the order
//From here on it should be 100% identical to the Run Dialog (Windows+R), except for the part with the Elevation
System.Diagnostics.Process.Start(startInfo);
}
}
}
I did not just use System (37) back then, as I wrote it when x32/x86 Systems were still a thing. You would need to check how it resolves nowadays.
Note that most of those paths are duplicated in the PATH System Variable, so you could look it up: https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/
Path Variables in turn go back to the old DOS days. Basically if you gave the Commandline a command/filename it would try the build-in commands, then Executables in the current working Directory (.bat, .com, .exe), and then go look over the path directories to again look for executeables. And only if all that failed, would it complain.
I finally tried to combine all three answers and came up with this:
I post it here in case someone has the same problem.
public static string[] GetPathOf(string cmd)
{
var list = new List<string>();
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Machine).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Process).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.User).Split(';'));
list = list.Distinct().Where(e=>Directory.Exists(e)).SelectMany(e=> new DirectoryInfo(e).GetFiles()).Where(e=>Regex.IsMatch(e.Name,"(?i)^"+cmd+"\\.(?:exe|cmd|com)")).Select(e=>e.FullName).ToList();
return list.ToArray();
}

Directory.getFiles An exception of type 'System.IO.IOException' occurred in mscorlib.dll

I am relatively well versed in C#, having worked in Unity (game engine) for a good 5 years now, but don't go near Windows much, just a heads up if it's something stupid I've missed.
In my WPF application, I am trying to look for a file in the root application location (\bin\Debug), but I keep receiving this error when I run it.
An exception of type 'System.IO.IOException' occurred in mscorlib.dll
but was not handled in user code Additional information: The directory
name is invalid.
Hopefully someone here can see what I've done wrong, and aid me in fixing this.
I am working on this as a side project for a friend who needed some help from someone who knows c#, but I've never gone near the Windows side of things before. (It's being run in the "public MainWindow()" initializer).
InitializeComponent();
string[] filePath = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "settings.txt");
string fileContent = filePath.ToString();
string[] contentArray = fileContent.Split(':');
string contentColor;
string contentIntensity;
for (int i = 0; i < contentArray.Length; i++)
{
switch (i)
{
case 0:
{
if (contentArray[i].ToLower().Contains("color: "))
{
contentColor = contentArray[i].Replace("title: ", "");
}
if (contentArray[i].ToLower().Contains("intensity: "))
{
contentIntensity = contentArray[i].Replace("intensity: ", "");
}
break;
}
}
}
What were you thinking here?
string[] filePath = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "settings.txt");
string fileContent = filePath.ToString();
It should be written as :
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "settings.txt");
string fileContent = File.ReadAllText(filePath);
you could do something like this
var filePath = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).
Where(name => name.Contains("settings")).ToList();
or
var filePath = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).
Where(name => name.EndsWith(".txt")).ToList();
or return a string[]
var filePath = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).
Where(name => name.EndsWith(".txt")).ToArray();
From MSDN
Directory.GetFiles :
Returns the names of files (including their paths) that match the
specified search pattern in the specified directory.
The method GetFiles accepts one or two parameters, a path or a path and a search pattern, the path has to be a directory !
IOException occurs when :
Path is a file name or there is a network error, and you are in the first case.
the method argument you are giving (AppDomain.CurrentDomain.BaseDirectory + "settings.txt") which is a file name not a directory, that's why you are having that exception.
So, instead of calling GetFiles on a File !! Just combine the two strings to get a file path by doing :
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "settings.txt");

Check if path is in Program Files [duplicate]

This question already has answers here:
See if file path is inside a directory
(2 answers)
Closed 9 years ago.
How can I check in C# if the specific path is to directory in "Program Files" ?
C:\Program Files\someDir... -> is in Program Files
D:\Apps\someDir... -> isn't in Program Files
Thanks!
You can check a path in ProgramFiles(x86) by using the code below:
string path = "yourpath";
var programfileX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
if (path.IndexOf(programfileX86, StringComparison.OrdinalIgnoreCase) >= 0)
{
//Found path
}
There're some interseting and subtle issues with the problem:
You should compare paths case insenstive, e.g. "C:\PRogRAM FILES (x86)\Sample" is OK
Separators could be either / or \ so "C:/PRogRAM FILES (x86)/Sample" is OK as well
You should break on separatos only, e.g. "C:\Program Files (x86)MyData\Sample" is not OK
The Code:
public static Boolean PathIncludes(String path, String pathToInclude) {
if (String.IsNullOrEmpty(pathToInclude))
return false;
else if (String.IsNullOrEmpty(path))
return false;
String[] parts = Path.GetFullPath(path).Split(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar, Path.VolumeSeparatorChar);
String[] partsToInclude = Path.GetFullPath(pathToInclude).Split(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar, Path.VolumeSeparatorChar);
if (parts.Length < partsToInclude.Length)
return false;
for (int i = 0; i < partsToInclude.Length; ++i)
if (!String.Equals(parts[i], partsToInclude[i], StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
public static Boolean InProgramFiles(String path) {
return PathIncludes(path, Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)));
}
// Tests:
// Supposing that ProgramFilesX86 is "C:\Program Files (x86)"
InProgramFiles(#"C:\PRogRAM FILES (x86)\Sample"); // <- true
InProgramFiles(#"C:/PRogRAM FILES (x86)/Sample"); // <- true
InProgramFiles(#"D:/PRogRAM FILES (x86)/Sample"); // <- false
InProgramFiles(#"C:/PRogRAM FILES (x86)A/Sample"); // <- false
First you need to get the program files path. You can do that with System.Environment:
var programFilesPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles);
If you want the 32 bit program files path you would just change the special folder you are looking for (System.Environment.SpecialFolder.ProgramFilesX86). Then I would do a contains:
var isInProgramFiles = myPath.ToLower().Contains(programFilesPath.ToLower());
That should get you 90% of the way there at least! Best of luck!
EDIT / Sanitize Note
As a side note - there are situations where you can have a valid input and this still wouldn't match. For example - using "/" instead of "\". If you want to make sure you handle these boundary cases correctly, you can create a "DirectoryInfo" object from your input string, validate that it is actually a folder and also standardize the formatting for it. That code looks something like:
if (!System.IO.Directory.Exists(inputPath)) return false;
var checkPath = (new System.IO.DirectoryInfo(inputPath)).FullName;
In this example "inputPath" is the same as "myPath" was above. That should do a moderately good job of sanitizing the input. Best of luck!
If you have a path variable:
string path = "/* whatever path */";
You can check if it is in a folder subfolder this way:
path.IndexOf('\\' + subfolder + '\\') != -1
Note that in more complex cases .. may revert you out of a subdirectory, meaning that you are not in folder f2 if you have something like this:
"\\base_on_drive\\subfolder\\f1\\f2\\..\\a_file.txt"
The .. will bump you back into it's parent folder f1.
if (path.Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)) || (path.Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)))
{
}
Assuming your program might be running inside of ProgramFiles, you will probably want to get the fullpath of any path you're checking (in case you get a relative path). In addition, C# has a handy SpecialFolder enumeration that you can use to get the ProgramFiles directory.
The following code will take in a path, convert it to a fullpath, and check if the ProgramFiles directory can be found inside of it. You may want to add some error handling (such as checking for null paths).
static string programfileX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
public bool IsInsideProgramFiles(string path)
{
// Get the fullpath in case 'path' is a relative path
string fullPath = System.IO.Path.GetFullPath(path);
return (fullPath.IndexOf(programfileX86, StringComparison.OrdinalIgnoreCase) >= 0);
}
Note: Depending on the systems your code is running in, you may want to check for both SpecialFolder.ProgramFiles and SpecialFolder.ProgramFilesx86.
Credit goes to Toan Nguyen's for the code to get the ProgramFiles directory:

Getting name(s) of FOLDER containing a specific SUBSTRING from the C:Temp directory in C#

Guys as the title says it I have to get the names of FOLDERS having a particular (user indicated) sub string.
I have a text box where the user will input the wanted sub string.
and I am using the codes below to achieve my goal.
string name = txtNameSubstring.Text;
string[] allFiles = System.IO.Directory.GetFiles("C:\\Temp");//Change path to yours
foreach (string file in allFiles)
{
if (file.Contains(name))
{
cblFolderSelect.Items.Add(allFiles);
// MessageBox.Show("Match Found : " + file);
}
else
{
MessageBox.Show("No files found");
}
}
It does not work.
When I trigger it,only the message box appears.
Help ?
You can use the appropriate API to let the framework filter the directories.
var pattern = "*" + txtNameSubstring.Text + "*";
var directories = System.IO.Directory.GetDirectories("C:\\Temp", pattern);
Because the MessageBox will appear for the first path that does not contain the substring
You could use Linq to get the folders, but you will need to use GetDirectories not GetFiles
string name = txtNameSubstring.Text;
var allFiles = System.IO.Directory.GetDirectories("C:\\Temp").Where(x => x.Contains(name));//
if (!allFiles.Any())
{
MessageBox.Show("No files found");
}
cblFolderSelect.Items.AddRange(allFiles);
You don't want to have the message box inside the loop.
string name = txtNameSubstring.Text;
string[] allFiles = System.IO.Directory.GetFiles("C:\\Temp");//Change path to yours
foreach (string file in allFiles)
{
if (file.Contains(name))
{
cblFolderSelect.Items.Add(file);
// MessageBox.Show("Match Found : " + file);
}
}
if(cblFolderSelect.Items.Count==0)
{
MessageBox.Show("No files found");
}
(Assuming cblFolderSelect was empty before this code runs)
As you currently have it, you're deciding whether to show the message box for each file that you examine. So if the first file doesn't match, you'll be told "No files found" even though the next file might match.
(I've also changed the Add to add the individual file that matches, not all of the files (for which one or more matches))

Categories

Resources