Getting disk drive info incorrectly - c#

public static string GetDriveType()
{
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach (DriveInfo drive in allDrives)
{
return DriveInfo.DriveType;
if(DriveType.CDRom)
{
return DriveInfo.Name;
}
}
}
As you guys can probably see, there is quite a bit wrong with this code. Basically, I am trying to return the name of the drive to use later in the code, but only if the drive is a CDRom drive. How can I just check the name of the drive and return it so that I can interpret it later when I am programmatically opening the CD drive? Thanks!

You should return a list of strings in case there are more cd drives:
public static List<string> GetCDDrives()
{
var cdDrives = DriveInfo.GetDrives().Where(drive => drive.DriveType == DriveType.CDRom);
return cdDrives?.Select(drive => drive.Name).ToList();
}

I think that you need something like the following:
public static string GetCDRomName()
{
// Get All drives
var drives = DriveInfo.GetDrives();
var cdRomName = null;
// Iterate though all drives and if you find a CdRom get it's name
// and store it to cdRomName. Then stop iterating.
foreach (DriveInfo drive in allDrives)
{
if(drive.DriveType == DriveType.CDRom)
{
cdRomName = drive.Name;
break;
}
}
// If any CDRom found returns it's name. Otherwise null.
return cdRomName;
}

Related

Retrieving the amount of local storage on a device in UWP app

I have been trying to find the amount of free storage space available in the fixed drive on a device in my UWP app. I have been using the following code to achieve this-
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach (DriveInfo d in allDrives)
{
if (d.DriveType == DriveType.Fixed && d.IsReady)
{
double availableFreeSpaceInBytes = d.AvailableFreeSpace;
}
}
But whenever I run this, d.IsReady always returns false indicating that the device is not ready. I referred this- https://learn.microsoft.com/en-us/dotnet/api/system.io.driveinfo.isready?view=netframework-4.8. But haven't been able to understand.
Please help me with what am I doing wrong. Or is there any other way to achieve this?
If you only need to know the free space on the drive where your UWP app is installed (usually, the C: drive), you can use the following without adding any additional capabilities:
using Windows.Storage;
string freeSpaceKey = "System.FreeSpace";
var retrieveProperties = await ApplicationData.Current.LocalFolder.Properties.RetrievePropertiesAsync(new string[] { freeSpaceKey });
var freeSpaceRemaining = (ulong)retrieveProperties[freeSpaceKey];
Retrieving the amount of local storage on a device in UWP app
AvailableFreeSpace is not available in UWP system. For getting available free space, you need use StorageFolder System.FreeSpace property to achieve. Pleas note if you used GetFolderFromPathAsync metod, you need to allow broadFileSystemAccess capability before. Please refer this case link.
const String k_freeSpace = "System.FreeSpace";
const String k_totalSpace = "System.Capacity";
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach (DriveInfo d in allDrives)
{
try
{
Debug.WriteLine("Drive: " + d.Name);
Debug.WriteLine("RootDir: " + d.RootDirectory.FullName);
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(d.RootDirectory.FullName);
var props = await folder.Properties.RetrievePropertiesAsync(new string[] { k_freeSpace, k_totalSpace });
Debug.WriteLine("FreeSpace: " + (UInt64)props[k_freeSpace]);
Debug.WriteLine("Capacity: " + (UInt64)props[k_totalSpace]);
}
catch (Exception ex)
{
Debug.WriteLine(String.Format("Couldn't get info for drive {0}. Does it have media in it?", d.Name));
}
}

How to close a particular windows explorer window in c#?

I am wondering if I can close an explorer window which is communicating with my USB drive. I can get the removable disk and its drive letter by using
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
if (!drive.IsReady)
{
continue;
}
if (drive.DriveType == DriveType.Removable && isDirectoryEmpty(drive.Name) == true)
{
//do stuff
}
}
How do I do that ? any help would be appreciated.
You cannot use Process.GetProcessesByName("explorer") because there is always one explorer process in the returned array, and by killing it, you would kill the window task bar too.
You have to use a COM library as explained here:
https://stackoverflow.com/a/13464352/1280523
You can try like this:
foreach (Process p in Process.GetProcessesByName("explorer"))
{
if (p.MainWindowTitle.ToLower().Contains(#"yourSpecificWindow"))
{
p.Kill();
}
}

How to get list of USB in winform using c#?

i have tried this code to get the usb devices in connected to the computer.
This is the code:
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
if (drive.DriveType == DriveType.Removable)
{
cmbUSB.Items.Add(drive.Name);
}
}
cmbusb is a combobox.. here i am getting this :
E:/
G:/
but not getting the device name, like :
E:/Insforia
something like this,
how can i get this? is it possible to get this? pls help
For getting the DeviceName of E:/ try this.
DriveInfo driveInfo = new DriveInfo("E");
if(driveInfo.IsReady)
{
string deviceName = driveInfo.VolumeLabel;
}
I believe you are looking for VolumeLabel, try:
The label length is determined by the operating system. For example,
NTFS allows a volume label to be up to 32 characters long. Note that
null is a valid VolumeLabel.
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
if (drive.DriveType == DriveType.Removable)
{
if (drive.IsReady)
cmbUSB.Items.Add(drive.Name + "-" + drive.VolumeLabel);
//^^^^^^^^^^^^^^^^
//here
}
}

