C# detect folder junctions in a path - c#

I want to make a quick check if in a complete path a Junction point is used. I already have a function to test a folder like IsJunction() but maybe there is an other solution to not call IsJunction() on every subfolder.
So I'm looking for a function like HasJunctionsInPath(string path) without testing each folder of the path.
Is there something which can do this?
Edit:
Or better...
Is it possible to resolve all junctions in a path to get the real location of a file or folder? This would be even better solve my problem and I still can compare the result with the original path to implement a bool HasJunctionsInPath(string path) function.

Look at the solution of Jeff Brown.
He implemented your features in a static class, that seems to just work fine.
http://www.codeproject.com/KB/files/JunctionPointsNet.aspx

As far as I know there's no out of the box implementation in c# to handle junctions / reparse points directly.
So you have to do some interop with kernel32.dll. This is a bit tricky, but you find samples.
You'll need the CreateFile() & DeviceIoControl() calls.
Here is a good sample to start:
http://www.codeproject.com/KB/vista/ReparsePointID.aspx?display=Print
useful msdn links:
http://msdn.microsoft.com/en-us/library/cc232007%28PROT.13%29.aspx
http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa363216%28v=vs.85%29.aspx
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7acd564f-0e9f-4295-8609-916af6675f0a

Related

Deleting long path too long folder from Network Share

I'm trying to delete folders in a shared location on a network using C#. Some of the folder paths are too long for Windows to handle. I've tried multiple options for this. The best one I found was creating a FileSystemObject, adding \\?\ to the path and calling DeleteFolder on the path that I want to delete, which works on my local computer for paths that are too long, because I have mapped drives like C: and G: etc, but when I try to use it on a Network share folder I get either a HRESULT: 0x800A004C (CTL_E_PATHNOTFOUND) or value does not fall within the expected range.
The following is my code:
private static void DeletePathWithLongFileNames(string path)
{
string tmpPath = #"\\?\" + path;
FileSystemObject fso = new FileSystemObject();
fso.DeleteFolder(tmpPath, true);
}
let's say for example, the network + share folder is \\myServer\mySharedFolder\folder1\etc\etc, which would be the path string I'm sending to my delete function
then the tmpPath is showing as "\\\\?\\\\\\myServer\\mySharedFolder\\folder1\\etc\\etc"
I don't know much about UNC so I don't know if this is what is wrong or not. I'm pretty sure there is something wrong with my tmpPath variable, but again I'm not sure. Maybe it's a syntax error But I can't for the life of me figure out what is wrong. Thanks in advance for the help
EDIT: I believe I have found the answer, I am testing it right now. So far it has worked for me. if I run the DeleteFolder method on the following path \\?\UNC\server\sharedFolder\folder1\etc\etc" this seems to work. Now I just have to figure out how to get rid of all those extra slashes.
EDIT 2: This does work, tested it on a Share folder on a network. It just came down to me not understanding UNC paths.
The safe way to delete paths that are too long is to use AlphaFS. AlphaFS is a .NET library providing more complete Win32 file system functionality to the .NET platform than the standard System.IO classes. The most notable deficiency of the standard .NET System.IO is the lack of support of advanced NTFS features, most notably extended length path support (eg. file/directory paths longer than 260 characters).
See Directory Delete: http://alphafs.alphaleonis.com/doc/2.2/api/html/BE179564.htm
Alphaleonis.Win32.Filesystem.Directory.Delete(path)

How to convert DOS path to normal path (.net)

