diff --git a/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs b/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs index d0d211801c51..3c44b2598454 100644 --- a/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs +++ b/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs @@ -183,7 +183,12 @@ ProjectRootElement CreateProjectRootElement(ProjectCollection projectCollection) var projectFileFullPath = Path.ChangeExtension(EntryPointFileFullPath, ".csproj"); var projectFileWriter = new StringWriter(); - WriteProjectFile(projectFileWriter, _directives, isVirtualProject: true, targetFilePath: _targetFilePath); + WriteProjectFile( + projectFileWriter, + _directives, + isVirtualProject: true, + targetFilePath: _targetFilePath, + artifactsPath: GetArtifactsPath(EntryPointFileFullPath)); var projectFileText = projectFileWriter.ToString(); using var reader = new StringReader(projectFileText); @@ -192,14 +197,34 @@ ProjectRootElement CreateProjectRootElement(ProjectCollection projectCollection) projectRoot.FullPath = projectFileFullPath; return projectRoot; } + + static string GetArtifactsPath(string entryPointFilePath) + { + // We want a location where permissions are expected to be restricted to the current user. + string directory = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? Path.GetTempPath() + : Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + + // Include entry point file name so the directory name is not completely opaque. + string fileName = Path.GetFileNameWithoutExtension(entryPointFilePath); + string hash = Sha256Hasher.HashWithNormalizedCasing(entryPointFilePath); + string directoryName = $"{fileName}-{hash}"; + + return Path.Join(directory, "dotnet", "runfile", directoryName); + } } public static void WriteProjectFile(TextWriter writer, ImmutableArray directives) { - WriteProjectFile(writer, directives, isVirtualProject: false, targetFilePath: null); + WriteProjectFile(writer, directives, isVirtualProject: false, targetFilePath: null, artifactsPath: null); } - private static void WriteProjectFile(TextWriter writer, ImmutableArray directives, bool isVirtualProject, string? targetFilePath) + private static void WriteProjectFile( + TextWriter writer, + ImmutableArray directives, + bool isVirtualProject, + string? targetFilePath, + string? artifactsPath) { int processedDirectives = 0; @@ -217,9 +242,16 @@ private static void WriteProjectFile(TextWriter writer, ImmutableArray + + false + {EscapeValue(artifactsPath)} + + """);