mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-04-18 05:17:53 -04:00
Make slnx / csproj always use relative paths (#4019)
* Make slnx / csproj always use relative paths --------- Co-authored-by: Kaydax <kaydax@kaydax.xyz>
This commit is contained in:
77
engine/Sandbox.SolutionGenerator/NativeFileSystem.cs
Normal file
77
engine/Sandbox.SolutionGenerator/NativeFileSystem.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Sandbox.SolutionGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// Provides native file system operations with platform-specific implementations.
|
||||
/// </summary>
|
||||
internal static partial class NativeFileSystem
|
||||
{
|
||||
[DllImport( "kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true )]
|
||||
private static extern IntPtr CreateFileW( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile );
|
||||
|
||||
[DllImport( "kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true )]
|
||||
private static extern uint GetFinalPathNameByHandleW( IntPtr hFile, char[] lpszFilePath, uint cchFilePath, uint dwFlags );
|
||||
|
||||
[DllImport( "kernel32.dll", SetLastError = true )]
|
||||
private static extern bool CloseHandle( IntPtr hObject );
|
||||
|
||||
private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
|
||||
private const uint OPEN_EXISTING = 3;
|
||||
private const uint FILE_SHARE_READ = 1;
|
||||
private const uint FILE_SHARE_WRITE = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the canonical path with proper casing for the given path.
|
||||
/// On Windows, this resolves the true filesystem path including correct casing.
|
||||
/// On Linux, this returns the path unchanged since the filesystem is case-sensitive.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to canonicalize.</param>
|
||||
/// <returns>The canonical path, or the original path if canonicalization fails.</returns>
|
||||
internal static string GetCanonicalPath( string path )
|
||||
{
|
||||
if ( string.IsNullOrWhiteSpace( path ) || !Path.IsPathRooted( path ) )
|
||||
return path;
|
||||
|
||||
if ( !OperatingSystem.IsWindows() )
|
||||
return path;
|
||||
|
||||
try
|
||||
{
|
||||
var handle = CreateFileW( path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero );
|
||||
if ( handle == IntPtr.Zero || handle == new IntPtr( -1 ) )
|
||||
return path;
|
||||
|
||||
try
|
||||
{
|
||||
var buffer = new char[512];
|
||||
var len = GetFinalPathNameByHandleW( handle, buffer, (uint)buffer.Length, 0 );
|
||||
if ( len > 0 && len < buffer.Length )
|
||||
{
|
||||
var finalPath = new string( buffer, 0, (int)len );
|
||||
// Remove the \\?\ prefix added by Windows API
|
||||
if ( finalPath.StartsWith( @"\\?\" ) )
|
||||
{
|
||||
finalPath = finalPath.Substring( 4 );
|
||||
}
|
||||
return finalPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseHandle( handle );
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore errors and return original path
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user