I have a program that tracks changes on a local folder using a FileSystemWatcher object.
The issue is that sometimes, on some environments and situations (I do not know which ones), this watcher gives me an event on a DOS path ("/Hello/How/Are/You" becomes something like "/HE~1/HO~1/AR~1/YO~1").
What I am looking for is a way to force this path back into its full and normal aspect.
Or at least something that can tell me that the path is indeed a DOS path, so I can process the entry differently.
EDIT: it has to work on long paths (+260 chars), so Path.GetFullPath(sShortPath) does not work for me here!
Path.GetFullPath(#"/HE~1/HO~1/AR~1/YO~1") should do what you need.
The best method depends what you are looking for, if you just want to access the file once then the 8byte file names will work for internal file references
if you want to display to the user or store then there are 2 option
Path contains most of the tools you need to manipulate paths
fullPath = Path.GetFullPath(path1);
FileInfo and DirectoryInfo these 2 classes provide persistent access to files and directory information and while they can be created with any valid path both have a Full name property that provides access to the full path
As others said, Path.GetFullPath(sShortPath) works fine if not used on very long paths (+260 chars).
Here is a link I followed that worked for me.
GetLongPathName from kernel32.dll worked fine with me, I just had to change the 255 StringBuilder limit to a higher value to make it work with long paths.

Significance of a PATH explained

This is probably a rudimentary question but I am still kinda new to programming and I've wondered for awhile. I've done multiple projects in Python, C#, and Java, and when I try to use new libraries (especially for Python) people always say to make sure its in the right PATH and such. I just followed an online tutorial on how to install Java on a new computer and it rekindled my question of what a path really is. Is the Path just were the programming language looks for a library in the file system? I get kinda confused on what it's significance is. Again, I'm sorry for the wide question, its just something that I've never quite gotten on my own programming.
EDIT: I just wanted to thank everyone so much for answering my question. I know it was a pretty dumb one now that I've finally figured out what it is, but it really helped me. I'm slowly working through as many C#, Java and Python tutorials as I can find online, and it's nice to know I have somewhere to ask questions :)
The PATH is an environment variable which the shell (or other command interpreter) uses to search for commands. Usually (always?) commands are found with a greedy algorithm, so entries that come first in the PATH are returned first. For example, a command in /usr/local/bin will override a command in /usr/bin given a PATH such as
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
while the purpose is consistent, the syntax is slightly different on WINDOWS - you would use
C:\> ECHO %PATH%
to "echo" your PATH.
First my shell is going to search /usr/local/sbin then /usr/local/bin then /usr/sbin and then /usr/bin before searching /sbin and /bin if the command isn't found then it will report that it couldn't find such a command...
# Like so
$ thisprogramdoesntexist
thisprogramdoesntexist: command not found
Now, on Linux at least, there's also a LD_LIBRARY_PATH which the system will use to search for dynamic libraries (greedily), on Windows I think it just uses the PATH. Finally, Java uses a CLASSPATH which is similar (but used to search for classes and JARs).
On Linux one might add an entry to the PATH like so,
$ export PATH="$PATH:/addNewFolder"
While on Windows you might use
set PATH=%PATH%;c:\addNewFolder
Sometimes, you might manipulate your PATH(s) to enable specific functionality, see update-java-alternatives on Ubuntu for an example.
A PATH is a file directory on your computer. If you need to install a programming language, you might need to put it in your system PATH variable. This means that the system looks to these files for different information, IE where the libraries for the code you are using are.
Hope that helped!
Exactly as other said, PATH is a list of folders that is included in the search -other than the current folder- and you can always access straight away. It's one of the Environment Variables.
For example, we have the python folder in C:\Python27. I'm sure you know that to run a python file, we commonly use python script.py.
What happens is that the command line searches for python.exe in your current folder, and if not found, search it in the folders in the path variable.
To read the path, you can, straightforwardly use:
$ PATH
If you're on windows, like i am, an easy way to deal with this is to just use System Properties. Just type it in the start menu, open it, and go to the 'advanced' tab. Click on the Environment Variables, there! You'll see a PATH variable, and you can modify it as you want.
I myself use more than one version of Python, and to deal with this, i appended all the folders to PATH, and changed my python.exe to pythonversion_number.exe. Problem solved! Now, i can run this in the command line:
$ python26 script.py
$ python33 script2.py
Some further reading on this, if you're interested, here's a good question asked
Hope this helps!
The best resource (so far) about PATH information, you can see in this question:
https://superuser.com/questions/284342/what-are-path-and-other-environment-variables-and-how-can-i-set-or-use-them
Stack Overflow is not the best place to search about this, always check the amazing
https://superuser.com/ for this kind of question.
PATH is a symbolic name usually associated to string values separated by a semicolons (where each string part is a directory name). This symbolic name (and its values) is handled by the operating system and could be modified by the end user through the some command line instruction like SET PATH=........ or through some kind of user interface configuration tool.
It is common practice for tools like compilers or other programming tools to look at this symbolic name and use the list of string values for searching files that are not directly available in the current folder used by the tools.
So, if an installation procedure set the PATH symbol in this way
SET PATH=%path%;C:\PROGRAM FILES\MYTOOLFOLDER;
it means, set the PATH symbol to the previous value (%PATH%) and add another string value to it (C:\PROGRAM FILES\MYTOOLFOLDER).
Then the tool, when it needs to search for a particular file or library, could read the PATH symbol values, split them at the semicolons and iteratively look at the directories listed one by one looking for the file required.
In C# programming, for example, the tool code could contain something like this
string pathSymbol = Environment.GetEnvironmentVariable("PATH");
string[] pathFolders = pathSymbol.Split(';');
foreach(string folder in pathFolders)
{
if(File.Exists(Path.Combine(folder, "mylibrary.dll"))
{
..... do whatever you need to do with the file
}
}
This example assumes a Windows environment.

How to get full path to file that "knows" when working in debugger

I have an XML file I'm streaming as an XDocument. I need to be able to get the full path of the file (NOT the bin/Debug path) using reflection or the like (so this will be the path from the User's machine it lives on).
I have tried about a zillion different ways, including:
System.Reflection.Assembly.GetCallingAssembly().Location
System.Reflectin.Assembly.GetEntryAssembly().Location
System.Reflection.GetExecutingAssembly().Location
AppDomain.CurrentDomain.BaseDirectory.
How do I look use System.IO to find the path on the User's machine to my file?? Quite suprised I haven't found the simple answer after googling all day.
::EDIT:: I've now found out that there is no way to "reflectively" locate a path dynamically based on whether the application is running in the debugger or not. My only option is to do some detection.
Thanks in advance!!
I'm assuming that the file is in a child directory of the executable?
You can get the full path of the current working directory (ie where your .exe was run from) by using the Environment class. You can then concatanate this with the child directory
Environment.CurrentDirectory + #"\folder\file.xml"
http://msdn.microsoft.com/en-us/library/system.environment.aspx
Hope this helps!
EDIT: After reading up a little it turns out that CurrentDirectory can be changed rather easily. The accepted answer here Environment.CurrentDirectory is yielding unexpected results when running installed app offers a more reliable method.
Found my answer here (using path stripping and GetFullPath() ). It's a real bummer there's no way around just stripping the bin/debug part of the path. I used the third part of the question linked above.

C#: new file() - where is the root save location?

If i make the call File myFile = new File('myfile.txt'); where is does this get saved to?
It's relative to the process's current directory. What that is will depend on how your application has been started, and what else you've done - for example, some things like the choose file dialog can change the current working directory.
EDIT: If you're after a temporary file, Path.GetTempFileName() is probably what you're after. You can get the temp folder with Path.GetTempPath().
That won't compile.
EDIT: However, if you're after where creating a text file using StreamWriter or File.Create("text.txt"), etc, then I defer to the other answers above; where it will be where the application is running from. Be aware as others mentioned that if you're working out of debug it will be in the debug folder, etc.
NORMALLY it gets saved to the same directory the executable is running in. I've seen exceptions. (I can't remember the specifics, but it threw me for a loop. I seem to recall it being when it's run as a scheduled task, or if it's run from a shortcut.
The only reliable way to know where it is going to save if you are using the code snippet you provided is to check the value of System.Environment.CurrentDirectory. Better yet, explicitly state the path where you want it to save.
Edit - added
I know this is a bit late in modifying this question, but I found a better answer to the problem of ensuring that you always save the file to the correct location, relative to the executable. The accepted answer there is worth up-votes, and is probably relevant to your question.
See here: Should I use AppDomain.CurrentDomain.BaseDirectory or System.Environment.CurrentDirectory?

Categories