dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.57k stars 4.55k forks source link

Creating symbolic links is broken when paths are virtualized #91044

Open lostmsu opened 10 months ago

lostmsu commented 10 months ago

Description

My app is packaged using DesktopBridge to be published in Store.

The issue is that when I create a symbolic link from withing my app's subfolder of AppData\Local (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MyApp"), it is not functional as it points to non-virtualized location.

Reproduction Steps

This has to be run from a desktop bridge app

bool virtualized = new DesktopBridge.Helpers().IsRunningAsUwp();
Console.WriteLine($"virtualized: {virtualized}");

var localData = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
var appData = new DirectoryInfo(Path.Join(localData.FullName, "SymlinkTest"));
appData.Create();

string original = Path.Join(appData.FullName, "original.txt");
File.WriteAllText(path: original, contents: "42");
var symlink = new FileInfo(Path.Join(appData.FullName, "symlink.txt"));
if (symlink.Exists) {
    symlink.Delete();
}
symlink.CreateAsSymbolicLink(original);
Console.WriteLine(File.ReadAllText(symlink.FullName));
symlink.Delete();

Expected behavior

virtualized: true 42

Actual behavior

virtualized: true System.IO.DirectoryNotFoundException: 'Could not find a part of the path 'C:\Users\MYUSER\AppData\Local\SymlinkTest\symlink.txt'.'

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

ghost commented 10 months ago

Tagging subscribers to this area: @dotnet/area-system-io See info in area-owners.md if you want to be subscribed.

Issue Details
### Description My app is packaged using DesktopBridge to be published in Store. The issue is that when I create a symbolic link from withing my app's subfolder of `AppData\Local` (`Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MyApp"`), it is not functional as it points to non-virtualized location. ### Reproduction Steps This has to be run from a desktop bridge app ```csharp bool virtualized = new DesktopBridge.Helpers().IsRunningAsUwp(); Console.WriteLine($"virtualized: {virtualized}"); var localData = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)); var appData = new DirectoryInfo(Path.Join(localData.FullName, "SymlinkTest")); appData.Create(); string original = Path.Join(appData.FullName, "original.txt"); File.WriteAllText(path: original, contents: "42"); var symlink = new FileInfo(Path.Join(appData.FullName, "symlink.txt")); if (symlink.Exists) { symlink.Delete(); } symlink.CreateAsSymbolicLink(original); Console.WriteLine(File.ReadAllText(symlink.FullName)); symlink.Delete(); ``` ### Expected behavior > virtualized: true > 42 ### Actual behavior > virtualized: true > System.IO.DirectoryNotFoundException: 'Could not find a part of the path 'C:\Users\MYUSER\AppData\Local\SymlinkTest\symlink.txt'.' ### Regression? _No response_ ### Known Workarounds _No response_ ### Configuration _No response_ ### Other information _No response_
Author: lostmsu
Assignees: -
Labels: `area-System.IO`
Milestone: -
adamsitnik commented 10 months ago

@Jozkee could you PTAL?

Jozkee commented 10 months ago

Is CreateAsSymbolicLink silently failing? @lostmsu do you have steps on how to run that code on a Desktop bridge app?

lostmsu commented 10 months ago

silently failing? No, it creates a symlink, but the destination is non-virtualized path, and trying to read the content immediately fails. So does an attempt to remove the symlink.

See the attached project sample.

If it was not clear - Windows only.

Be sure that you run virtualized (e.g. Packaged) variant only. The virtualization shenanigans annoyingly can make the test pass if all the files exist in non-virtualized locations.

SymlinkPackaged.zip

Jozkee commented 10 months ago

No, it creates a symlink, but the destination is non-virtualized path, and trying to read the content immediately fails. So does an attempt to remove the symlink.

I see, yes. I think this may be a problem related to the windows API CreateSymbolicLinkW which doesn't take into account the virtualized context, so we may not be able to fix it.

bansalsushant commented 7 months ago

@lostmsu Which environment are you using for this? We tried to repro this on Win 11 23H2 and we were not able to repro the issue - the sym link worked as expected.