-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Immediate crash when trying to run as a different user #2555
Comments
@DrusTheAxe Are |
Note that I have installed the runtime for the other user too. |
Hmmm. I haven't seen the Run as another user feature before. Let me do some investigation to determine what it's actually doing. As a general rule, you can run an app using WinAppSDK as long as the runtime is installed for that user e.g. the Microsoft.WindowsAppRuntime.1.1 MSIX package is registered for that user. Alternatively, if the package is provisioned then it's made available to all users. At login a list of packages you should have but don't (and have but shouldn't) is built and processed, before you get to the desktop. I doubt Run as another user is performing a full login. If it's just CreateProcessAsUser then results would depend on state of the machine and that user's profile. Will do some digging. |
That's odd. It's been there at least since Windows XP, where it was called Run as..., and probably even before that, but my memory doesn't go that far.
Right. Except it doesn't. Hence this issue.
That's interesting but not the situation here, since I've run the runtime installer from the second user, and when the TS session belongs to the second user the test program runs.
I don't know what that means. A call to Anyway, again, this doesn't really matter here since, again, I have installed the runtime for the second user, being logged on to the console as the second user, so there was no dependency on the provisioned package being auto-installed for the user. |
I have updated the steps to reproduce above in hopes of making the situation more clear. |
Is it relevant that this happens on a terminal session? I can see it crash when trying to run an unpackaged app from a normal desktop session as different user. It also crashes when trying to run as admin which is supposed to work with 1.1 onwards. So what is going on here? |
That's just the term. I never said it was a remote session. In the context of users and programs run by those users there are two things called "a session". One of them is logon sessions, which represent a login for the purposes of permissions (including by a service account, or a login for SMB), are the basis for tokens, are represented by the The other one is Terminal Services sessions which represent a physical connection a console†, local or remote, used by Remote Desktop Services and Fast User Switching. They can be enumerated by the Each token is linked to a specific Terminal Services session, and while the member of the
This term is used throughout Windows. Here, since the processes run under different users, using different logon sessions, but in the same TS session, it was appropriate to qualify the term so as to reduce confusion. "Two processes in different logon session running in the same session" is undoubtedly worse than "two processes in different logon sessions running in the same Terminal Services session." "Normal desktop session" isn't a thing. It's unclear and suggests the question are there abnormal desktop sessions. There's an existing term and I simply used it.
Programming is hard and not everyone is equally qualified or able to do it adequately. † Except in the special case of session 0 since Windows Vista. Vista leverages the security boundary formed by TS session (in the Object Manager etc.) to separate certain system processes from user processes and protect them. That Windows XP gave the first user that logs on to the machine access to the "global namespace" it just odd and that was fixed in Vista. |
In my case on a normal dekstop session, with no terminal services involved, event viewer logs the following error: <EventData>
<Data>Windows App Runtime</Data>
<Data>ERROR 0x80070520: Bootstrapper initialization failed while looking for version 1.1 (MSIX package version >= 1002.543.1943.0)</Data>
</EventData> |
Further investigation shows that adding |
Does this repro with a recent servicing update (1.1.2+)? There were some fixes in 1.1.2 that may be significant here. Is 1.1.2+ registered for the other user? Easiest way to tell is via an admin cmd prompt
and the PackageUserInformation property shows which users have the package registered e.g.
|
As expected, the same crash still happens with:
with the following values:
The package indeed exists: PS C:\> Get-AppxPackage | Where-Object -Property "PackageFullName" -EQ "Microsoft.WinAppRuntime.DDLM.1003.565.600.0-x6_1003.565.600.0_x64__8wekyb3d8bbwe" | Select-Object Name, PackageFamilyName, PackageFullName | fl
Name : Microsoft.WinAppRuntime.DDLM.1003.565.600.0-x6
PackageFamilyName : Microsoft.WinAppRuntime.DDLM.1003.565.600.0-x6_8wekyb3d8bbwe
PackageFullName : Microsoft.WinAppRuntime.DDLM.1003.565.600.0-x6_1003.565.600.0_x64__8wekyb3d8bbwe And has the requested AUMID. (I'll skip dumping the manifest here.) From there the call flow is the following:
I don't see anything that was done in relation to this, which is why it makes sense that except for the version (the AUMID passed to Regarding your previous comment:
I don't know if the fault is with Windows or the Windows App SDK, and without source code access I can't debug it any more than point the stack trace mentioned above, but even if the problem is with Windows such that everything in Windows works under such a login except for |
That'll be Windows. From your info it's pretty clear WinAppSDK provides added functionality, in some cases working around Windows to achieve equivalent ends, but only so much you can work around. Hunting up the activation experts... |
BTW 0x80070520 == ERROR_NO_SUCH_LOGON_SESSION. "A specified logon session does not exist. It may already have been terminated." Comparing notes with the activation experts |
Indeed seems so. The following code fails with the same error when run as a different user (and succeeds as the same user): ...
IApplicationActivationManagerPtr aam{ CLSID_ApplicationActivationManager };
DWORD pid{};
HRESULT hr = aam->ActivateApplication(L"Microsoft.WinDbg_8wekyb3d8bbwe!Microsoft.WinDbg", L"", AO_NOERRORUI | AO_NOSPLASHSCREEN, &pid); (Same happens with But:
Why is it so important to lookup and load the framework using the whole AppX/AAM thing? Edit: |
The core problem is the Deployment stack in Windows doesn't know about unpackaged apps (not until Win11 and the new inbox Dynamic Dependencies API). Thus if you install an unpackaged app and use the bootstrapper to give a process access to the framework's content, and Deployment happens to run and decide "hey, this framework is unused because I only know about static dependencies declared in packaged apps' appxmanifest.xml and I see none needing this framework package so let's remove it". Even though your unpackaged process is running using it. Aaaand BadMojo™. To enable unpackaged apps to use packaged goods we need to make it clear to the Deployment stack for both install-time and run-time. For install-time we need a main package with a declared dependency on the framework package. As long as that main package is installed the framework won't get removed. WinAppSDK's Main + DDLM packages satisfy that. For run-time we need a running process with package identity and its appxmanifest.xml to declare a Lacking this 'helper' DDLM process we'd don't get unpackaged apps reliably using framework packages.
The tradeoffs of MSIX vs redistributables (i.e. SelfContained) are documented but sorry, link eludes my memory at the moment. Servicing, perf and disk footprint are some of the differences. SelfContained has its merits but it's not without its downsides. Neither option (MSIX vs SelfContained) fully supplants the other which is why we support both :-) |
I don't see how that's relevant to unpackaged EXEs loading unpackaged DLLs.
Again, this doesn't answer the question and talks about something comepletely different.
Once again - Self-contained distribution is not what I want. That's why I wrote that. I wrote what I meant and I meant what I wrote. I want unpackaged apps to just load a bunch of DLLs, rather than activate a package. That way it works when they're That's possible today, but with a lot of hackery. Self-contained distribution demonstartes that it's possible, but self-contained distribution requires the bunch of DLLs to be located in the same folder as the EXE. WHICH IS NOT WHAT I WANT. I DON'T WANT TO DISTRIBUTE 60MB OF DLLS WITH MY PROGRAMS. However, if a few calls to I want the Windows App SDK to support it directly, without having to patch all those calls. Whether or not this shared location is system-wide or user-specific I leave as an open question. But regardless of how you answer these questions it is possible for an unpackaged app written using the Windows App SDK to successfully load the Windows App Runtime from a location different than the one in which the EXE is located and without doing any package activation, and then subsequently successfully run. The problem is that is requires patching the Windows App SDK to not require the DLLs be located in the same folder as the EXE. Please remove this requirement. This solves the runas issue. |
You touch on some complex issues. The TL;DR you possibly can achieve what you want in a couple of ways:
Do either of these meet your needs?
Just stating the facts, not trying to sell you SelfContained ;-) You don't need self-contained if you don't want AND you don't need the Bootstrapper with its related plumbing...if you only run on Win11. Alternatively, you may be able to use the Bootstrapper but avoid the issue with 'Run as different user'. Solution #1 is actually quite simple:
Hmmm. That may not be well documented. I'll follow up on that. The limitation is Windows' Dynamic Dependencies APIs require Win11. That's a problem if your app runs on Win10. The alternative (solution #2)...
The limitation is this requires Windows >= 20H1 (it requires Windows' behavior not available on RS5 or 19H1). WinAppSDK's bootstrap solution needs a process running with the identity of a main package that manifests a static dependency on WinAppSDK's framework package. There's a couple of ways to accomplish that:
WinAppSDK 1.0 did #1 but Packaged COM isn't supported1 in elevated processes on older systems (<Win11) so WinAppSDK 1.1 added #2. The decision which to use is made in
The limitations are (a) this requires Windows >= 20H1 and (b) doesn't support elevation if the servicing update isn't present. 1 Well, Packaged COM wasn't supported on <Win11. A Windows servicing update released recently (June?) addressed that. If a downlevel system has that update Packaged COM works for elevated processes. I'll make a separate post regarding the other issues you raised and why this works the way it does. |
It's a little more complicated than that. The problem here is...
It's not. That's why WindowsAppSDKSelfContained=true doesn't involve the Bootstrapper or Dynamic Dependencies, as then WinAppSDK isn't an MSIX package.
Absolutely. Just use the Windows Dynamic Dependencies APIs instead of the Bootstrapper (which under the covers uses WinAppSDK's Dynamic Dependencies APIs). We have 2 implementations of Dynamic Dependencies. Windows' implementation makes changes across Windows to support dynamic dependencies. WinAppSDK's implementation uses Windows in perfectly valid (if uncommon) ways to reliably produce the same net effect, without changes in Windows.
Loading the DLL is the goal. The activation plumbing is an implementation detail, but our options are limited (see previous post) The (long-standing) limitation was unpackaged apps cannot use packaged goods. Not until Dynamic Dependencies came along i.e. Win11. Technically, yes, a process can Servicing is the key. WinAppSDK's Dynamic Dependencies is all about giving unpackaged apps access to packaged goods in reliable ways Windows can understand. The Bootstrapper is just a specialized use of Dynamic Dependencies, to enable dynamic use of WinAppSDK (chicken/egg problem: DynDep API's in the framework package, how do you call it to use the framework package when you can't yet access the framework package... The Bootstrap API!).
The problem is servicing. How do we get the necessary bits distributed, deployed (install, update etc) and reliably managed? That's not as easy as it sounds (well, assuming it even sounds easy :P). MSIX provides a strong solution here. It's just <sic> a matter of balancing the requirements with the technical limitations.
TL;DR because changing previously released versions of Windows (aka 'downlevel') isn't viable, so we trick existing Windows to work the way we need. Deployment only understood 'static' dependenciesThe Deployment stack in Windows knows not to service a package in use. HOW it knows is the key. Deployment determines a package is in use if 1+ running process with package identity has the package in its package graph. For instance, if the calculator app in the Microsoft.WindowsCalculator package has a dependency on VCLibs then when you run the Calculator its package graph is [Calculator, VCLibs]. When running the app's process has a package identity in its process token (e.g. Deployment knows the process' package graph because it computed the package graph when the package was registered for the user. Calculator's
When the Calculator package was registered for the user Deployment resolves this dependency to a specific package (version>=minversion, a compatible ProcessorArchitecture, etc) and saves the resolved package graph. During later Deployment operations Deployment checks resolved static package dependencies to determine if we're being asked to service a package that's in use and if so, don't proceed.2 2It's a little more involved (e.g. if the Notice the word 'static'. The package graph is resolved at install-time based on static manifested dependencies. Deployment had no concept of processes using packages without a static dependency. Until Win11. Win11 taught Windows to understand 'dynamic' dependenciesDynamic Dependencies introduced in Win11 didn't just add some API functions. We also changed Windows - changed the Deployment stack - to know about packages in use dynamically. That's why AddPackageDependency() has no mention of a 'bootstrapping' or helper processes -- we just changed Windows to understand this behavior. That's great -- if you write apps that only work on >=Win11. Lots of developers need to run on older (<Win11) systems. Windows App SDK supports Windows down to RS5. The question is how to accomplish that. Backport Win11's dynamic dependencies?One option is to service Windows. We could have backported Windows' Dynamic Dependencies work to older systems. But that's problematic for multiple reasons including
Make WinAppSDK work in ways Win10 understandsThe alternative is to do things in ways downlevel Windows understands producing equivalent results. And thus, the bootstrapper and helper process. WinAppSDK refers to this as "polyfill" -- leverage Windows functionality where we can, and supplement with our own implementation where necessary. See Version support. Future?This leads to the obvious question, "Why not make WinAppSDK's Dynamic Dependencies use Windows' APIs on Win11 and only do the polyfill on Win10?" That's always been the long-term goal1 we just haven't done it (yet). But this won't help apps on Win10 so we've been focusing on some higher priority work first (e.g. elevation). 1 You may have noticed WinAppSDK's Dynamic Dependencies API is verrrry similar to Win11's, almost as if they were designed that way... ;-) That's not an accident.
Loading the DLL is the goal. The activation plumbing is an implementation detail, but our options are limited. The (long-standing) limitation is unpackaged apps cannot use packaged goods. Not until Dynamic Dependencies came long i.e. Win11. Technically, yes, a process can Servicing is the key. WinAppSDK's Dynamic Dependencies is all about giving unpackaged apps access to packaged goods and doing so reliably in ways Windows can understand (or at least well enough not to break apps). The Bootstrapper is just a specialized (but necessary) use of Dynamic Dependencies to to enable dynamic use of WinAppSDK.
The problem is servicing. How do we get the necessary bits distributed, deployed (install, update etc) and reliably managed? That's not as easy as it sounds (well, assuming it even sounds easy :P). MSIX provides a strong solution here. 'Run as different user' brings some unusual details to the equation. I'm investigating other options but nothing yet. As you may have guessed, navigating Windows behavior to achieve the desired result is a bit tricky. |
@DrusTheAxe, I read your post a few times and I've also read a bunch of other issues and discussion under this project that deal with related problems and I couldn't find an answer to my question. Maybe it's my fault for broadening the issue. So I'll leave this issue for the specific problem of I may later open a separate issue for the broader matter, but before that I'd like to try one more time here, since this issue already exists and there's some history here. I am asking that the Windows App SDK (i.e. the VSIX, NuGet package etc.), without modifying the Windows App Runtime in any way, allow completely unpackaged applications (i.e. not even using sparse packages, just "plain old Win32 applications") to use, without using any "package APIs" or relying on any other OS mechanism that doesn't support the Are you saying this this is impossible or is there any other reason why this feature can't find itself in the next point release of the SDK? |
So to summarize, you're asking for a solution that (1) enables unpackaged apps to use WinAppSDK (2) that's compatible with And constraint #4 is no MSIX -if- MSIX doesn't support BTW are there Windows version constraints on your |
What do you mean by "involve MSIX"?
That's a somewhat complicated question to answer but the short answer is: The slightly longer answer is that our customers have 17 times more Server 2019 instances than Server 2022 instances. Obviously it would be better to also support Server 2016, but that ship has sailed. Assuming we can find a way to live with that (e.g. maintain two versions until pre-2019 goes away, use WASDK only for certain elements that would be offered only starting with 2019 etc.) 2019 is the bare minimum. If 2019 isn't supported that means nothing is. † I think there are advantages to also distributing the runtime in an unpackaged form, but spreading too much here was probably wrong of me. In time I hope to address that in a separate issue or discussion, unless you convince yourself that a non-MSIX runtime is desirable before I get the chance. |
> MSIX - Does Not Support "INSTALL FOR ALL USERS" and by extension "RUN AS ANOTHER USER". >> Since WindowsAppSDK uses MSIX based runtime, you simply can't leverage WindowsAppSDK features for "ALL USERS on the SAME MACHINE" in your Apps until MSIX limitations are fixed in the OS. Simple as that. >>> Any attempt to support "ALL USERS" will essentially result in ditching MSIX in its current form. >>>> See below
No, "Machine Wide Provisioning" does not count as it still registers/installs the app per User basis which is essentially "single user installation". |
Yes, that's what I meant. Thank you for the detailed response.
Very true. The MSIX (framework-dependent) solution is recommended in this case. There are OS limitations in runas+MSIX support causing the problem here. That's the heart of the issue and unfortunately I haven't been able to find a creative workaround. For the OS limitation, please use FeedbackHub to submit your feedback about the issue to get it on the appropriate OS teams' radar. +@mikebattista @MikeHillberg @kanismohammed as FYI
Server is similar to Desktop but can have variances due to release schedules, the underlying codebase/builds used for a release, servicing updates, system definition and configuration, conditional code in Windows binaries themselves (e.g.
Doubtful ;-) Aside from the obvious but surmountable issues (technical and non-technical) the hard nut is servicing. How do you update such a thing -- Distribute how? Apply the update when it's in use? Minimize disk space impact? Among other factors. "Install" something is easy (relatively speaking), it's "Update" that's hard. MSIX solves these issues. Inventing a new solution is a non-trivial undertaking, and an ongoing tax of splintered redundant efforts (there's only so many devs and hours to go around). If MSIX has issues it's likely more sensible (and justifiable :-)) to address them than invent a new redundant divergent solution. |
An omission on my part, since it was obvious to me and I forgot to specify it explicitly: I am not interested in anything that depends, requires or otherwise entails operating system updates. My machine is always updates but my customers' machine aren't necessarily, and it is on their machines I need to run. Their reasons may be poor but that's irrelevant. Judging their decisions on this issue is not what they're paying me for. Again I remind that since it was called "Project Reunion" till this very day the Windows App SDK promised and promises "downlevel support" and "not relying on operating system servicing/updates" (paraphrases). If any bug is resolved with an OS update we're back to UWP. Again, one of the main supposed benefits of WASDK over UWP was supposedly its independence of OS updates.
In principle, generally, that's true. In practice, regarding the specific workaround I tried, I don't believe there's a dependency on workstation-specific behavior, but that's why I was careful and said that I've tested down to 1809 but haven't tested on Server yet. If any when I will get to operationalizing it from the "less than PoC" state it is now I will of course test it on Servers too. |
Describe the bug
App crashes during load when run as a different user than the one to whom the Terminal Services session belongs.
Steps to reproduce the bug
<WindowsPackageType>None</WindowsPackageType>
to the.vcxproj
.<AppxPackage>true</AppxPackage>
to<AppxPackage>false</AppxPackage>
Expected behavior
Program running.
Screenshots
NuGet package version
1.1.0
Packaging type
Unpackaged
Windows version
Windows 11 version 21H2 (22000)
IDE
Visual Studio 2022
The text was updated successfully, but these errors were encountered: