File extension restriction to .cor (only) - c#

How can I restrict only .cor files to be added to the list.
The code bellow allows .corx, .corxx, .corxxx to be added to the list.
I only want .cor files. Is that possible?
private void btn_models_Click(object sender, EventArgs e)
{
DialogResult res = dlg_find_folder.ShowDialog();
if (res == DialogResult.OK)
{
tbx_models.Text = dlg_find_folder.SelectedPath;
populateChecklist(tbx_models.Text, "cor");
cbx_all.CheckState = System.Windows.Forms.CheckState.Checked;
}
}
/// <summary>
/// Function populates the models checklist based on the models found in the specified folder.
/// </summary>
/// <param name="directory">Directory in which to search for files</param>
/// <param name="extension">File extension given without period</param>
private void populateChecklist(String directory, String extension)
{
clb_run_list.Items.Clear();
System.Collections.IEnumerator enumerator;
String mdl_name;
try
{
enumerator = System.IO.Directory.GetFiles(directory, "*." + extension).GetEnumerator();
while (enumerator.MoveNext())
{
mdl_name = parse_file_name((String)enumerator.Current, directory, extension);
clb_run_list.Items.Add(mdl_name);
}
}
catch
{
//above code will fail if the initially specified directory does not exist
//MessageBox.Show("The specified directory does not exist. Please select a valid directory.");
}
return;
}

How about;
if (Path.GetExtension(mdl_name).Equals(".cor", StringComparison.OrdinalIgnoreCase))
clb_run_list.Items.Add(mdl_name);

Do a check for FileName.EndsWith(extension) before adding to your list?

This is an artifact of Windows support for old DOS 8.3 filenames. Files with an extension like .corxxx get mapped to a 8.3 name like Blah~1.cor. And will match your wildcard.
Nothing you can do but double-check the filename you get. Use Path.GetExtension()

Related

C# FolderBrowserDialog - how to include shared folders

I create a FolderBrowserDialog as follows (only an excerpt -not complete code):
string tempSetWorkingPath = null;
try
{
FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
folderDlg.ShowNewFolderButton = true;
folderDlg.Description = "Selected your working folder. This is where your PDF files will be saved.";
folderDlg.RootFolder = Environment.SpecialFolder.MyComputer;
folderDlg.SelectedPath = (Convert.ToString(WorkingPath).Trim().Length == 0) ? ((int)Environment.SpecialFolder.MyComputer).ToString() : WorkingPath;
if (folderDlg.ShowDialog() == DialogResult.OK)
{
tempSetWorkingPath = folderDlg.SelectedPath;
}
else
{
tempSetWorkingPath = "";
}
}
...
The code works well, except the only folders that are showing are the local folders. Users have DropBox and OneDrive shared folders on their systems and to select one of those directories, the user needs to cycle through the windows user directories and select the folder from there. On some systems I have seen over the last few months, I've seen the DropBox and OneDrive directories appear below the DeskTop directory ... but I have not, despite hours of searching - found a way to achive that.
How can I achieve that?
MTIA
DWE
Given I have observed a large number of queries posted here and elsewhere regarding the inclusion of the directories, including shared directories and given the response by # Mailosz, it seems that the root folder property of the folder dialog holds the key - it Gets or sets the root folder where the browsing starts from and thats what my code was missing.
The full code to the function referred to in my question appears below, in the event it assists someone else.
/// <summary>
/// presents the user with a folder dialog
/// Returns a full qualified directory chosen by the user
/// </summary>
/// <param name="WorkingPath">if a fully qualified directory name is provided, then the folder structure in the folder dialog will open to the directory selected</param>
/// <returns>Returns a full qualified directory chosen by the user or if no directory was chosen, an empty string</returns>
public string SetWorkingPath(string WorkingPath)
{
string tempSetWorkingPath = null;
try
{
FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
// check our proposed working path and if its valid
if((!string.IsNullOrEmpty(WorkingPath) && (WorkingPath != null)))
{
if (!Directory.Exists(WorkingPath))
WorkingPath = string.Empty;
}
else // if we are empty or null set us to empty
{
WorkingPath = string.Empty;
}
folderDlg.ShowNewFolderButton = true;
folderDlg.Description = "Please select your working folder. This is where your PDF files will be saved.";
folderDlg.RootFolder = Environment.SpecialFolder.Desktop;//.MyComputer;
folderDlg.SelectedPath = (Convert.ToString(WorkingPath).Trim().Length == 0) ? ((int)Environment.SpecialFolder.MyComputer).ToString() : WorkingPath;
if (folderDlg.ShowDialog() == DialogResult.OK)
{
// make sure we have a backslash on the end of our directory string
tempSetWorkingPath = PathAddBackslash(folderDlg.SelectedPath);
}
else
{
// return an empty string
tempSetWorkingPath = string.Empty;
}
}
catch (Exception ex)
{
tempSetWorkingPath = string.Empty;
throw (ex);
}
return tempSetWorkingPath;
}
public string PathAddBackslash(string path)
{
// They're always one character but EndsWith is shorter than
// array style access to last path character. Change this
// if performance are a (measured) issue.
string separator1 = Path.DirectorySeparatorChar.ToString();
string separator2 = Path.AltDirectorySeparatorChar.ToString();
// Trailing white spaces are always ignored but folders may have
// leading spaces. It's unusual but it may happen. If it's an issue
// then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
path = path.TrimEnd();
// Argument is always a directory name then if there is one
// of allowed separators then I have nothing to do.
if (path.EndsWith(separator1) || path.EndsWith(separator2))
return path;
// If there is the "alt" separator then I add a trailing one.
// Note that URI format (file://drive:\path\filename.ext) is
// not supported in most .NET I/O functions then we don't support it
// here too. If you have to then simply revert this check:
// if (path.Contains(separator1))
// return path + separator1;
//
// return path + separator2;
if (path.Contains(separator2))
return path + separator2;
// If there is not an "alt" separator I add a "normal" one.
// It means path may be with normal one or it has not any separator
// (for example if it's just a directory name). In this case I
// default to normal as users expect.
return path + separator1;
}

