Use Process.Start to execute a File on a Shared Folder - c#

I'm trying to start a new Process by using Process.Start() which works great when I pass in
Process.Start("C:\\Documents and Settings\\Upload.exe")
but is it possible to perform that same operation when I move Upload.exe into a shared folder under My Network Places? I tried
Process.Start("\\Shared Folder\\Upload.exe");
but I get a Win32Exception. Thanks for any information or suggestions in advance.

You should use UNC path for accessing a network resource. (Your file becomes a network resource when you place it in a shared path)
UNC path takes the following form.
\\ServerName\SharedPath\YourFile.exe
or
\\ServerName\D$\SharedPath\YourFile.exe
where D$ is the drive letter.
In your case you may have to use the following
Process.Start(#"\\Server-Name\Shared Folder\Upload.exe");
Use # symbol in front of the string because your \\ will be treated as \, as an escape character.

Try either: "\\\\Shared Folder\\Upload.exe" or #"\\Shared Folder\Upload.exe"

Related

How to pass relative path to use the File.Delete static function in C#?

I've been trying to create a way to upload, download and delete a PDF file. The upload and the download function work fine, but when I try to delete the PDF it doesn't really work as I want it to.
It does work when I use this form:
File.Delete(#"C:\Users\Donovan\1_Test.pdf");
But it doesn't work when I try this:
File.Delete(#"~\1_Test.pdf");
I want to find a way to make the second line of code work, because I work in a team and we don't share the same file path.
Use Environment.GetFolderPath to find the user's home directory.
string home = Environment.GetFolderPath(Environment.SpecialFolder.UseProfile);
File.Delete(Path.Combine(home, "1_Test.pdf"));
You might also want to consider putting the file in the folder for temporary files instead. You can find that location with Path.GetTempPath. (Note that windows will not automatically clean up temporary files, so you still need to delete anything you put there after you are done with it.)
Try this. I think it works :D
File.Delete(Server.MapPath("~/") + "1_Test.pdf");
If you are all using the userpath you can go with this approach:
System.IO.File.Delete(
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"1_Test.pdf"
)
);
You unfortunately cannot make it work with ~. This only works as a relative path for web applications.
We use a local config file for our application where each developer stores its own preferences and can change these independent of other developers.
Depending on your application (web, desktop, mobile, windows, linux, whatever) you can write a config-object and fill it or use i.e. appsettings in web.config for this purpose.
var basePath = Config.FileBase;
File.Delete(Path.Combine(basePath, "\1_Test.pdf"));
Another method:
File.Delete(Environment.ExpandEnvironmentVariables("%USERPROFILE%\\1_Test.pdf"));
Have you considered it to put the *.pdf files in a database?

How to get minimal absolute path from relative path without any permission checks?

Say, I have two path strings, an absolute one such as #"C:\abc\xyz", and a relative one such as #"..\def". How do I reliably combine those to yield the minimal form #"C:\abc\def"?
As the process should work for any forms of path that .NET's I/O API supports (i.e. the native paths of the system that .NET or Mono is currently running on, or alternatively something like UNC paths and the like), manual string manipulation seems to be too unreliably a solution.
In general, the tidy way to combine path strings is to use the Path.Combine method:
Path.Combine(#"C:\abc\xyz", #"..\def")
Unfortunately, it does not minimize the path and returns C:\abc\xyz\..\def.
As is suggested in a couple of other questions (e.g. this, or this), the GetFullPath method should be applied to the result:
Path.GetFullPath(Path.Combine(#"C:\abc\xyz", #"..\def"))
The problem with this is that GetFullPath actually looks at the file system rather than just handling the path string. From the docs:
The file or directory specified by path is not required to exist. (...) However, if path does exist, the caller must have permission to obtain path information for path. Note that unlike most members of the Path class, this method accesses the file system.
Therefore, GetFullPath doesn't work if I just want to minimize arbitrary path strings: Depending on whether the path happens to exist on the system where the application is running, the method might fail with a SecurityException if the user does not have access to the path.
So, how do I reliably combine path strings that could be processed by System.IO methods to return the shortest possible absolute path?
You can use AbsolutePath of Uri class
var path = new Uri(Path.Combine(#"C:\abc\xyz", #"..\def")).AbsolutePath;
If you want to use it via System.IO you will run into access violation problems at that point.
Why bother to increase the time till the exception comes?
Use try {} catch {} around GetFullPath and handle the error in place would be my suggestion.
So, how do I reliably combine path strings that could be processed by System.IO methods to return the shortest possible absolute path?

Different slashes in web application paths

Why if I need to check if a folder exists on the web server I need to use backslashes in the path string:
if (Directory.Exists(#"~\assets\images\gallery\thumbnails"))
while to load the image I need to use slashes?
new WebImage("~/assets/images/gallery/thumbnail/name.jpg")
What's rule behind this?
Thanks.
Directory.Exists is a check against file system, which on Windows follows Windows path specification (the link is not exactly "specification," but will do for the purpose) which has \ as directory separator. On *nix systems, however, it would take / as directory separator. Thus, one should use Path.DirectorySeparatorChar for correctness and interoperability.
WebImage takes a URL reference (~ notwithstanding) and follows RFC 1738 which defines / as segment separator.
The two, while appearing similar, are different and (mostly) unrelated concepts.
For URLs you use forward slashes. In file paths in Windows you use backslashes. The first path is to a location on the hard drive. The second path is to a URL.
I believe WebImage refers to a virtual path, as used in URLs and referred to by the browser (for example).
Directory refers to actual physical directories on the server.
Windows uses backslash for physical directories.
URL conventions use slash for virtual paths.

Blank space after file extension -> weird FileInfo behaviour

Somehow a file has appeared in one of my directories, and it has space at the end of its extension -
its name is "test.txt ". The weird thing is that Directory.GetFiles() returns me the path of this
file, but I'm unable to retrieve file information with FileInfo class.
The error manifests here:
DirectoryInfo di = new DirectoryInfo("c:\\somedir");
FileInfo fi = di.GetFileSystemInfos("test*")[0] as FileInfo;
//correctly fi.FullName is "c:\somedir\test.txt "
//but fi.Exists==false (!)
Is FileInfo class broken? Can I somehow retrieve information about this file? I really don't know how did that file appear on my file system, and I am unable to recreate some more of them.
All of my attempts to create a new file with this type of extension have failed, but now my program is
crashing when encoutering it. I can easily handle the exception when finding the file, but boy am I
curious about this!
Ending file names with a space is documented as a Bad Idea.
From MSDN "Naming Files, Paths, and Namespaces (Windows)":
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.
Also, the KB article "INFO: Filenames Ending with Space or Period Not Supported":
Problems can arise when a Macintosh client creates a file on a Windows NT server. The code to remove trailing spaces and periods is not carried out and the Macintosh user gets the correctly punctuated filename. The Win32 APIs FindFirstFile() and FindNextFile() return a filename that ends in a space or in a period; however, there is no way to create or open the file using the Win32 API.
DirectoryInfo probably uses FindFirstFile() and friends to produce directory listings. File.Exists is most likely implemented through GetFileAttributes() which probably suffers from the same problem as CreateFile() and will report a nonexistent file.
Hence, not a problem in .NET specifically, but in Windows itself.
Yes i know of these files. I also got once such a beast thing. To get rid of it i don't know about a programming way in C#, but good old command line is your friend:
Open a console window in the given folder (or execute cmd and navigate to the folder with cd command). Now enter dir /x to retrieve the shortname of the files in this directory. Use this name to delete or rename the file by using the del or ren command.
You can manipulate files with trailing spaces (among other edge cases) if you use the \\?\ path syntax: \\?\c:\somedir\test.txt .

Is it worth it to lookup the default application in the registry when opening a file from a C# application?

I'm building an application (a side project which is likely to enlist the help of the stackoverflow community on more than one occasion) which will need to open a variety of file types (i.e. open Word documents in Word, not natively in my application).
I've been playing with some code for looking up the default application for the file type in the registry and passing this to Process.Start(). There seem to be two issues with this approach:
1) The application name is quoted in some instances, and not in others.
2) Process.Start() requires that the application path and it's arguments are passed separately (i.e. Process.Start("notepad.exe", #"C:\myfile.txt"); rather than Process.Start(#"notepad.exe C:\myfile.txt");).
This means when I retrieve the path from the registry, I have to split it (after determining if I need to split on quotes or spaces) to determine what part is the application path and what parts are arguments, then pass those separately to Process.Start().
The alternative seems to be to just pass the filename, as in Process.Start(#"C:\myfile.txt"), but I think this only works if the application is in the Path environment variable.
Which way is better? In the case of the registry, is there a common solution for how to do the argument parsing?
Thanks for any and all help!
Update:
I guess the short answer is 'No.'
It seems like I was really going the overkill route, and that passing just the filename will work whenever there's an associated value in the registry. I.e. anything I find in the registry myself, Process.Start() already knows how to do.
I did discover that when I try this with a "new" filetype, I get a Win32Exception stating "No application is associated with the specified file for this operation." Fredrik Mörk mentions in a comment that this doesn't occur for him in Vista. What's the proper way to handle this?
If the extension is registered to be opened with a certain application, it doesn't need to be in the PATH in order to run.
The application does not need to be in the PATH if you only specify the filename. The following code worked fine for me:
System.Diagnostics.Process.Start(#"C:\Users\Dan\Desktop\minors.pdf");
You typically do not need to lookup the program for registered types, and the program does not typically need to be in the PATH environment variable. Usually the command in the registry contains the full path. This is how the command for .kml files (Google Earth) looks (in my computer):
C:\Program Files\Google\Google Earth\googleearth.exe "%1"
Given that, you can safely just use Process.Start together with the document file names. Should it be that the file type is not registered you will invoke the default Windows behaviour for this (asking you which program to use, and so on).

Categories

Resources