Passing 2 filepaths with spaces via commandline to a C# application - c#

I am trying to pass two directory paths via the command line to a C# application. These paths will likely contain spaces, and given that C# populates args[] by splitting across spaces, this is giving me problems.
What I tried was passing the paths wrapped in quotes, like this:
myprogram.exe "C:\aa a\bbb\" "C:\ppp\ll l\"
..this, however, creates a problem because the backslash at the end of each path is being interpreted by C# as an escape character, so it is parsing the double quote as well. When I run the app with these argurments, args[] contains only one entry:
C:\aa a\bbb" C:\ppp\ll l"
The easy solution would be to only enter directory paths without the final backslash, but it is not optimal and will likely frustrate users of the program.
Is there an easy solution to this?

Did you try to pass them "twiced" ?
myprogram.exe "C:\\aa a\\bbb\\" "C:\\ppp\\ll l\\"

Related

Regex - Extracting File Paths

I need to be able to extract the full file path out of this string (without whatever is after the file extension):
$/FilePath/FilePath/KeepsGoing/Folder/Script.sql (CS: 123456)
A simple solution such as the following could would work for this case, however it is only limited to a file extension with 3 characters:
(\$.*\..{3})
However, I find problems with this when the file contains multiple dots:
$/FilePath/FilePath/File.Setup.Task.exe.config (CS: 123456)
I need to be able to capture the full file path (from $ to the end of whatever the file extension is, which can be any number of things). I need to be able to get this no matter how many dots are in the name of the file. In some cases there are spaces in the name of the file too, so I need to be able to incorporate that.
Edit: The ending (CS....) in this case is not standard. All kinds of stuff can follow the path so I cannot predict what will come after the path, but the path will always be first. Sometimes spaces do exist in the file name.
Any suggestions?
Try this:
(\$.*\.[\w.-]+)
But! it will not properly match files with space or special chars in the file extension. If you need to match files that might have special chars in the file extension you'll need to elaborate on the input (is it quoted? is it escaped?).

Directory.GetFiles alters string path