How to Check if file pattern exist in C# SSIS package [duplicate]

I have a for loop container within my ssis package which contains a script and a sql task.
I have 3 variables.
source.string = this is folder location
file.string = i have used wildcard = *.csv
exist.int = defaulted to 0
I have the innitexpression value set to #Exists=1
and the evalexpression value set to #Exists=1
in the script I have set it to look at source variable and if file.string variable exists then set exist variable to 1
problem is it just loops it should only loop if no file there. cant see how I've done this wrong it was working before I changed the variable to be a wildcard *.csv
I have tested it using another variable which contains a filename rather than a wildcard and it works correctly the issue is when looking for a wildcard for the filename followed by the extension. why is this? can I not pass through a wildcard variable?
my script task is
public void Main()
{
// TODO: Add your code here
string Filepath = Dts.Variables["User::Source"].Value.ToString()
+ Dts.Variables["User::file"].Value.ToString();
if (
File.Exists(Filepath))
{
Dts.Variables["User::Exists"].Value = 1;
}
/// MessageBox.Show (Filepath);
/// MessageBox.Show(Dts.Variables["Exists"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
Based on comments above i made 2 different solutions. The solution for you right now would be no. 2
This one can search for a specific file based on multiple files in your path. It need some tweaking but can be used if you wanna check if a specific file exists with wildcard
This one evaluates to true if any wildcard file is found.
C# Code 1
Using System.IO:
string Filepath = Dts.Variables["User::Source"].Value.ToString();
string WildCard = Dts.Variables["User::file"].Value.ToString(); // In Text form #"*.txt";
string fullpath = Filepath + WildCard;
//With for loop
string txtFile = null;
// Gets all files with wildcard
string[] allfiles = Directory.GetFiles(Filepath, WildCard);
//Loop through all files and set the filename in txtFile. Do whatever you want here
foreach(string fileName in allfiles)
{
//Check if a file contains something, it could be a prefixed name you only want
if(fileName.Contains("txt"))
{
txtFile = fileName;
if(File.Exists(txtFile))
{
Dts.Variables["User::Exists"].Value = 1;
}
}
}
C# Code 2
Using System.IO;
Using System.Linq;
string Filepath = Dts.Variables["User::Source"].Value.ToString();
string WildCard = Dts.Variables["User::file"].Value.ToString(); //In text form "*.txt";
string fullpath = Filepath + WildCard;
//With bool
bool exists = Directory.EnumerateFiles(Filepath, WildCard).Any();
if(exists == true)
{
Dts.Variables["User::Exists"].Value = 1;
}
MessageBox.Show (Filepath);
MessageBox.Show(Dts.Variables["Exists"].Value.ToString());

How to find out if a file is a shortcut file or not in windows 7 and 8? [duplicate]

I need to test if a file is a shortcut. I'm still trying to figure out how stuff will be set up, but I might only have it's path, I might only have the actual contents of the file (as a byte[]) or I might have both.
A few complications include that I it could be in a zip file (in this cases the path will be an internal path)
Shortcuts can be manipulated using the COM objects in SHELL32.DLL.
In your Visual Studio project, add a reference to the COM library "Microsoft Shell Controls And Automation" and then use the following:
/// <summary>
/// Returns whether the given path/file is a link
/// </summary>
/// <param name="shortcutFilename"></param>
/// <returns></returns>
public static bool IsLink(string shortcutFilename)
{
string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);
Shell32.Shell shell = new Shell32.ShellClass();
Shell32.Folder folder = shell.NameSpace(pathOnly);
Shell32.FolderItem folderItem = folder.ParseName(filenameOnly);
if (folderItem != null)
{
return folderItem.IsLink;
}
return false; // not found
}
You can get the actual target of the link as follows:
/// <summary>
/// If path/file is a link returns the full pathname of the target,
/// Else return the original pathnameo "" if the file/path can't be found
/// </summary>
/// <param name="shortcutFilename"></param>
/// <returns></returns>
public static string GetShortcutTarget(string shortcutFilename)
{
string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);
Shell32.Shell shell = new Shell32.ShellClass();
Shell32.Folder folder = shell.NameSpace(pathOnly);
Shell32.FolderItem folderItem = folder.ParseName(filenameOnly);
if (folderItem != null)
{
if (folderItem.IsLink)
{
Shell32.ShellLinkObject link = (Shell32.ShellLinkObject)folderItem.GetLink;
return link.Path;
}
return shortcutFilename;
}
return ""; // not found
}
You can simply check the extension and/or contents of this file. It contains a special GUID in the header.
Read [this document][1].
Link deleted, for me it goes to a porn site
If you are using .NET 6.0, then you can use FileInfo or DirectoryInfo. Both have a property named LinkTarget. If it is a shortcut, then LinkTarget will be a string targeting the original file/folder. Otherwise, it will be null.
Suppose there is a folder shortcut named "folder", then:
var info = new DirectoryInfo("path/to/the/folder/shortcut");
bool isShortcut = info.LinkTarget != null;
Check the extension? (.lnk)