how to search media file in our system by c#?

I want to search the media files situated in my system by c#. means I want to create the search engine that will scan all drives (again small question here , how to get the drives on our system by c# code ? )and search the media files like .mp3,.mp4,...etc . How can i do that by c# desktop application?
try this:
List<string> mediaExtensions = new List<string>{"mp3", "mp4"};
List<string> filesFound = new List<string>();
void DirSearch(string sDir)
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, "*.*"))
{
if(mediaExtensions.Contains(Path.GetExtension(f).ToLower()))
filesFound.Add(f);
}
DirSearch(d);
}
}
Rather than a brute-force iterative search through directories, I recommend looking into using the Windows Desktop Search API, which will be orders of magnitude faster.
Windows Desktop Search via C#
To get your drive list:
string[] drives = Environment.GetLogicalDrives();
To get all your files:
foreach(string drive in drives)
string[] allFiles = Directory.GetFiles(drive, "*.*", SearchOption.AllDirectories);
To get all your files using recursion:
List<string> allFiles = new List<string>();
private void RecursiveSearch(string dir)
{
allFiles.Add(Directory.GetFiles(dir));
foreach(string d in Directory.GetDirectories(dir))
{
RecursiveSearch(d);
}
}
Filter using Manu's answer
try this
var files = new List<string>();
//#Stan R. suggested an improvement to handle floppy drives...
//foreach (DriveInfo d in DriveInfo.GetDrives())
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady == true))
{
files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, "File Name", SearchOption.AllDirectories));
}

Solving UnauthorizedAccessException issue for listing files

Listing all files in a drive other than my system drive throws an UnauthorizedAccessException.
How can I solve this problem?
Is there a way to grant my application the access it needs?
My code:
Directory.GetFiles("S:\\", ...)
Here's a class that will work:
public static class FileDirectorySearcher
{
public static IEnumerable<string> Search(string searchPath, string searchPattern)
{
IEnumerable<string> files = GetFileSystemEntries(searchPath, searchPattern);
foreach (string file in files)
{
yield return file;
}
IEnumerable<string> directories = GetDirectories(searchPath);
foreach (string directory in directories)
{
files = Search(directory, searchPattern);
foreach (string file in files)
{
yield return file;
}
}
}
private static IEnumerable<string> GetDirectories(string directory)
{
IEnumerable<string> subDirectories = null;
try
{
subDirectories = Directory.EnumerateDirectories(directory, "*.*", SearchOption.TopDirectoryOnly);
}
catch (UnauthorizedAccessException)
{
}
if (subDirectories != null)
{
foreach (string subDirectory in subDirectories)
{
yield return subDirectory;
}
}
}
private static IEnumerable<string> GetFileSystemEntries(string directory, string searchPattern)
{
IEnumerable<string> files = null;
try
{
files = Directory.EnumerateFileSystemEntries(directory, searchPattern, SearchOption.TopDirectoryOnly);
}
catch (UnauthorizedAccessException)
{
}
if (files != null)
{
foreach (string file in files)
{
yield return file;
}
}
}
}
You can the use it like this:
IEnumerable<string> filesOrDirectories = FileDirectorySearcher.Search(#"C:\", "*.txt");
foreach (string fileOrDirectory in filesOrDirectories)
{
// Do something here.
}
It's recursive, but the use of yield gives it a low memory footprint (under 10KB in my testing). If you want only files that match the pattern and not directories as well just replace EnumerateFileSystemEntries with EnumerateFiles.
Are you allowed to access the drive? Can the program access the drive when it's not run from Visual Studio? Are restrictive permissions defined in the project's Security page ("Security Page, Project Designer")?
In .net core you can do something like this below. It can search for all subdirectories recursively with good performance and ignoring paths without access.
I also tried other methods found in
How to quickly check if folder is empty (.NET)? and
Is there a faster way than this to find all the files in a directory and all sub directories? and
https://www.codeproject.com/Articles/1383832/System-IO-Directory-Alternative-using-WinAPI
public static IEnumerable<string> ListFiles(string baseDir)
{
EnumerationOptions opt = new EnumerationOptions();
opt.RecurseSubdirectories = true;
opt.ReturnSpecialDirectories = false;
//opt.AttributesToSkip = FileAttributes.Hidden | FileAttributes.System;
opt.AttributesToSkip = 0;
opt.IgnoreInaccessible = true;
var tmp = Directory.EnumerateFileSystemEntries(baseDir, "*", opt);
return tmp;
}
I solved the problem. Not really but at least the source.
It was the SearchOption.AllDirectories option that caused the exception.
But when I just list the immediate files using Directories.GetFiles, it works.
This is good enough for me.
Any way to solve the recursive listing problem?

Categories

Resources