@@ -27,51 +27,70 @@ const wchar_t *PROGNAME = L"python.exe";
2727#endif
2828#endif
2929
30- static void
31- set_user_base ()
30+ static std::wstring
31+ get_user_base ()
3232{
33- wchar_t envBuffer[2048 ];
3433 try {
3534 const auto appData = winrt::Windows::Storage::ApplicationData::Current ();
3635 if (appData) {
3736 const auto localCache = appData.LocalCacheFolder ();
3837 if (localCache) {
3938 auto path = localCache.Path ();
40- if (!path.empty () &&
41- !wcscpy_s (envBuffer, path.c_str ()) &&
42- !wcscat_s (envBuffer, L" \\ local-packages" )
43- ) {
44- _wputenv_s (L" PYTHONUSERBASE" , envBuffer);
39+ if (!path.empty ()) {
40+ return std::wstring (path) + L" \\ local-packages" ;
4541 }
4642 }
4743 }
4844 } catch (...) {
4945 }
46+ return std::wstring ();
5047}
5148
52- static winrt::hstring
49+ static std::wstring
5350get_package_family ()
5451{
5552 try {
5653 const auto package = winrt::Windows::ApplicationModel::Package::Current ();
5754 if (package) {
5855 const auto id = package.Id ();
59- return id ? id.FamilyName () : winrt::hstring ();
56+ if (id) {
57+ return std::wstring (id.FamilyName ());
58+ }
6059 }
6160 }
6261 catch (...) {
6362 }
6463
65- return winrt::hstring ();
64+ return std::wstring ();
65+ }
66+
67+ static std::wstring
68+ get_package_home ()
69+ {
70+ try {
71+ const auto package = winrt::Windows::ApplicationModel::Package::Current ();
72+ if (package) {
73+ const auto path = package.InstalledLocation ();
74+ if (path) {
75+ return std::wstring (path.Path ());
76+ }
77+ }
78+ }
79+ catch (...) {
80+ }
81+
82+ return std::wstring ();
6683}
6784
6885static int
6986set_process_name ()
7087{
71- std::wstring executable, home;
72-
88+ const auto home = get_package_home ();
7389 const auto family = get_package_family ();
7490
91+ std::wstring executable;
92+
93+ /* If inside a package, use user's symlink name for executable */
7594 if (!family.empty ()) {
7695 PWSTR localAppData;
7796 if (SUCCEEDED (SHGetKnownFolderPath (FOLDERID_LocalAppData, 0 ,
@@ -86,44 +105,40 @@ set_process_name()
86105 }
87106 }
88107
89- home. resize ( MAX_PATH );
90- while ( true ) {
91- DWORD len = GetModuleFileNameW (
92- NULL , home. data (), ( DWORD )home. size ());
93- if ( len == 0 ) {
94- home. clear ( );
95- break ;
96- } else if (len == home. size () &&
97- GetLastError () == ERROR_INSUFFICIENT_BUFFER ) {
98- home. resize (len * 2 );
99- } else {
100- home .resize (len);
101- size_t bslash = home. find_last_of ( L" / \\ " );
102- if (bslash != std::wstring::npos) {
103- home. erase (bslash) ;
108+ /* Only use module filename if we don't have a home */
109+ if (home. empty () && executable. empty () ) {
110+ executable. resize ( MAX_PATH );
111+ while ( true ) {
112+ DWORD len = GetModuleFileNameW (
113+ NULL , executable. data (), ( DWORD )executable. size () );
114+ if (len == 0 ) {
115+ executable. clear ();
116+ break ;
117+ } else if (len == executable. size () &&
118+ GetLastError () == ERROR_INSUFFICIENT_BUFFER ) {
119+ executable .resize (len * 2 );
120+ } else {
121+ executable. resize (len);
122+ break ;
104123 }
105- break ;
106124 }
107125 }
108126
109- if (executable.empty () && !home.empty ()) {
110- executable = home + L" \\ " + PROGNAME ;
111- }
112-
113127 if (!home.empty ()) {
114128 Py_SetPythonHome (home.c_str ());
115129 }
116- if (!executable.empty ()) {
117- const wchar_t *launcherPath = _wgetenv (L" __PYVENV_LAUNCHER__" );
118- if (launcherPath) {
130+
131+ const wchar_t *launcherPath = _wgetenv (L" __PYVENV_LAUNCHER__" );
132+ if (launcherPath) {
133+ if (!executable.empty ()) {
119134 _wputenv_s (L" __PYVENV_BASE_EXECUTABLE__" , executable.c_str ());
120- _Py_SetProgramFullPath (launcherPath);
121- /* bpo-35873: Clear the environment variable to avoid it being
122- * inherited by child processes. */
123- _wputenv_s (L" __PYVENV_LAUNCHER__" , L" " );
124- } else {
125- _Py_SetProgramFullPath (executable.c_str ());
126135 }
136+ _Py_SetProgramFullPath (launcherPath);
137+ /* bpo-35873: Clear the environment variable to avoid it being
138+ * inherited by child processes. */
139+ _wputenv_s (L" __PYVENV_LAUNCHER__" , L" " );
140+ } else if (!executable.empty ()) {
141+ _Py_SetProgramFullPath (executable.c_str ());
127142 }
128143
129144 return 1 ;
@@ -135,9 +150,12 @@ wmain(int argc, wchar_t **argv)
135150 if (!set_process_name ()) {
136151 return 121 ;
137152 }
138- set_user_base ();
153+ const wchar_t *p = _wgetenv (L" PYTHONUSERBASE" );
154+ if (!p || !*p) {
155+ _wputenv_s (L" PYTHONUSERBASE" , get_user_base ().c_str ());
156+ }
139157
140- const wchar_t * p = wcsrchr (argv[0 ], L' \\ ' );
158+ p = wcsrchr (argv[0 ], L' \\ ' );
141159 if (!p) {
142160 p = argv[0 ];
143161 }
0 commit comments