Repository: microsoft/terminal (language: cpp)

Issue:
As of latest preview version (1.13.10336.0), homedir alias (~) no longer recognized.
### Windows Terminal version

1.13.10336.0

### Windows build number

22000.466

### Other Software

_No response_

### Steps to reproduce

Open up Terminal Preview, drop down arrow to start a WSL distro session.

### Expected Behavior

Session would open normally.

### Actual Behavior

[error 2147942667 (0x8007010b) when launching `ubuntu.exe']
Could not access starting directory "~"


Discussion / hints:
This was never supported; the starting directory was simply _ignored_ for profiles like this.

Can you change the commandline from `ubuntu.exe` to `wsl -d Ubuntu` (or whatever the name of your Ubuntu distribution is?)
![terminal_preview_bugreport](https://user-images.githubusercontent.com/123279/152424132-13cadff8-ee60-4deb-92b2-9ef847c6488f.png)

> This was never supported; the starting directory was simply _ignored_ for profiles like this.
> 
> Can you change the commandline from `ubuntu.exe` to `wsl -d Ubuntu` (or whatever the name of your Ubuntu distribution is?)

I didn't specifically _set_ it to that, that I recall. I've only ever messed with those settings to set fonts, and to change the distro name.

Go ahead and close this in favor of the bigger fish to fry. (I saw the localization bug. Thank you for your work on this, man! 🙏🏻)

AUGH! I think I know what's up. That's not gonna be great.

We changed the base WSL profile, and Ubuntu customizes it to set a different EXE. We try to detect which EXE is being launched, because if it's WSL we want to tell it about the special `~` starting directory.

_Hmm._ This needs some thought...

> Go ahead and close this in favor of the bigger fish to fry. (I saw the localization bug. Thank you for your work on this, man! 🙏🏻)

Aw, thanks. :smile:

I'll keep this one open regardless.. it's gonna bite us, especially since this feature/misfeature is in stable.
@zadjii-msft should we `BODGE` in our own check that the starting directory is a literal `~` and .... just clear it? These distro launchers are being fragment-customized on top of their WSL profiles ...
Okay so team discussion:

If the `startingDirectory` is `~`, and the commandline isn't wsl.exe, then drop the user in `%userprofile%`. Do this logic in `ConptyConnection`. 

Fix patch:
diff --git a/src/types/ut_types/UtilsTests.cpp b/src/types/ut_types/UtilsTests.cpp
index e49ee6ef6e1..14b0ffa58b7 100644
--- a/src/types/ut_types/UtilsTests.cpp
+++ b/src/types/ut_types/UtilsTests.cpp
@@ -479,5 +479,29 @@ void UtilsTests::TestMangleWSLPaths()
         VERIFY_ARE_EQUAL(LR"("wsl" --cd "\\wsl.localhost\Ubuntu\home\user" -d Ubuntu)", commandline);
         VERIFY_ARE_EQUAL(L"", path);
     }
+
+    /// Tests for GH #12353
+
+    const auto expectedUserProfilePath = wil::ExpandEnvironmentStringsW<std::wstring>(L"%USERPROFILE%");
+    {
+        auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(wsl -d Ubuntu)", L"~");
+        VERIFY_ARE_EQUAL(LR"("wsl" --cd "~" -d Ubuntu)", commandline);
+        VERIFY_ARE_EQUAL(L"", path);
+    }
+    {
+        auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(wsl ~ -d Ubuntu)", L"~");
+        VERIFY_ARE_EQUAL(LR"(wsl ~ -d Ubuntu)", commandline);
+        VERIFY_ARE_EQUAL(expectedUserProfilePath, path);
+    }
+    {
+        auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(ubuntu ~ -d Ubuntu)", L"~");
+        VERIFY_ARE_EQUAL(LR"(ubuntu ~ -d Ubuntu)", commandline);
+        VERIFY_ARE_EQUAL(expectedUserProfilePath, path);
+    }
+    {
+        auto [commandline, path] = MangleStartingDirectoryForWSL(LR"(powershell.exe)", L"~");
+        VERIFY_ARE_EQUAL(LR"(powershell.exe)", commandline);
+        VERIFY_ARE_EQUAL(expectedUserProfilePath, path);
+    }
 }
 #endif
diff --git a/src/types/utils.cpp b/src/types/utils.cpp
index 45c6b22c9d0..4f8a1fd0974 100644
--- a/src/types/utils.cpp
+++ b/src/types/utils.cpp
@@ -670,8 +670,15 @@ std::tuple<std::wstring, std::wstring> Utils::MangleStartingDirectoryForWSL(std:
         }
     } while (false);
 
+    // GH #12353: `~` is never a valid windows path. We can only accept that as
+    // a startingDirectory when the exe is specifically wsl.exe, because that
+    // can override the real startingDirectory. If the user set the
+    // startingDirectory to ~, but the commandline to something like pwsh.exe,
+    // that won't actually work. In that case, mangle the startingDirectory to
+    // %userprofile%, so it's at least something reasonable.
     return {
         std::wstring{ commandLine },
-        std::wstring{ startingDirectory }
+        startingDirectory == L"~" ? wil::ExpandEnvironmentStringsW<std::wstring>(L"%USERPROFILE%") :
+                                    std::wstring{ startingDirectory }
     };
 }


Test patch: