i have to start process which is placed inside Program Files. But the problem is that Process.Start does not taking space in path.
Process regeditProcess = Process.Start("regedit.exe", "/s C:\\Program Files\\Test Folder\\sample.reg");
Path:
C:\\Program Files\\Test Folder\\sample.reg
there is a space between Program and Files in 'Program Files'.
Thats my problem. How to avoid space?
You should pass command line arguments, containing spaces, in quotes ("), like this:
Process regeditProcess = Process.Start("regedit.exe", "/s \"C:\\Program Files\\Test Folder\\sample.reg\"");
Process.Start is not the problem here, the problem is that regedit.exe doesn't accept spaces in the parameter. Put it into quotes:
Process.Start("regedit.exe", "/s \"C:\\Program Files\\Test Folder\\sample.reg\"");
also, you should use %ProgramFiles% or something equivalent to get the program files folder instead of hardcoding "C:\\Program Files".
You can do something like this to get Program files
Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles)
Here is more detailed code
if(Environment.Is64BitOperatingSystem)
{
Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
}
else
{
Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles)
}
The proper thing to do would be to quote the path that contains spaces. So the argument string should be like this:
"/s \"C:\\Program Files\\Test Folder\\sample.reg\""
Though when working with paths, you generally should always use verbatim literal strings.
#"/s ""C:\Program Files\Test Folder\sample.reg"""
Otherwise, you could convert the path using 8.3 names. I don't know of any methods to do this for you in the framework but the rules are simple. If you have a long name that is longer than 6 characters, you take the first 6 non-space characters and append it with tilde (~) followed by a number (usually starting with 1). If multiple files have the same 6 characters, the number is incremented in alphabetical order. So in your case it could be written:
#"/s C:\Progra~1\TestFo~1\sample.reg"
Related
I have a noodle scratcher
I want to grab a filename from the command line argument - the program is invoked using the context menu (right click) and calling, to do this it is added to the registry etc etc.
It works fine on local files on lettered drives, however when I run it against a network address that contains spaces I hit an issue.
i.e. "\\server\test folder\filename.txt"
If there are no spaces it seems to return the correct path. If there are spaces in the directory or filename it turns that component into jibberish.
Example Images:
Path with spaces
\\192.168.0.200\Web\1K5SXZ~6\T5MSMN~1.TXT
Path without spaces
\\192.168.0.200\Web\testdirectory\testfile.txt
Code used:
string[] args = Environment.GetCommandLineArgs();
foreach (string a in args)
{
MessageBox.Show(a);
}
Any Thoughts?
Thx
E
This happens because if the executable was called with an argument with spaces you wouldn't be able to differentiate wether it's 2 arguments or one:
myapp.exe \foo bar\baz
Could be interpreted as \foo and \bar\baz (2 arguments, because there's a space) rather than the (intended) \foo bar\baz; usually you just surround the path with quotes to prevent this:
myapp.exe "\foo bar\baz"
I guess explorer just takes the safe(r) route* and simply uses the 8.3 filename which will never contain spaces anyway and, thus, remove the need for quotes.
See here for more; if you want the LFN (Long File Name) it's easy to get it back:
string[] args = Environment.GetCommandLineArgs();
foreach (string a in args)
{
MessageBox.Show(new FileInfo(a).FullName);
}
* Actually; I think maybe explorer does so because it has no way of knowing if it's invoking an "LFN aware" application. But that's just (not well thought-through) speculation on my part.
I've been attempting to list all filepaths for programs that start on boot. I encountered the following data
Rundll32.exe shell32.dll, ShellExec_RunDLL C:\Users\Name\AppData\Roaming\Oracle\JavaUpdate.exe
"C:\Program Files (x86)\Steam\steam.exe" -silent
This data is from the registry \HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run, obtained using following code
foreach(var valueName in registryKey.GetValueNames()){
bootItems.Add(registryKey.GetValue(valueName);
}
Which solution could extract the path from both?
I've attempted to use the following regular expression and variations without any luck.
"^\"([^\"]*)\".*$"
If they only ever look like that then this regex will do the job:
\b.:\\.+?.exe\b
It matches any character followed by a colon and a slash,followed by any text that then ends with .exe where the start/end is either a word break or a start/end of line.
I'm creating a console application in C#, and I want to check if a specific file (foo.exe). But when the path contains spaces (C:\A Folder With Spaces\) it checks if foo.exe exists at this directory: C:\A.
Question: How can I check inside of a folder that contains spaces?
It looks like you are passing the name of the file as command-line parameter. In this case the split at the space is done by Windows cmd command processor when you pass C:\A Folder With Spaces\ as parameter. To fix this, enclose the file name in doublequotes:
c:\test>myprog.exe "C:\A Folder With Spaces\foo.exe"
If (File.Exists(#"C:\A Folder With Spaces\foo.exe")
{
//the # sign makes the spaces be taken literally.
}
Sounds like you're supplying the path as an argument to the console application? In which case enclose the path argument in quotes
I am trying to pass a file path into a C# Console Application but am having problems with the string being incorrect by the time it reaches the console application.
If I run my application from the command line, with a file path parameter:
MyApp "C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject\"
A windows dialogue pops up and informs me that my application has stopped working, and when I click the Debug option, I can see that the result of args[0] is:
C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject"
Note there is still a trailing quote at the end.
If I pass a second argument:
MyApp "C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject\" "any old string"
I get an error again, and after viewing in debug I see that args[0] is:
C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject" any
I am baffled as to why this is happening. My only guess is that the backslashes in the string are causing some kind of escape sequence from the string? Edit: I notice that the same is happening in the string example above! It seems \" is causing problems here.
I just want to pass in the file path of the current solution directory and am calling my app from a pre-build event using $(SolutionDir), and know that I can get the path of the current solution in other ways. But this is simplest and I am curious as to why it does not work as expected.
Yes, the rules for commandline arguments are a little murky.
The \ is the escape char and you can use it to escape quotes ("). You'll have to escape a backslash but only when it is preceding a quote. So use (note the '\\' at the end):
MyApp "C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject\\"
or, simpler but you'll have to deal with it in C# somehow:
MyApp "C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject"
Also see this question
That's why it's always better to use / in path
"C:/Users/DevDave/Documents/Visual Studio 2012/Projects/MyProject/" "any old string"
take a look: http://en.wikipedia.org/wiki/Path_(computing) , you can use both \ and / in path but if you want any shell compatibility I suggest to use /
Anything that comes after MyApp will be the first argument (args[0]). In your case, the first argument is "C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject\". Also, the quote at the end of the string seems to happen because \" means that you want to want to escape the quote and write it as a string. In this case, the quote is not closing the string. That is the reason that your args[0] is the whole thing that comes after MyApp
If you don't want to scape the quote and have a slash behind it, you should do \\"
You could try this and tell me what happens:
MyApp "C:\Users\DevDave\Documents\Visual Studio 2012\Projects\MyProject\\"
(look at the double slash)
Hope it helps.
Continuation of Henk's answer, and choose to add a \ at the end of the path, then:
If you choose to hack the bug by choosing this code in Henk's answer ("simpler but you'll have to deal with it in C# somehow:"), then you should realize some bugs that will occur:
args[0] will only be set, even if you pass multiple parameters in. The length of args will be equal to 1. So you have to split args[0] into multiple pieces for your hack.
You have to replace any " characters with a \ if they are at the end of the pieces you split.
If I have an executable called app.exe which is what I am coding in C#, how would I get files from a folder loaded in the same directory as the app.exe, using relative paths?
This throws an illegal characters in path exception:
string [ ] files = Directory.GetFiles ( "\\Archive\\*.zip" );
How would one do this in C#?
To make sure you have the application's path (and not just the current directory), use this:
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.getcurrentprocess.aspx
Now you have a Process object that represents the process that is running.
Then use Process.MainModule.FileName:
http://msdn.microsoft.com/en-us/library/system.diagnostics.processmodule.filename.aspx
Finally, use Path.GetDirectoryName to get the folder containing the .exe:
http://msdn.microsoft.com/en-us/library/system.io.path.getdirectoryname.aspx
So this is what you want:
string folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + #"\Archive\";
string filter = "*.zip";
string[] files = Directory.GetFiles(folder, filter);
(Notice that "\Archive\" from your question is now #"\Archive\": you need the # so that the \ backslashes aren't interpreted as the start of an escape sequence)
Hope that helps!
string currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string archiveFolder = Path.Combine(currentDirectory, "archive");
string[] files = Directory.GetFiles(archiveFolder, "*.zip");
The first parameter is the path. The second is the search pattern you want to use.
Write it like this:
string[] files = Directory.GetFiles(#".\Archive", "*.zip");
. is for relative to the folder where you started your exe, and # to allow \ in the name.
When using filters, you pass it as a second parameter. You can also add a third parameter to specify if you want to search recursively for the pattern.
In order to get the folder where your .exe actually resides, use:
var executingPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
As others have said, you can/should prepend the string with # (though you could also just escape the backslashes), but what they glossed over (that is, didn't bring it up despite making a change related to it) was the fact that, as I recently discovered, using \ at the beginning of a pathname, without . to represent the current directory, refers to the root of the current directory tree.
C:\foo\bar>cd \
C:\>
versus
C:\foo\bar>cd .\
C:\foo\bar>
(Using . by itself has the same effect as using .\ by itself, from my experience. I don't know if there are any specific cases where they somehow would not mean the same thing.)
You could also just leave off the leading .\ , if you want.
C:\foo>cd bar
C:\foo\bar>
In fact, if you really wanted to, you don't even need to use backslashes. Forwardslashes work perfectly well! (Though a single / doesn't alias to the current drive root as \ does.)
C:\>cd foo/bar
C:\foo\bar>
You could even alternate them.
C:\>cd foo/bar\baz
C:\foo\bar\baz>
...I've really gone off-topic here, though, so feel free to ignore all this if you aren't interested.
Pretty straight forward, use relative path
string[] offerFiles = Directory.GetFiles(Server.MapPath("~/offers"), "*.csv");