directory.getfiles stops searching when error - c#

I have this code witch works perfectly on my dev enviroment:
String[] FileNames = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".bak") || s.EndsWith(".dwg")).ToArray();
var queryDupNames = from f in FileNames
group f by Path.GetFileNameWithoutExtension(f) into g
where g.Count() > 1
select new { Name = g.Key, FileNames = g }
;
var lista = queryDupNames.ToList();
With this code I´m looking for files with the same name and different extension (bak and dwg). When I tried this with my company mapped drive I got this error:
Excepción no controlada: System.IO.DirectoryNotFoundException: No se puede encontrar una parte de la ruta de acceso 'O:\auskalononden\sistema de gestion\mantenimiento\01.-Maquinas y utiles\COMPROBADORAS\utiles y maquinas sin presion ni agua original\Deapnelizadora de alimantacion CODIGO-- ESPAÑA-- FRANCIA\JAULA GIRONA ESPAÑA FRANCIA\Jaula de utensilios KIDJQd sC-22\4403.-repu'.
en System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
en System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption)
en System.IO.Directory.GetFiles(String path, String searchPattern, SearchOption searchOption)
en bakdwg.Program.Main(String[] args) en D:\dev\bakdwg\bakdwg\Program.cs:línea 19
Is there any whay to tell: if you have an error with this path, follow with next path? or something?

As per my comment, the error occurs because your file path is too long. As #Richard comments, you could use Win32 APIs directly to get around this limit. However, personnally I prefer to use the Delimon.Win32.IO C# library from TechNet. This library replaces basic file functions of System.IO and supports File & Folder names up to up to 32,767 Characters. See a basic code example below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// Specifically adding the Delimon.Win32.IO Library to use in the current Code Page
using Delimon.Win32.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetFiles(#"c:\temp");
foreach (string file in files)
{
Console.WriteLine(file);
}
Console.ReadLine();
}
}
}

That path has 261 characters. The normal Win32 APIs max out at 260 (MAX_PATH) and there is no support in .NET for Win32's long path support (you can P/Invoke but that means doing all the operations on that file/directory that way).

Related

UnRAR DLL unable to be referenced in C#