Loop through set of files and check if it is comma delimited in C#

I need to loop through set of files and check if it is comma delimited or not in C#.I am very new to C#.Please help me with this.
Thanks in advance.
As someone already pointed out it is not going to be easy solution.
It could be very easy if every comma delimited file had a specified extension (for example: csv). If not the following algorigthm should work:
Retrieve all names (paths + names) of files in specified directory. If needed filter only those that may be of interest. Hint: take a look at System.IO.Directory and System.IO.File and System.IO.DirectoryInfo and System.IO.FileInfo
You have to examine every file, and check if it is comma delimited or not. This is going to be tricky part. You could build a regular expression, that will check each line of the file and and tell you if it is comma delimited or not.
Regular expressions are a bit hard to learn at the beginning but it should pay back after some time.
Here's a quick Console app that will take a directory, scan the directory for all files, then iterate through them and return a percentage of lines containing commas -vs- the total lines in the file. As has been pointed out, there are CSV libraries you can validate against. This is just a quick example to get you started.
To use this, create a new Console App project in Visual Studio and name it "TestStub" then copy and past this into the "Program.cs" file.
namespace TestStub
{
using System;
using System.IO;
using System.Text;
public class Program
{
private static char[] CSV = { ',', ',' };
private static bool csvFound = false;
/// <summary>
/// This is the console program entry point
/// </summary>
/// <param name="args">A list of any command-line args passed to this application when started</param>
public static void Main(string[] args)
{
// Change this to use args[0] if you like
string myInitialPath = #"C:\Temp";
string[] myListOfFiles;
try
{
myListOfFiles = EnumerateFiles(myInitialPath);
foreach (string file in myListOfFiles)
{
Console.WriteLine("\nFile {0} is comprised of {1}% CSV delimited lines.",
file,
ScanForCSV(file));
}
Console.WriteLine("\n\nPress any key to exit.");
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(
"Error processing {0} for CSV content: {1} :: {2}",
myInitialPath,
ex.Message,
ex.InnerException.Message);
}
}
/// <summary>
/// Get a list of all files for the specified path
/// </summary>
/// <param name="path">Directory path</param>
/// <returns>String array of files (with full path)</returns>
public static string[] EnumerateFiles(string path)
{
string[] arrItems = new string[1];
try
{
arrItems = Directory.GetFiles(path);
return arrItems;
}
catch (Exception ex)
{
throw new System.IO.IOException("EnumerateFilesAndFolders() encountered an error:", ex);
}
}
/// <summary>
/// Determines if the supplied file has comma separated values
/// </summary>
/// <param name="filename">Path and filename</param>
/// <returns>Percentage of lines containing CSV elements -vs- those without</returns>
public static float ScanForCSV(string filename)
{
//
// NOTE: You should look into one of the many CSV libraries
// available. This method will not carefully scruitinize
// the file to see if there's a combination of delimeters or
// even if it's a plain-text (e.g. a newspaper article)
// It just looks for the presence of commas on multiple lines
// and calculates a percentage of them with and without
//
float totalLines = 0;
float linesCSV = 0;
try
{
using (StreamReader sReader = new StreamReader(filename))
{
int elements = 0;
string line = string.Empty;
string[] parsed = new string[1];
while (!sReader.EndOfStream)
{
++totalLines;
line = sReader.ReadLine();
parsed = line.Split(CSV);
elements = parsed.Length;
if (elements > 1)
{
++linesCSV;
}
}
}
}
catch (Exception ex)
{
throw new System.IO.IOException(string.Format("Problem accessing [{0}]: {1}", filename, ex.Message), ex);
}
return (float)((linesCSV / totalLines) * 100);
}
}
}
}

