Repository: dotnet/roslyn
File: src/Compilers/Shared/NativeMethods.cs (C#)

Code before:
            [In, Out] StringBuilder lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            [In, MarshalAs(UnmanagedType.Bool)]
            bool bInheritHandles,
            uint dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            [In] ref STARTUPINFO lpStartupInfo,
            out PROCESS_INFORMATION lpProcessInformation
        );

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        internal static extern IntPtr GetCommandLine();

#if !NET
        //------------------------------------------------------------------------------
        // ResolveLinkTarget
        //------------------------------------------------------------------------------
        extension(File)
        {
            public static FileSystemInfo? ResolveLinkTarget(string path, bool returnFinalTarget)
            {
                if (!returnFinalTarget) throw new NotSupportedException();

                path = Path.GetFullPath(path);

                using var handle = CreateFileW(
                    lpFileName: path,
                    dwDesiredAccess: FILE_READ_ATTRIBUTES,
                    dwShareMode: FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    lpSecurityAttributes: IntPtr.Zero,
                    dwCreationDisposition: OPEN_EXISTING,
                    dwFlagsAndAttributes: FILE_FLAG_BACKUP_SEMANTICS,
                    hTemplateFile: IntPtr.Zero);

                if (handle.IsInvalid)
                {
                    return null;
                }

                uint flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS;
                uint needed = GetFinalPathNameByHandleW(hFile: handle, lpszFilePath: null, cchFilePath: 0, dwFlags: flags);
                if (needed == 0) return null;

                var sb = new StringBuilder((int)needed + 1);
                uint len = GetFinalPathNameByHandleW(hFile: handle, lpszFilePath: sb, cchFilePath: (uint)sb.Capacity, dwFlags: flags);
                if (len == 0) return null;

                return new FileInfo(TrimWin32ExtendedPrefix(sb.ToString()));
            }

Review comment (suggestion):
Is there a need for this method to work with relative paths?

I guess it's possible for a path coming from the environment (PATH, DOTNET_ROOT etc) to be relative..though that seems really weird, and likely to result in unpredictable behavior. I wonder if that is a condition we should log/throw/complain about, if it ever happens.

Code after:
            [In, Out] StringBuilder lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            [In, MarshalAs(UnmanagedType.Bool)]
            bool bInheritHandles,
            uint dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            [In] ref STARTUPINFO lpStartupInfo,
            out PROCESS_INFORMATION lpProcessInformation
        );

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        internal static extern IntPtr GetCommandLine();

#if !NET
        //------------------------------------------------------------------------------
        // ResolveLinkTarget
        //------------------------------------------------------------------------------
        extension(File)
        {
            public static FileSystemInfo? ResolveLinkTarget(string path, bool returnFinalTarget)
            {
                if (!returnFinalTarget) throw new NotSupportedException();

                using var handle = CreateFileW(
                    lpFileName: path,
                    dwDesiredAccess: FILE_READ_ATTRIBUTES,
                    dwShareMode: FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    lpSecurityAttributes: IntPtr.Zero,
                    dwCreationDisposition: OPEN_EXISTING,
                    dwFlagsAndAttributes: FILE_FLAG_BACKUP_SEMANTICS, // needed for directories
                    hTemplateFile: IntPtr.Zero);

                if (handle.IsInvalid)
                {
                    return null;
                }

                uint flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS;
                uint needed = GetFinalPathNameByHandleW(hFile: handle, lpszFilePath: null, cchFilePath: 0, dwFlags: flags);
                if (needed == 0) return null;

                var sb = new StringBuilder((int)needed + 1);
                uint len = GetFinalPathNameByHandleW(hFile: handle, lpszFilePath: sb, cchFilePath: (uint)sb.Capacity, dwFlags: flags);
                if (len == 0) return null;

                return new FileInfo(TrimWin32ExtendedPrefix(sb.ToString()));
            }
        }