I was trying to make a program to clean out some directories on my NAS and I noticed that a lot of folders contained nested rar and zip files and I have plenty of space to unpack them. The program should ask the user for a directory to be cleaned then unpack all rars then delete all of the rars. I'm trying to use UnRAR DLL and I cant even get the rars to unpack. I realize I'm having an issue where visual studio 2022 is refusing to recognize the Unrar DLL in the "using" command. Because of that I've been unable to unpack a single file. This is one my first useful programs so if im missing something basic I understand.
This is my initial attempt:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using UnRAR;
namespace Cleaning
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter Directory To Be Cleaned");
string rar_path = Console.ReadLine();
string[] Rars = Directory.GetFiles(rar_path, "*.rar", SearchOption.AllDirectories);
foreach (string rar in Rars)
{
string source = rar;
string dest = "C:\\Users\\Kaleb\\OneDrive\\Desktop\Test Area";
UnRAR unrar = new UnRAR();
unrar.Password = "password_of_myarchive";
unrar.Open(#source, UnRAR.OpenMode.Extract);
while (unrar.ReadHeader())
{
unrar.ExtractToDirectory(#dest);
}
unrar.Close();
}
}
}
}
For reference I have added the UnRAR DLL to the project folder.
SO I was able to get it working with the source code from the great people over at SharpCompress and utilizing their source I've got the following stable build.
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Common;
using System;
using System.IO;
using System.Linq;
using System.Globalization;
namespace ConsoleApp3
{
public class Program
{
static void Main(string[] args)
{
for (; ; )
{
Console.WriteLine("Enter E to extract all directories in file path");
Console.WriteLine("Enter D to delete all Archives in file path");
Console.WriteLine("REMEMBER TO ALWAYS EXTRACT BEFORE DELETING");
string option = Console.ReadLine();
if (option == "e" || option == "E")
{
Console.WriteLine("Enter Directory To Be Cleaned");
//as a warning this will extract all files from any rar in the slected driectory one at a time in order.
//if a rar is broken it will halt the program until the offendin rar is deleted best way to find is to see what has been extracted so far and go from there
//or one could also limit the directory in order to refine the number of rars to look for
string rar_path = Console.ReadLine();
string[] Rars = Directory.GetFiles(rar_path, "*.rar", SearchOption.AllDirectories);
foreach (string rar in Rars)
{
var DirectoryFinal = Path.GetDirectoryName(rar);
using (var archive = RarArchive.Open(#rar))
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{
entry.WriteToDirectory(#DirectoryFinal, new ExtractionOptions()
{
ExtractFullPath = true,
Overwrite = true
});
}
};
}
}
else if (option == "d" || option == "D")
{
Console.WriteLine("Enter Directory To Be Cleaned");
//be careful with this i would recomend extracting and then chekcing everything first
string rar_path = Console.ReadLine();
string[] TobeDeleted = Directory.GetFiles(rar_path, "*.r*", SearchOption.AllDirectories);
foreach (string rarstobedeleted in TobeDeleted)
{
File.Delete(rarstobedeleted);
}
}
else
{
Console.WriteLine("Thats not an option try again");
}
Console.WriteLine("Cleaning Complete.");
;
}
}
}
}
This work effectively for rar files only for the time being but will effectively clean up any directories where someone may have downloaded a large amount of files stored in separated rars

FFProbe.Analyse getting the error 'The system cannot find the file specified' when given a string

I want to compress every video within every drive and its sub-directories so the code I have used so far finds each drive and looks for .mp4 locations. Then it uses that list of strings to compress each file but it comes up with this error at:
var mediaInfo = FFProbe.Analyse(filePath: d)
and
.FromFileInput(d, verifyExists: true)
System.ComponentModel.Win32Exception: 'The system cannot find the file specified'
I checked what the .Analyse needs and it is a string and d is a string which has the right path location C:\\Users\\Helix\\Desktop\\apartment\\5 Little Monkeys Swinging In The Tree.mp4" which I thought would work but it does not seem to like it. What am I doing wrong?
I am also curious as to if GetDrives() works on network drives? And if it does would two servers running this code conflict when grabbing the same file at the same time?
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MediaToolkit;
using MediaToolkit.Model;
using FFMpegCore;
using FFMpegCore.Enums;
namespace Video_Compressor_for_Servers
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void CompAll_Click(object sender, EventArgs e)
{
//An empty list for later to collect strings
List<string> file = new List<string>();
//extract primary drives strings into a list since there could be more than just C:\
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach (DriveInfo d in allDrives)
{
//The d.Name output has "Drive C:\" as the output. remove the "Drive " part first
var replacement = d.Name.Replace("Drive ", "");
/*Grab each files location with the Directory tool from the earlier IO libary.
GetFiles is a subcommand of directory with options in the brackets. These
options can be found in more detail by seaching for GetFiles C#*/
string[] files = Directory.GetFiles(#"C:\Users\Helix\Desktop\apartment\","*.mp4", SearchOption.AllDirectories);// replacement//AllDirectories
//Convert the array to a list
List<string> templist = files.ToList();
//Add them to the earlier empty list we made
file.AddRange(templist);
}
//Now that we have paths to all the files we need we can now compress them
foreach (string d in file)
{
var mediaInfo = FFProbe.Analyse(filePath: d);
//Open the video file with MediaToolkit
FFMpegArguments
.FromFileInput(d, verifyExists: true)
.OutputToFile(d, false, options => options
.WithVideoCodec(VideoCodec.LibX264)
.WithConstantRateFactor(21)
.WithAudioCodec(AudioCodec.Aac)
.WithVariableBitrate(4)
.WithVideoFilters(filterOptions => filterOptions
.Scale(VideoSize.Ed))
.WithFastStart())
.ProcessSynchronously();
}
}
}
}
You need to download both ffprobe.exe and ffmpeg.exe.
The executable is missing not the media one.

Get Project Path

