How to get the target folder of a link?

Heiko 1,291 Reputation points
2023-02-12T17:18:12.69+00:00

Within my app I let the user open file system directories in explorer. But if I have e.g. a directory

C:\Users\Heiko\Documents\Eigene Bilder\

C:\Users\Heiko\Documents\My Pictures\

and try to open it via

Process.Start(@"C:\Users\Heiko\Documents\Eigene Bilder");

the explorer opens and displays the message 'Cannot open the folder. Access is forbidden.'. Of course the folder is a link to folder 'C:\Users\Heiko\Pictures' and here I have all rights to do something.

How can I get the target path for such folders? I only need the path for opening it via explorer.

Until now I have the following in C#:

WIN32_FIND_DATA wfd = new WIN32_FIND_DATA();

using (SafeFindHandle fh = FindFirstFile(Path.Combine(path, "*"), wfd))
{
	if (fh.IsInvalid)
		continue;

	do
	{
		if ((wfd.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
		{
			if (wfd.cFileName == "." || wfd.cFileName == "..")
				continue;

			if ((wfd.dwFileAttributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint &&
				(wfd.dwReparseTags == IO_REPARSE_TAG_MOUNT_POINT || wfd.dwReparseTags == IO_REPARSE_TAG_SYMLINK))
			{
				// How to get here the target folder?
			}
		}
		//...
	} while (FindNextFile(fh, wfd));
}
.NET
.NET
Microsoft Technologies based on the .NET software framework.
4,103 questions
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,839 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,748 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,335 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,884 questions
{count} votes

Accepted answer
  1. David Lowndes 4,721 Reputation points
    2023-02-13T13:38:57.7066667+00:00

    Have you had a look at using the GetFinalPathNameByHandle API?

    1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Xiaopo Yang - MSFT 12,726 Reputation points Microsoft External Staff
    2023-02-13T02:45:14.51+00:00

    Hello,

    Welcome to Microsoft Q&A!

    As the answer said, you can use PKEY_Link_TargetParsingPath to retrieve the target path.

    Or you can use CreateFile to open the target file and then retrieve the path name.

    HANDLE h =CreateFile(L"C:\\Users\\SymbolicLink\\To\\MyFolder", GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,NULL);
    

    Thank you.

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. Heiko 1,291 Reputation points
    2023-02-13T12:48:52.9333333+00:00

    Thank you, but If I try to get the directory handle by

    HANDLE hFile = CreateFileW(L"C:\\Users\\Heiko\\Documents\\Eigene Bilder", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);

    I always get 0xFFFFFFFF and last error is 5 (Access denied).

    I figured out, that the following works:

    HANDLE hFile = CreateFileW(L"C:\\Users\\Heiko\\Documents\\Eigene Bilder", 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);

    Then I can get the linked path with GetFinalPathNameByHandleW().

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.