Better way to check if a Path is a File or a Directory?

I am processing a TreeView of directories and files. A user can select either a file or a directory and then do something with it. This requires me to have a method which performs different actions based on the user's selection.
At the moment I am doing something like this to determine whether the path is a file or a directory:
bool bIsFile = false;
bool bIsDirectory = false;
try
{
string[] subfolders = Directory.GetDirectories(strFilePath);
bIsDirectory = true;
bIsFile = false;
}
catch(System.IO.IOException)
{
bIsFolder = false;
bIsFile = true;
}
I cannot help to feel that there is a better way to do this! I was hoping to find a standard .NET method to handle this, but I haven't been able to do so. Does such a method exist, and if not, what is the most straightforward means to determine whether a path is a file or directory?
From How to tell if path is file or directory:
// get the file attributes for file or directory
FileAttributes attr = File.GetAttributes(#"c:\Temp");
//detect whether its a directory or file
if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
MessageBox.Show("Its a directory");
else
MessageBox.Show("Its a file");
Update for .NET 4.0+
Per the comments below, if you are on .NET 4.0 or later (and maximum performance is not critical) you can write the code in a cleaner way:
// get the file attributes for file or directory
FileAttributes attr = File.GetAttributes(#"c:\Temp");
if (attr.HasFlag(FileAttributes.Directory))
MessageBox.Show("Its a directory");
else
MessageBox.Show("Its a file");
How about using this?
if(File.Exists(data.path))
{
// is file
}
else if(Directory.Exists(data.path))
{
// is Folder
}
else
{
// invalid path
}
File.Exists() will return false if it's not a file even if the directory does exist, so if it returns true, we know we got a file, if it returns false, we either have a directory or an invalid path so next we test if it's a valid directory with Directory.Exists() if that returns true, we have a directory if not it's an invalid path.
With only this line you can get if a path is a directory or a file:
File.GetAttributes(data.Path).HasFlag(FileAttributes.Directory)
Here's mine:
bool IsPathDirectory(string path)
{
if (path == null) throw new ArgumentNullException("path");
path = path.Trim();
if (Directory.Exists(path))
return true;
if (File.Exists(path))
return false;
// neither file nor directory exists. guess intention
// if has trailing slash then it's a directory
if (new[] {"\\", "/"}.Any(x => path.EndsWith(x)))
return true; // ends with slash
// if has extension then its a file; directory otherwise
return string.IsNullOrWhiteSpace(Path.GetExtension(path));
}
It's similar to others' answers but not exactly the same.
As an alternative to Directory.Exists(), you can use the File.GetAttributes() method to get the attributes of a file or a directory, so you could create a helper method like this:
private static bool IsDirectory(string path)
{
System.IO.FileAttributes fa = System.IO.File.GetAttributes(path);
return (fa & FileAttributes.Directory) != 0;
}
You could also consider adding an object to the tag property of the TreeView control when populating the control that contains additional metadata for the item. For instance, you could add a FileInfo object for files and a DirectoryInfo object for directories and then test for the item type in the tag property to save making additional system calls to get that data when clicking on the item.
After combining the suggestions from the other answers, I realized I came up with about the same thing as Ronnie Overby's answer. Here are some tests to point out some things to think about:
folders can have "extensions": C:\Temp\folder_with.dot
files cannot end with a directory separator (slash)
There are technically two directory separators which are platform specific -- i.e. may or may not be slashes (Path.DirectorySeparatorChar and Path.AltDirectorySeparatorChar)
Tests (Linqpad)
var paths = new[] {
// exists
#"C:\Temp\dir_test\folder_is_a_dir",
#"C:\Temp\dir_test\is_a_dir_trailing_slash\",
#"C:\Temp\dir_test\existing_folder_with.ext",
#"C:\Temp\dir_test\file_thats_not_a_dir",
#"C:\Temp\dir_test\notadir.txt",
// doesn't exist
#"C:\Temp\dir_test\dne_folder_is_a_dir",
#"C:\Temp\dir_test\dne_folder_trailing_slash\",
#"C:\Temp\dir_test\non_existing_folder_with.ext",
#"C:\Temp\dir_test\dne_file_thats_not_a_dir",
#"C:\Temp\dir_test\dne_notadir.txt",
};
foreach(var path in paths) {
IsFolder(path/*, false*/).Dump(path);
}
Results
C:\Temp\dir_test\folder_is_a_dir
True
C:\Temp\dir_test\is_a_dir_trailing_slash\
True
C:\Temp\dir_test\existing_folder_with.ext
True
C:\Temp\dir_test\file_thats_not_a_dir
False
C:\Temp\dir_test\notadir.txt
False
C:\Temp\dir_test\dne_folder_is_a_dir
True
C:\Temp\dir_test\dne_folder_trailing_slash\
True
C:\Temp\dir_test\non_existing_folder_with.ext
False (this is the weird one)
C:\Temp\dir_test\dne_file_thats_not_a_dir
True
C:\Temp\dir_test\dne_notadir.txt
False
Method
/// <summary>
/// Whether the <paramref name="path"/> is a folder (existing or not);
/// optionally assume that if it doesn't "look like" a file then it's a directory.
/// </summary>
/// <param name="path">Path to check</param>
/// <param name="assumeDneLookAlike">If the <paramref name="path"/> doesn't exist, does it at least look like a directory name? As in, it doesn't look like a file.</param>
/// <returns><c>True</c> if a folder/directory, <c>false</c> if not.</returns>
public static bool IsFolder(string path, bool assumeDneLookAlike = true)
{
// https://stackoverflow.com/questions/1395205/better-way-to-check-if-path-is-a-file-or-a-directory
// turns out to be about the same as https://stackoverflow.com/a/19596821/1037948
// check in order of verisimilitude
// exists or ends with a directory separator -- files cannot end with directory separator, right?
if (Directory.Exists(path)
// use system values rather than assume slashes
|| path.EndsWith("" + Path.DirectorySeparatorChar)
|| path.EndsWith("" + Path.AltDirectorySeparatorChar))
return true;
// if we know for sure that it's an actual file...
if (File.Exists(path))
return false;
// if it has an extension it should be a file, so vice versa
// although technically directories can have extensions...
if (!Path.HasExtension(path) && assumeDneLookAlike)
return true;
// only works for existing files, kinda redundant with `.Exists` above
//if( File.GetAttributes(path).HasFlag(FileAttributes.Directory) ) ...;
// no idea -- could return an 'indeterminate' value (nullable bool)
// or assume that if we don't know then it's not a folder
return false;
}
This was the best I could come up with given the behavior of the Exists and Attributes properties:
using System.IO;
public static class FileSystemInfoExtensions
{
/// <summary>
/// Checks whether a FileInfo or DirectoryInfo object is a directory, or intended to be a directory.
/// </summary>
/// <param name="fileSystemInfo"></param>
/// <returns></returns>
public static bool IsDirectory(this FileSystemInfo fileSystemInfo)
{
if (fileSystemInfo == null)
{
return false;
}
if ((int)fileSystemInfo.Attributes != -1)
{
// if attributes are initialized check the directory flag
return fileSystemInfo.Attributes.HasFlag(FileAttributes.Directory);
}
// If we get here the file probably doesn't exist yet. The best we can do is
// try to judge intent. Because directories can have extensions and files
// can lack them, we can't rely on filename.
//
// We can reasonably assume that if the path doesn't exist yet and
// FileSystemInfo is a DirectoryInfo, a directory is intended. FileInfo can
// make a directory, but it would be a bizarre code path.
return fileSystemInfo is DirectoryInfo;
}
}
Here's how it tests out:
[TestMethod]
public void IsDirectoryTest()
{
// non-existing file, FileAttributes not conclusive, rely on type of FileSystemInfo
const string nonExistentFile = #"C:\TotallyFakeFile.exe";
var nonExistentFileDirectoryInfo = new DirectoryInfo(nonExistentFile);
Assert.IsTrue(nonExistentFileDirectoryInfo.IsDirectory());
var nonExistentFileFileInfo = new FileInfo(nonExistentFile);
Assert.IsFalse(nonExistentFileFileInfo.IsDirectory());
// non-existing directory, FileAttributes not conclusive, rely on type of FileSystemInfo
const string nonExistentDirectory = #"C:\FakeDirectory";
var nonExistentDirectoryInfo = new DirectoryInfo(nonExistentDirectory);
Assert.IsTrue(nonExistentDirectoryInfo.IsDirectory());
var nonExistentFileInfo = new FileInfo(nonExistentDirectory);
Assert.IsFalse(nonExistentFileInfo.IsDirectory());
// Existing, rely on FileAttributes
const string existingDirectory = #"C:\Windows";
var existingDirectoryInfo = new DirectoryInfo(existingDirectory);
Assert.IsTrue(existingDirectoryInfo.IsDirectory());
var existingDirectoryFileInfo = new FileInfo(existingDirectory);
Assert.IsTrue(existingDirectoryFileInfo.IsDirectory());
// Existing, rely on FileAttributes
const string existingFile = #"C:\Windows\notepad.exe";
var existingFileDirectoryInfo = new DirectoryInfo(existingFile);
Assert.IsFalse(existingFileDirectoryInfo.IsDirectory());
var existingFileFileInfo = new FileInfo(existingFile);
Assert.IsFalse(existingFileFileInfo.IsDirectory());
}
public bool IsDirectory(string path) {
return string.IsNullOrEmpty(Path.GetFileName(path)) || Directory.Exists(path);
}
Checks if the path file name is an empty string, or if the directory exists. This way you won't have the file attributes error while still providing redundancies for a possible exists failure.
Here's what we use:
using System;
using System.IO;
namespace crmachine.CommonClasses
{
public static class CRMPath
{
public static bool IsDirectory(string path)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
string reason;
if (!IsValidPathString(path, out reason))
{
throw new ArgumentException(reason);
}
if (!(Directory.Exists(path) || File.Exists(path)))
{
throw new InvalidOperationException(string.Format("Could not find a part of the path '{0}'",path));
}
return (new System.IO.FileInfo(path).Attributes & FileAttributes.Directory) == FileAttributes.Directory;
}
public static bool IsValidPathString(string pathStringToTest, out string reasonForError)
{
reasonForError = "";
if (string.IsNullOrWhiteSpace(pathStringToTest))
{
reasonForError = "Path is Null or Whitespace.";
return false;
}
if (pathStringToTest.Length > CRMConst.MAXPATH) // MAXPATH == 260
{
reasonForError = "Length of path exceeds MAXPATH.";
return false;
}
if (PathContainsInvalidCharacters(pathStringToTest))
{
reasonForError = "Path contains invalid path characters.";
return false;
}
if (pathStringToTest == ":")
{
reasonForError = "Path consists of only a volume designator.";
return false;
}
if (pathStringToTest[0] == ':')
{
reasonForError = "Path begins with a volume designator.";
return false;
}
if (pathStringToTest.Contains(":") && pathStringToTest.IndexOf(':') != 1)
{
reasonForError = "Path contains a volume designator that is not part of a drive label.";
return false;
}
return true;
}
public static bool PathContainsInvalidCharacters(string path)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
bool containedInvalidCharacters = false;
for (int i = 0; i < path.Length; i++)
{
int n = path[i];
if (
(n == 0x22) || // "
(n == 0x3c) || // <
(n == 0x3e) || // >
(n == 0x7c) || // |
(n < 0x20) // the control characters
)
{
containedInvalidCharacters = true;
}
}
return containedInvalidCharacters;
}
public static bool FilenameContainsInvalidCharacters(string filename)
{
if (filename == null)
{
throw new ArgumentNullException("filename");
}
bool containedInvalidCharacters = false;
for (int i = 0; i < filename.Length; i++)
{
int n = filename[i];
if (
(n == 0x22) || // "
(n == 0x3c) || // <
(n == 0x3e) || // >
(n == 0x7c) || // |
(n == 0x3a) || // :
(n == 0x2a) || // *
(n == 0x3f) || // ?
(n == 0x5c) || // \
(n == 0x2f) || // /
(n < 0x20) // the control characters
)
{
containedInvalidCharacters = true;
}
}
return containedInvalidCharacters;
}
}
}
The most accurate approach is going to be using some interop code from the shlwapi.dll
[DllImport(SHLWAPI, CharSet = CharSet.Unicode)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
[ResourceExposure(ResourceScope.None)]
internal static extern bool PathIsDirectory([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath);
You would then call it like this:
#region IsDirectory
/// <summary>
/// Verifies that a path is a valid directory.
/// </summary>
/// <param name="path">The path to verify.</param>
/// <returns><see langword="true"/> if the path is a valid directory;
/// otherwise, <see langword="false"/>.</returns>
/// <exception cref="T:System.ArgumentNullException">
/// <para><paramref name="path"/> is <see langword="null"/>.</para>
/// </exception>
/// <exception cref="T:System.ArgumentException">
/// <para><paramref name="path"/> is <see cref="F:System.String.Empty">String.Empty</see>.</para>
/// </exception>
public static bool IsDirectory(string path)
{
return PathIsDirectory(path);
}
I came across this when facing a similar problem, except I needed to check if a path is for a file or folder when that file or folder may not actually exist. There were a few comments on answers above that mentioned they would not work for this scenario. I found a solution (I use VB.NET, but you can convert if you need) that seems to work well for me:
Dim path As String = "myFakeFolder\ThisDoesNotExist\"
Dim bIsFolder As Boolean = (IO.Path.GetExtension(path) = "")
'returns True
Dim path As String = "myFakeFolder\ThisDoesNotExist\File.jpg"
Dim bIsFolder As Boolean = (IO.Path.GetExtension(path) = "")
'returns False
Hopefully this can be helpful to someone!
soooo late in the game i know, but thought i'd share this anyway. If you are solely working with the paths as strings, figuring this out is easy as pie:
private bool IsFolder(string ThePath)
{
string BS = Path.DirectorySeparatorChar.ToString();
return Path.GetDirectoryName(ThePath) == ThePath.TrimEnd(BS.ToCharArray());
}
for example:
ThePath == "C:\SomeFolder\File1.txt" would end up being this:
return "C:\SomeFolder" == "C:\SomeFolder\File1.txt" (FALSE)
Another example:
ThePath == "C:\SomeFolder\" would end up being this:
return "C:\SomeFolder" == "C:\SomeFolder" (TRUE)
And this would also work without the trailing backslash:
ThePath == "C:\SomeFolder" would end up being this:
return "C:\SomeFolder" == "C:\SomeFolder" (TRUE)
Keep in mind here that this only works with the paths themselves, and not the relationship between the path and the "physical disk"... so it can't tell you if the path/file exists or anything like that, but it sure can tell you if the path is a folder or a file...
If you want to find directories, including those that are marked "hidden" and "system", try this (requires .NET V4):
FileAttributes fa = File.GetAttributes(path);
if(fa.HasFlag(FileAttributes.Directory))
I needed this, the posts helped, this gets it down to one line, and if the path isn't a path at all, it just returns and exits the method. It addresses all of the above concerns, doesn't need the trailing slash either.
if (!Directory.Exists(#"C:\folderName")) return;
I see, I'm 10 years too late to the party.
I was facing the situation, where from some property I can receive either a file name or a full file path. If there is no path provided, I have to check the file-existence by attaching a "global" directory-path provided by another property.
In my case
var isFileName = System.IO.Path.GetFileName (str) == str;
did the trick.
Ok, it's not magic, but perhaps this could save someone a few minutes of figuring out.
Since this is merely a string-parsing, so Dir-names with dots may give false positives...
I use the following, it also tests the extension which means it can be used for testing if the path supplied is a file but a file that doesn't exist.
private static bool isDirectory(string path)
{
bool result = true;
System.IO.FileInfo fileTest = new System.IO.FileInfo(path);
if (fileTest.Exists == true)
{
result = false;
}
else
{
if (fileTest.Extension != "")
{
result = false;
}
}
return result;
}
using System;
using System.IO;
namespace FileOrDirectory
{
class Program
{
public static string FileOrDirectory(string path)
{
if (File.Exists(path))
return "File";
if (Directory.Exists(path))
return "Directory";
return "Path Not Exists";
}
static void Main()
{
Console.WriteLine("Enter The Path:");
string path = Console.ReadLine();
Console.WriteLine(FileOrDirectory(path));
}
}
}
Using the selected answer on this post, I looked at the comments and give credence to
#ŞafakGür, #Anthony and #Quinn Wilson for their info bits that lead me to this improved answer which I wrote and tested:
/// <summary>
/// Returns true if the path is a dir, false if it's a file and null if it's neither or doesn't exist.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static bool? IsDirFile(this string path)
{
bool? result = null;
if(Directory.Exists(path) || File.Exists(path))
{
// get the file attributes for file or directory
var fileAttr = File.GetAttributes(path);
if (fileAttr.HasFlag(FileAttributes.Directory))
result = true;
else
result = false;
}
return result;
}
Maybe for UWP C#
public static async Task<IStorageItem> AsIStorageItemAsync(this string iStorageItemPath)
{
if (string.IsNullOrEmpty(iStorageItemPath)) return null;
IStorageItem storageItem = null;
try
{
storageItem = await StorageFolder.GetFolderFromPathAsync(iStorageItemPath);
if (storageItem != null) return storageItem;
} catch { }
try
{
storageItem = await StorageFile.GetFileFromPathAsync(iStorageItemPath);
if (storageItem != null) return storageItem;
} catch { }
return storageItem;
}
Very late to the party here but I've found the Nullable<Boolean> return value to be quite ugly - IsDirectory(string path) returning null doesn't equate to a non-existent path without verbose commenting, so I've come up with the following:
public static class PathHelper
{
/// <summary>
/// Determines whether the given path refers to an existing file or directory on disk.
/// </summary>
/// <param name="path">The path to test.</param>
/// <param name="isDirectory">When this method returns, contains true if the path was found to be an existing directory, false in all other scenarios.</param>
/// <returns>true if the path exists; otherwise, false.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="path"/> is null.</exception>
/// <exception cref="ArgumentException">If <paramref name="path"/> equals <see cref="string.Empty"/></exception>
public static bool PathExists(string path, out bool isDirectory)
{
if (path == null) throw new ArgumentNullException(nameof(path));
if (path == string.Empty) throw new ArgumentException("Value cannot be empty.", nameof(path));
isDirectory = Directory.Exists(path);
return isDirectory || File.Exists(path);
}
}
This helper method is written to be verbose and concise enough to understand the intent the first time you read it.
/// <summary>
/// Example usage of <see cref="PathExists(string, out bool)"/>
/// </summary>
public static void Usage()
{
const string path = #"C:\dev";
if (!PathHelper.PathExists(path, out var isDirectory))
return;
if (isDirectory)
{
// Do something with your directory
}
else
{
// Do something with your file
}
}
Just adding a fringe case - "Folder Selection." in path
In my app I get recently opened paths passed to me, some of which have "Folder Selection." at the end.
Some FileOpenDialogs and WinMerge add "Folder Selection." to paths (it's true).
But under Windows OS "Folder Selection." is not an advised file or folder name (as in don't do it, ever - shakes fist).
As said here: http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
Do not end a file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface does not. However, it is acceptable to specify a period as the first character of a name. For example, ".temp".
So whilst "Folder Selection." shouldn't be used, it can be. (awesome).
Enough explanation - my code (I like enums a lot):
public static class Utility
{
public enum ePathType
{
ePathType_Unknown = 0,
ePathType_ExistingFile = 1,
ePathType_ExistingFolder = 2,
ePathType_ExistingFolder_FolderSelectionAdded = 3,
}
public static ePathType GetPathType(string path)
{
if (File.Exists(path) == true) { return ePathType.ePathType_ExistingFile; }
if (Directory.Exists(path) == true) { return ePathType.ePathType_ExistingFolder; }
if (path.EndsWith("Folder Selection.") == true)
{
// Test the path again without "Folder Selection."
path = path.Replace("\\Folder Selection.", "");
if (Directory.Exists(path) == true)
{
// Could return ePathType_ExistingFolder, but prefer to let the caller known their path has text to remove...
return ePathType.ePathType_ExistingFolder_FolderSelectionAdded;
}
}
return ePathType.ePathType_Unknown;
}
}
This is my solution, beware that i was looking for a function that strictly avoid any unnecessary file system access at all, but only string manipulations are allowed here (paths may not exist):
public static bool IsFolder(string path)
{
if (string.IsNullOrEmpty(path)) return false;
if (path.EndsWith("\\")) return true;
return (path.Contains("\\") && string.IsNullOrEmpty(Path.GetExtension(path)));
}
Wouldn't this work?
var isFile = Regex.IsMatch(path, #"\w{1,}\.\w{1,}$");

Categories

Resources