I have a solution with few projects.
Solution 1 has
Pro1 (MVC project),
Pro2 (Class Library), and
Pro3 (Class Library)
So I use Pro 3 for the reporting part and using hkHtmlToPDF for exporting htmls as pdf. There is a exe called hkHtmlToPdf.exe for doing my task.
But I have very little issue. It is needed exe path to execute the code. I want to get Pro3 physical path and used below code to get the path.
var myPath = System.AppDomain.CurrentDomain.BaseDirectory;
Above code returns web project path. Actually I need Pro3 path. How to get it?
You know the name of your exe file.
string pattern = "hkHtmlToPdf.exe";
string dirPath = AppDomain.CurrentDomain.BaseDirectory;
Directory.GetFiles(dirPath , pattern, SearchOption.AllDirectories);
EDIT:
All work just fine! Create 2 console app as follow:
static void Main(string[] args)
{
Console.WriteLine("This exe is runned from another exe.");
Console.ReadKey();
}
static void Main(string[] args)
{
string pattern = "ConsoleApplication1.exe";
string dirPath = AppDomain.CurrentDomain.BaseDirectory;
var files = Directory.GetFiles(dirPath, pattern, SearchOption.AllDirectories);
if (files.Length > 0) Process.Start(files[0]);
else Debug.WriteLine("File not found");
Console.ReadKey();
}
Place them in one folder, run App2. It WILL FIND App1 and run. Even if App1 will be in sub folder!
Instead of searching you could add the path as a configuration parameter in web.config.

ZipFile.ExtractToDirectory "Illegal characters in path"

I want to unzip a file with ZipFile class in c# (VS2012).
Even if I copy the paths directly from win explorer I get this error:
System.ArgumentException: Illegales Zeichen im Pfad. bei
System.IO.Path.CheckInvalidPathChars(String path, Boolean
checkAdditional) bei System.IO.Path.GetFileName(String path) bei
System.IO.Compression.ZipHelper.EndsWithDirChar(String test) bei
System.IO.Compression.ZipArchiveEntry.set_FullName(String value)
bei System.IO.Compression.ZipArchiveEntry..ctor(ZipArchive archive,
ZipCentralDirectoryFileHeader cd) bei
System.IO.Compression.ZipArchive.ReadCentralDirectory() bei
System.IO.Compression.ZipArchive.get_Entries() bei
System.IO.Compression.ZipFileExtensions.ExtractToDirectory(ZipArchive
source, String destinationDirectoryName) bei
System.IO.Compression.ZipFile.ExtractToDirectory(String
sourceArchiveFileName, String destinationDirectoryName, Encoding
entryNameEncoding) bei
System.IO.Compression.ZipFile.ExtractToDirectory(String
sourceArchiveFileName, String destinationDirectoryName) bei
WindowsFormsApplication1.MainForm.buttonStartNxtOSEK_Click(Object
sender, EventArgs e) in
d:\C#\nxtOSEKInstaller\nxtOSEKSetup\WindowsFormsApplication1\Form1.cs:Zeile
192.
Code:
string zipPath = #"D:\C#\nxtOSEKInstaller\nxtOSEKSetup\WindowsFormsApplication1\bin\Debug\res\package.zip";
string extractPath = #"D:\testcyginstall\cygwin";
textBoxProgress.AppendText("Entpacke .... ");
try {
ZipFile.ExtractToDirectory(zipPath, extractPath);
} catch (System.ArgumentException ex) {
textBoxProgress.AppendText("\n" + "Error\n" + ex.ToString());
return;
}
EDIT
Problem solved: Some files with chinese file names in the zip file caused the problem.
It's very frustrating when the exception does not output the problematic path name.
As you already know some characters are not valid on windows:
\ / : * ? " < > |
This would bring a lot of situations when your application receives zip from different OS since some of those invalid characters are valid in other OS.
In order to solve this problem you can sanitize your files names before you extract them:
public void ExtractZipFileToPath(
string zipFilePath,
string ouputPath
)
{
using (var zip = ZipFile.Read(zipFilePath))
{
foreach (var entry in zip.Entries.ToList())
{
entry.FileName = SanitizeFileName(entry.FileName);
entry.Extract(ouputPath);
}
}
}
Sanitizing examples here How to remove illegal characters from path and filenames?

How to go about searching a server for a specific file?

I am attempting to find a specific file on a web(site/server), and this file could have varying extensions depending upon the server. How would I determine the extension for a unique sever?
Example Possibilities:
website.com/list.bz2
--or--
website.com/list.gz
using System;
using System.IO;
class App
{
public static void Main()
{
string searchPath = #"c:\";
string searchPattern = "list.*";
DirectoryInfo di = new DirectoryInfo(searchPath);
FileInfo[] files = di.GetFiles(searchPattern, SearchOption.AllDirectories);
foreach (FileInfo file in files)
Console.WriteLine(file.FullName);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
If you don't have access to server and want to search it as a anonymous client, then you should search internet for google hacking.

Categories

Resources