Using System.IO, I tried the following code:
string[] files = Directory.GetFiles("\\folder\\folder_2\\folder_3");
And got the following exception:
"System.IO.DirectoryNotFoundException - It was not possible to locate part of the path 'C:\folder\folder_2\folder_3)' "
I don't know why "c:\" was added to the original string, and I can't seem to keep the method from doing so. What am I doing wrong?
Any help is much appreciated.
A backslash (\) at the start of a path makes it an absolute path. Remove the first \ if you want a relative path:
string[] files = Directory.GetFiles("folder\\folder_2\\folder_3");
You need to escape each of the beginning backslashes in your path, you only escaped a single slash. Use either correct escaping:
string[] files = Directory.GetFiles("\\\\folder\\folder_2\\folder_3");
Or you can use a verbatim string literal:
string[] files = Directory.GetFiles(#"\\folder\folder_2\folder_3");
Full explanation found in MSDN Documentation
In addition to the answers provided, you could use verbatim string literals, which will pass the string exactly without the need for escaping with all the messy backslashes.
In your case this would be
string[] files = Directory.GetFiles(#"folder\folder_2\folder_3");
Notice that the # is outside of quotes, but stuck to the opening quotes, this tells C# to use it, (pardon the pun) literally. The syntax highlighting for this kind of string will also change in Visual Studio, just FYI.
edit: saw a comment by another user advising you to use the #, it's the same thing. Sorry did not see this earlier.
Read about them here at MSDN

Sox absolute paths and piping

I have a question about using Sox. I need to mix many audio files and every file has it's own specific time when it should be added. I'm using piping and everything goes fine until I need to grab files with absolute paths with spaces in folder names. In this case I need to use double quotes twice (in path and to allocate piping). Here's example:
-m "initial.wav" "|sox "path with spaces\file1.mp3" -p pad 8.52 0" "|sox "another path with spaces\file2.mp3" -p pad 19.07 0" "|sox "file3.mp3" -p pad 36.52 0" "output.mp3"
And of course these quotes around file paths ruin command.
How can I fix this? Maybe it's possible to use single quotes somehow or maybe I'm missing something obvious...
Will may be useful to add that I'm runing sox from C# app, thus everything happens in Windows.
Usually, it is possible to escape the inner double quotes somehow. (Most?) *nix shells use the backslash for that purpose, i.e. you would write ... "|sox \"path with spaces/file1.mp3\" ...". Of course, Windows uses the backslash for different purposes (delimiting path components), so there may be a slightly different way to escape quotes.

C# - Regex for file paths e.g. C:\test\test.exe

I am currently looking for a regex that can help validate a file path e.g.:
C:\test\test2\test.exe
I decided to post this answer which does use a regular expression.
^(?:[a-zA-Z]\:|\\\\[\w\.]+\\[\w.$]+)\\(?:[\w]+\\)*\w([\w.])+$
Works for these:
\\test\test$\TEST.xls
\\server\share\folder\myfile.txt
\\server\share\myfile.txt
\\123.123.123.123\share\folder\myfile.txt
c:\folder\myfile.txt
c:\folder\myfileWithoutExtension
Edit: Added example usage:
if (Regex.IsMatch (text, #"^(?:[a-zA-Z]\:|\\\\[\w\.]+\\[\w.$]+)\\(?:[\w]+\\)*\w([\w.])+$"))
{
// Valid
}
*Edit: * This is an approximation of the paths you could see. If possible, it is probably better to use the Path class or FileInfo class to see if a file or folder exists.
I would recommend using the Path class instead of a Regex if your goal is to work with filenames.
For example, you can call Path.GetFullPath to "verify" a path, as it will raise an ArgumentException if the path contains invalid characters, as well as other exceptiosn if the path is too long, etc. This will handle all of the rules, which will be difficult to get correct with a Regex.
This is regular expression for Windows paths:
(^([a-z]|[A-Z]):(?=\\(?![\0-\37<>:"/\\|?*])|\/(?![\0-\37<>:"/\\|?*])|$)|^\\(?=[\\\/][^\0-\37<>:"/\\|?*]+)|^(?=(\\|\/)$)|^\.(?=(\\|\/)$)|^\.\.(?=(\\|\/)$)|^(?=(\\|\/)[^\0-\37<>:"/\\|?*]+)|^\.(?=(\\|\/)[^\0-\37<>:"/\\|?*]+)|^\.\.(?=(\\|\/)[^\0-\37<>:"/\\|?*]+))((\\|\/)[^\0-\37<>:"/\\|?*]+|(\\|\/)$)*()$
And this is for UNIX/Linux paths
^\/$|(^(?=\/)|^\.|^\.\.)(\/(?=[^/\0])[^/\0]+)*\/?$
Here are my tests:
Win Regex
Unix Regex
These works with Javascript
EDIT
I've added relative paths, (../, ./, ../something)
EDIT 2
I've added paths starting with tilde for unix, (~/, ~, ~/something)
The proposed one is not really good, this one I build for XSD, it's Windows specific:
^(?:[a-zA-Z]\:(\\|\/)|file\:\/\/|\\\\|\.(\/|\\))([^\\\/\:\*\?\<\>\"\|]+(\\|\/){0,1})+$
Try this one for Windows and Linux support: ((?:[a-zA-Z]\:){0,1}(?:[\\/][\w.]+){1,})
I use this regex for capturing valid file/folder paths in windows (including UNCs and %variables%), with the exclusion of root paths like "C:\" or "\\serverName"
^(([a-zA-Z]:|\\\\\w[ \w\.]*)(\\\w[ \w\.]*|\\%[ \w\.]+%+)+|%[ \w\.]+%(\\\w[ \w\.]*|\\%[ \w\.]+%+)*)
this regex does not match leading spaces in path elements, so
"C:\program files" is matched
"C:\ pathWithLeadingSpace" is not matched
variables are allowed at any level
"%program files%" is matched
"C:\my path with inner spaces\%my var with inner spaces%" is matched
regex CmdPrompt("^([A-Z]:[^\<\>\:\"\|\?\*]+)");
Basically we look for everything that's not in the list of forbidden Windows Path Characters:
< (less than)
> (greater than)
: (colon)
" (double quote)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
I know this is really old... but expanding on #agent-j's response I've added named groups, and support for period characters.
^(?<ParentPath>(?:[a-zA-Z]\:|\\\\[\w\s\.]+\\[\w\s\.$]+)\\(?:[\w\s\.]+\\)*)(?<BaseName>[\w\s\.]*?)$
I've saved this at Regexr
I found most of the answers here to be a little hit or miss.
Found a good solution here though:
https://social.msdn.microsoft.com/forums/vstudio/en-US/31d2bc84-c948-4914-8a9d-97b9e788b341/validate-a-network-folder-path
Note* - this is only for network shares - not local files
Answer:
string pattern = #"^\\{2}[\w-]+(\\{1}(([\w-][\w-\s]*[\w-]+[$$]?)|([\w-][$$]?$)))+";
string[] names = { #"\\my-network\somelocation", #"\\my-network\\somelocation",
#"\\\my-network\somelocation", #"my-network\somelocation",
#"\\my-network\\somelocation",#"\\my-network\somelocation\aa\dd",
#"\\my-network\somelocation\",#"\\my-network\\somelocation"};
foreach (string name in names)
{
if (Regex.IsMatch(name, pattern))
{
Console.WriteLine(name);
//Directory.Exists function to check if file exists
}
}
Alexander's Answer + Relative Paths
Alexander has the most correct answer thus far since it supports spaces in file names (i.e. C:\Program Files (x86)\ will match)... This aims to include relative paths as well.
For example, you can do cd / or cd \ and it does the same thing.
Further more, if you're currently in C:\some\path\to\some\place and you type either of those commands, you end up at C:\
Even more, you should consider paths, that start with '/' as a root path (to the current drive).
(?:[a-zA-Z]:(\|/)|file://|\\|.(/|\)|/)([^,\/:*\?\<>\"\|]+(\|/){0,1})
A Modified version of Alexander's answer, however, we include paths that are relative with no leading / or drive letter, as well as / with no leading drive letter (relative to the current drive as root).

What is does the syntax [/ ] mean in a C# string

I am not able to google for as, as Google blocks out symbols.
it appeared in this context:
Console.WriteLine("Usage: findduplicatefiles [/sub] DirectoryName [DirectoryName]...");
Thanks :)
It doesn't mean anything in C#. All that Console.WriteLine() call does is write this string:
"Usage: findduplicatefiles [/sub] DirectoryName [DirectoryName]..."
into the console as output.
However, in the Windows command line, / functions as a command-line argument delimiter, and [] means it's an optional argument. The usage prompt is telling the user that sub is an optional argument to use with the findduplicatefiles program.
Examples:
Run findduplicatefiles.exe against the current directory:
C:\>findduplicatefiles .
Run findduplicatefiles.exe against the current directory with the sub argument:
C:\>findduplicatefiles /sub .
Run findduplicatefiles.exe against two directories, C:\abc and C:\def, with the sub argument:
C:\>findduplicatefiles /sub abc def
"[/" in a string doesn't mean anything to C#. It just writes those characters out. But I think you are confused about the meaning of what is being written out.
There is a convention when documenting command-line programs where putting an argument in square braces means the argument is optional. Thus, the string your program is writing out indicates that the command findduplicatefiles may optionally have an argument /sub after which it must have at least one directory name, and may optionally have other directory names.
In this case is does not mean anything to C#. It's just a character in the string just like the rest of the string.
Means optionally put /sub before directoryName. It is not a C# question.

Categories

Resources