App Elevation Samples – Part 3

Picture5

If you haven’t read part 1 and part 2 of this series yet, please start there first. I have covered the “hello world” version of a packaged app that requires elevation at launch time and showed how a packaged app can dynamically elevate itself. In this post we’ll get to the fun part: using the ‘allowElevation’ capability from a UWP app to execute code with elevated privileges on Windows 10 desktop with the 1809 update.

TL;DR

I already have the 1809 update and the Windows SDK 17763 (or later) installed. Just show me the code on GitHub …

Sample Code Repo on Github

Step-by-Step Tutorial

1. Create a new Universal Windows App

Make sure you run Windows 10 with the 1809 update and have the Windows SDK 17763 (or later) installed. Now create a new C# Universal Windows application in Visual Studio 2017 (can use any supported programming language as well, e.g. C++, JS, …):

FileNewProject2

Be sure to set both “Minimum” and “Target” version to 17763 or higher as build number 17763 maps to the 1809 update for Windows 10. The ‘allowElevation’ capability we will be using has been introduced in 1809 and is not available in earlier versions of Windows 10.

setVersions

Now we need to add a ‘fullTrustProcess’ desktop extension to our UWP that will contain the code we want to run with elevated privileges. For a complete tutorial on UWP desktop extension read up here on all the details. In this post I will quickly move through the steps of setting up the desktop extension for our new UWP app:

2. Add the desktop extension project

For this example we want the desktop extension process to be headless (i.e. a background process without UI). It can have a UI as well if that’s what you need for your scenario. So let’s add a C# desktop console application (of course this could be C++, VB, etc. as well) and call it “Elevated Extension”:

addConsole2We don’t want a console box to pop up for our elevated background process, so we need to configure this project to run headless. For that go into the project settings and change the Output Type from “Console Application” to “Windows Application” (I know, not very intuitive …)

outputType

5. Packaging everything together

Next we need to add a “Windows Application Packaging Project” (look for it in the “Windows Universal” category). Name it “Package” and make it the startup project,  so your solution setup looks like in the screenshot below. In order to package both the UWP and the desktop code in one app package, add both as Application references to the Packaging project:

addref3

6. Configuring the appx manifest

Now to connect the two projects we need to declare the “fullTrustProcess” desktop extension in the package manifest. For this open the Package.appxmanifest file in the Packaging project (“Package”) in XML editing mode and add the extension within the <Application> node. While we are in this file we are also adding the “appExecutionAlias” extension that we learned about in part 2, as we will need it to launch our extension with elevated privileges. Last but not least, you will also need to add namespace definitions for “uap3” and “desktop” in the root <Package> element per below snippet.

<Package
  ...
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
  IgnorableNamespaces="uap3 desktop ...">
  ...

  <Extensions>

    <desktop:Extension Category="windows.fullTrustProcess"
                       Executable="Elevated Extension\Elevated Extension.exe">
      <desktop:FullTrustProcess>
        <desktop:ParameterGroup GroupId="User" Parameters="/user" />
        <desktop:ParameterGroup GroupId="Admin" Parameters="/admin" />
      </desktop:FullTrustProcess>
    </desktop:Extension>

    <uap3:Extension Category="windows.appExecutionAlias"
                    Executable="Elevated Extension\Elevated Extension.exe"
                    EntryPoint="Windows.FullTrustApplication">
      <uap3:AppExecutionAlias>
        <desktop:ExecutionAlias Alias="ElevatedExtension.exe" />
      </uap3:AppExecutionAlias>
    </uap3:Extension>

  </Extensions> 
  ...
</Package>

Note that the the two parameter groups I am defining for the desktop extension are not mandatory. I am doing it here only for this sample to later demonstrate how we can launch the extension with either user privileges or admin privileges.

7. Adding the launcher code

Now that solution and manifest are set up and configured correctly, we are ready to add the code to launch the extension from the UWP – as either elevated or regular process. First lets add some XAML to MainPage.xaml:

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <Button Content="Run Backgroundprocess as User"
            Click="ButtonUser_Click"
            HorizontalAlignment="Stretch"
            FontSize="32" Margin="3"/>
    <Button Content="Run Backgroundprocess as Admin"
            Click="ButtonAdmin_Click"
            HorizontalAlignment="Stretch"
            FontSize="32" Margin="3"/>
</StackPanel>

Before we can add the code-behind for the button click handlers, we need to add a reference to the UWP desktop extension SDK, because that’s where the FullTrustProcessLauncher API is defined. This API, btw, is not new in the 1809 update. It has been around since the Creators Update (SDK build 14393), but it’s recommended you reference the Desktop extension SDK that matches your target version, i.e. 17763 in our case.

addDeskExte

Next we add the two button click handlers in MainPage.xaml.cs. The key piece is the FullTrustProcessLauncher API. We are passing in the parametergroup to indicate to the extension whether we need to run it as user or with admin privileges. The processing of this parameter is application logic as we will see in the next step. Wrapping this call into an “IsApiContractPresent” is an important practice to ensure our universal app can run without crashing also on non-desktop devices that don’t support the FullTrustProcessLauncher API:

private async void ButtonUser_Click(object sender, RoutedEventArgs e)
{
  if (ApiInformation.IsApiContractPresent(
      "Windows.ApplicationModel.FullTrustAppContract", 1, 0))
  {
    await
      FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("User");
  }
}

private async void ButtonAdmin_Click(object sender, RoutedEventArgs e)
{
  if (ApiInformation.IsApiContractPresent(
      "Windows.ApplicationModel.FullTrustAppContract", 1, 0))
  {
    await
      FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Admin");
  }
}

The final piece of code we need to add now goes into Program.cs of the “Elevated Extension” project. This is the code that handles the “/user” vs “/admin” parameter. If the latter has been specified we want to do the same as in part 2, i.e. relaunch the process as admin using the AppExecutionAlias. In case you are wondering why the strings we are handling here are different from the strings being passed to the launch API (“/user vs “User”), take a look at the ParameterGroup entries we added to the manifest. It maps a friendly name (“User”) to what could be in some case a fairly convoluted long string of parameters (“/user” in our case).

static void Main(string[] args)
{
    if (args.Length > 2)
    {
        if (args[2] == "/admin")
        {
          string aliasPath =
      Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) +
      @"\microsoft\windowsapps\ElevatedExtension.exe";

          ProcessStartInfo info = new ProcessStartInfo();
          info.Verb = "runas";
          info.UseShellExecute = true;
          info.FileName = aliasPath ;
          Process.Start(info);
          return;
        }
    }

    AutoResetEvent areWeDone = new AutoResetEvent(false);
    // do some task, then exit
    areWeDone.WaitOne(10000); 
}

8. Run and test the solution

Now we are ready to run and test our solution, before hitting F5 make sure the “Package” project is set as startup project and you have added the “allowElevation” capability in its appx manifest:

  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="allowElevation" />
  </Capabilities>

When the UWP is up-and-running use the buttons to launch the extension either as user or as admin. Observe the result in TaskManager, remember that the extension has been coded to exit itself after 10sec in this example:

uwpElevated

This concludes my 3-part tutorial about the new ‘allowElevation’ capability. Please leave your feedback and questions as comments and I will do my best to address them in a timely fashion.

Picture0

53 thoughts on “App Elevation Samples – Part 3

  1. Hi Stefan.

    I’ve also been reading your other article on “UWP WITH DESKTOP EXTENSION ”
    https://stefanwick.com/2018/04/06/uwp-with-desktop-extension-part-2/

    I wanted to implement something like scenario 2 so that I can use the launcher program to pass parameters (ip addresses) to netsh and perform ip properties changes to the system. Does that mean i need to self-elevate the launcher program or netsh, or both?

    If it’s just the launcher program that needs elevation, which you have demonstrated in this article, how do i launch netsh after that? Do I start a new netsh process after AutoResetEvent?

    If it’s just the netsh that needs elevation, does that mean at package manifest, I’d set AppExecutionAlias I to point that the full path of netsh?

    Thanks.

    Liked by 1 person

    1. You can’t point directly to netsh (or other EXEs outside your package) in the appx manifest. To solve it you can include a tiny EXE (like my Launcher.exe) as “windows.fullTrustProcess” extension in your UWP package and launch it via FullTrustProcessLauncher. This process will then run outside of the sandbox and you can launch netsh (or any other EXE on your system) from there. To launch it as elevated process follow the steps from the other post.

      Like

  2. Thanks Stefan, got it working now. It didn’t work before because when I was going through part 1 of this sample, I added application manifest for the win32 application, but forgot to remove it when doing self-elevation, as you pointed out in part 2.

    Like

  3. Hi Stefan, I’m also trying to get UWP to receive response from the launched process, which is similar to your other article: https://stefanwick.com/2018/04/16/uwp-with-desktop-extension-part-3/ where AppService connection is used to pass request and response between both sides.

    However the method described in this article pass request (as parameter) through fullTrustProcess instead. So how would we handle sending the response from process back to UWP?

    Like

    1. With elevated processes this is unfortunately more tricky. Would be a worth a blog post of its own. An elevated process can’t connect to a UWP app process, so you would have to use a different communication mechanism. In a simple case you may be able to just do file-based communincation, or you have a non-elevated Win32 process in between your UWP and the elevated process.

      Like

      1. Hi Stephan, Thank you so much for the post. It was really helpful. As you mentioned above, communication between UWP process and launched elevated process is more tricky. I need exactly the same thing for my project. Have you already written a blog on this? If not, do you have any plans to do so?

        Like

      2. Hi Sanjay, I don’t have a blog post on this yet (and not aware of other docs covering it). It’s still a very new feature (technically the 1809 update hasn’t fully been released yet). I have moved on to a different team in Microsoft by now, but I will check with the team to see if there is any guidance documentation coming out for this soon. Thanks for the question/feedback!

        Like

  4. Hello Stefan,

    “I will check with the team to see if there is any guidance documentation coming out for this soon”

    Is there any update on this from the team?

    Like

    1. Nothing concrete to share yet. AppService support for this scenario is being investigated for a future update. For now you’d have to come up with your own way to communicate. Depending on your scenario I guess you could exchange information via files, or put a non-elevated Win32 process in between your elevated process and the UWP to proxy the communication.

      Like

      1. Thanks Stefan for the update! I will be really great if you could update me once AppService way is available in future release. For now I will rely on File based IO.

        Thanks,
        Sanjay

        Like

  5. Hi Stefan,
    Thanks for sharing this post. I have two questions:
    1. With this approach, can we set values in the registry( HKEY_LOCAL_MACHINE).
    2. I currently on windows 10 sdk 14393.0 and I facing issues while running win32 process having administrative privileges. Is upgrading to Windows SDK 17763 only option.
    Thanks

    Like

  6. Thanks Stefan. So with this approach mentioned in this blog ( using Windows SDK 17763), does it allow us write into the registry(HKEY_LOCAL_MACHINE) from the win32 background process.

    Like

      1. Thanks for answering my queries. I’ll explore the steps you have mentioned in the blog
        I might be digressing here, but I didn’t find any way to launch UWP as administrator( I am still going through the documentation). Is there any recommended way that you suggest me. It would be helpful.

        Like

  7. To summarize, In order for UWP to launch an elevated win32, I have follow the steps mentioned in your blog. This would need Windows SDK 17763. We’ll not be able to achieve this on older SDKs like 14393. Please let me know if my understanding is right.

    Thanks again for your time!

    Like

  8. Hi Stefan,

    Similar to what you have explained in the blog above, I have one existing win32 app, which I want to launch with elevated access from UWP app via normal launcher fulltrust process. I am not able to launch this win32 App because it has some dependency on win32 Dlls, If I include all these additional DLLS using static library, then I am able to launch win32 exe in elevated mode. Just to summarize, below are two scenarios:

    CASE 1: (Working case)

    UWP App ==> Launches Fulltrust process ==> launches my win32 exe (having NO DLL dependency) in elevated mode

    CASE 2: (Failure Case)

    UWP App ==> Launches Fulltrust process ==> Fails to launch EXE (having DLL dependency) in elevated mode

    Can you please confirm whether this is a limitation ( or as designed) on Win10 RS5 or I am doing something wrong?

    Thanks,
    Sanjay

    Like

    1. Are those additional DLLs part if the operating system, or part of an app. If the latter you will need to include them in the package, because otherwise the package wouldn’t work when installed on another system. This isn’t specific to elevation. You shouldn’t have to link them statically though.

      Like

  9. Hi Stefan,

    Thanks for the quick reply. These dlls are part of win32 App which needs to run in elevated mode. As there are three versions of dlls (x86, x64 and ARM), can you please suggest how do I do it or provide any pointer/msdn link which explains how to do this.

    I tried to add them in Packaging project along with Applications thinking that visual studio will take care of adding them in the package along with other win32/uwp applications, but VS does not allow us to select/add any projects which do not produce an executable.

    Thanks,
    Sanjay

    Like

  10. Hi Stefan,

    I am not sure at this point of time. It would be great if you could provide some reference on both of the approaches.

    Actually my solution structure is something like below.

    1) UWP App (e.g SampleUWPClientApp)
    2) UWP library (e.g Sample SampleUWPLibrary which is referenced by SampleUWPClientApp)
    3) RunFullTrust Win32 Exe (e.g SampleDesktopExtension, which loads few DLLs dynamically using LoadLibrary). This will be launched from my UWP library (SampleUWPLibrary )
    4) VS UWP Packaging project (e.g Package, Currently this includes 1 and 2 in applications as a reference and 3 as part of manifest desktop extension)

    I am working on developing 2) and 3) whereas 1 and 4 are done by someone else. Is it possible to just share the binaries (e.g Nuget package which includes both UWP dll and win32 Extension along with Win32 DLLS) or some some other mechanism to have it integrated with 1 and 4)

    Thank you so much for all the help and support.

    Thanks,
    Sanjay

    Like

      1. Thank you so much Stefan! This was very helpful information. I was able to load DLLs from my win32 exe. I really appreciate all the help you provided to me.

        Like

  11. Hello Stefan,

    I was going through UWP samples provided by Microsoft in the github and observed that UWP app can also talk to win32 NT service (custom capability) using RPC.

    https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CustomCapability

    Is similar IO approach possible in UWP app with elevated desktop extension? i.e Can I start an RPC server in elevated desktop extension and then send requests from UWP app?

    While browsing through CustomCapability\Service\Server\RpcServer.cpp from the above mentioned link I noticed below comment.
    ——————————-
    //By default, RPC endpoints don’t allow UWAs (AppContainer processes) to connect to them, so we need to set the security on the endpoint to allow access to UWAs with the custom capability.
    ——————————-

    From this I understand that RPC end point will not be accessible from UWP process. Can you please clarify/confirm this? If RPC end point is not accessible from UWP app, then can I request one custom capability from MS and declare that in UWP app manifest and include signed sccd file (having that capability) in the app as well and run RPC server in elevated desktop extension.

    Thanks,
    Sanjay

    Like

    1. It should be possible, though I have never tried it myself (and I am working on a different project now, so I won’t get to trying this in the foreseeable future I am afraid). In fact, you should be able to do RPC with UWP even without special capabilities if you are not concerned about security in your scenario (or for initial testing). The custom capabilities are required in order to do this securely though.

      Like

  12. Hi Stefan, we have a situation where we are packaging a UWP app ,a C# console app , and a Windows NT service using Packaging project with AppElevaion and Desktop Extension and FullTrust capability etc support . The UWP app talks to the Windows NT service using custom capability. We are able to pack the Windows NT services in the packaging project ,build the packaging project and install it. and When the packaging project starts, it launches the UWP app which starts the C# console app. The C# console app installs the Windows NT service. The service is installed successfully using the UWP app. But when the App tries to talk to the service , the RPC communication fails. We receive the error that “RPC server is unavailable”. Since the UWP app is part of the packaging project, is there anything else to be done specifically in order for the app to reach the service across the custom capability? If we remove the packaging project, the UWP app is able to talk to the service. But in our case, we need the packaging project since we need to pack the Windows NT service along with the UWP app. Could you please help resolve this issue with the UWP app not able to make RPC connection from within the package?

    Like

  13. Thank you Stefan for the reply. The UWP app is already using custom capability. For the packaging project, do we need a new custom capability and new sccd file?

    Like

    1. Once you use a packaging project for your UWP, you will need to make all appxmanifest changes in the packaging project’s manifest. This is true in general, not only for custom capabilities. The manifest file in your UWP is actually irrelevant as it doesn’t get deployed when your app is installed.

      Like

  14. Thank you Stefan for your reply. Since the custom capability is already declared for the UWP app, do we need a new custom capability/ SCCD for the packaging project ,if we are to omit he custom capability for the UWP app? Can we reuse the UWP app’s custom capability for the packaging project? O do we need to request new custom capability/SCCD file?

    Like

    1. If you make the identity of the packaging project the same as the one you had for the UWP project you should be able to re-use the custom capablity. Full disclaimer: I am not an expert on custom capabilities, and I no longer work on the Windows team (working on Azure-IoT now).

      Like

  15. Hello Stefan,

    Your sample app (https://github.com/StefanWickDev/AllowElevation-Samples/tree/master/Elevated%20Extension%20UWP) is works fine in Windows RS5 and 19H1 but it is NOT working in 20H1 preview builds (18941 and 18936). When I look into event viewer I see some .NET exception.
    +++++++++++++++++++++++++++++
    Exception Info: System.ComponentModel.Win32Exception
    at System.Diagnostics.Process.StartWithShellExecuteEx(System.Diagnostics.ProcessStartInfo)
    at System.Diagnostics.Process.Start()
    at System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo)
    at Elevated_Extension.Program.Main(System.String[])
    ++++++++++++++++++++++++++++

    If I replace “Elevated Extension” exe with win32 C++ project (to bypass .NET exception) then I am getting “The request is not supported ” error popup (in build 18941 and 18936) while trying to elevate the extension (bay calling ExecuteShellEx API with C++ code). This extension is getting elevated SUCCESSFULLY in RS5 and 19H1.

    Can you please confirm whether it is a bug in 20H1 preview builds or an intentional change (change in strategy) to withdraw allowElevation support for future Win10 releases?

    Thanks,
    Sanjay

    Like

  16. Hi Stefan,
    One question…the app always is elevated even when the user presses NO in the UAC prompt. Is there a anyway we can prevent this? ie. the extension should not be launched or the operation should be cancelled wen pressing NO.

    Like

  17. Thanks Stefan.
    On button click in UWP app, the extension is launched. When the extension is launched, when the UAC prompt is displayed, press No button. In this case the extension should not be run again with the ProcessStartInfo etc. What we get is, if we add an exception handler in Main() , then exception message says “user cancelled” if we press No. My question is can we get which button was pressed or cancelled state,other than via an exception.

    Like

  18. Hi, Stefan. Thanks for this series: it has been really useful in helping me to get some of my projects working. But I have some questions, if I may:

    Firstly: on the need for the AppExecutionAlias. I have found that it’s OK for a running instance to start a copy of itself (or an instance of a different executable) from within its own directory. I have found no difference whether I start from the current execution directory, or whether I start from the LocalApplicationData directory as you did. Can you clarify please why the alias is necessary, please?

    Second (related to the above): I note that you pass a parameter to the first (non-elevated) instance of ElevatedExtension, and then use the /admin parameter to start the new, elevated instance. So far, so good. But I tried to pass a payload into the elevated instance on another parameter (just a meaningless string, for now: /helloElevatedInstance), and I found that the parameter was sent correctly when executing from the current execution directory, but that it got stripped away when executing through the alias. I think that’s because the alias is designed to start UWP apps, and UWP apps pass their parameters through the Activate interface (which, of course, the console app doesn’t have. Have I guessed correctly? If so, is there any way to persuade the alias to propagate the parameters onto the command line?

    Third: When I install and run the package on a machine inside an admin user’s account, everything works fine. I can also install and run the package on the same machine on a user user’s account, and it works fine. But when I install only into the user user’s account, but not the admin’s account, Process.Start fails with a “File not found” error after it’s completed UAC. This is true whether I use the alias or whether I use the current execution directory. In fact, I can enable and disable the user’s installation by installing and de-installing the admin’s installation, without any other changes to the user’s installation, and this is repeatable across a range of different Windows’. (See also, my question at https://stackoverflow.com/questions/58845877/problem-accessing-native-executable-resources-in-uwp-package-in-user-installatio). I thought that UWP was designed such that this kind of leakage was not possible. Can you help me understand what’s going on, please?

    Thanks very much in anticipation.

    Like

    1. Hi Jules, thanks for your questions!

      First, let me say that I have left the Windows organization back in June 2018 and I have been working in Azure since then. So my knowledge on these topics might be slightly outdated. I am committed to supporting the content on my blog, but I won’t be able to provide product support or provide insights on current roadmaps etc. With that out of the way, let me attempt to answer your questions:

      1) At the time I wrote the sample (on a preview of build 1809) using the AppExecutionAlias was required to make this scenario work. Also it’s convenient since you don’t need to make assumptions about the location of the EXE. Even if it works now on current builds without using the alias, I would say it’s recommended to use it.

      2) This is (valid) feedback for the FullTrustProcessLauncher API. Currently, it does not take arbitrary parameters – it only takes the name of a “parameter group”, which is defined in the appxmanifest file. This can contain any string you like, but you need to declare (read: hardcode) it in advance in the manifest. To workaround this limitation you can use LocalSettings in AppData to pass arbitrary parameters to the process. I have explained that workaround here: https://stefanwick.com/2018/04/06/uwp-with-desktop-extension-part-2/

      3) I believe this behavior is currently by design, though I’d agree to the experience is definitely not ideal. When you install an app that declares ‘allowElevation’ as a non-admin user, that user won’t be able to execute the part of the app that requires elevation. This is because when prompted to elevated they’d need to provide credentials for a different (admin) user, who may not have the app installed. There is definitely room for improvement here (but not something I can comment on). For now, given that ‘allowElevation’ is an enterprise-only feature, I think the enterprise needs to ensure those will be installed in a context that will enable the user to be successful (e.g. don’t let non-admin users install the app in the first place).

      Hope this helps.

      Like

      1. Hi, Stefan,

        Thanks for your quick reply. Appreciate you’re not part of the team any more, but you’re still wanting to help.

        Re point 1: I’m afraid I’m still a little confused. My context is that I already have a full-trust process running; now I want to elevate it. Presumably the process knows its own execution directory. What further assumptions does it need to make to create the elevated copy?

        Re point 2: I think you misunderstand. I understand the necessity for the parameter group when starting the full-trust process from the UWP process. But once the full-trust process has started, it no longer has access to the parameter group. Nevertheless, it appears that there is no other way to pass parameters from the un-elevated full-trust process to the elevated copy. Does this fit with your experience?

        Re point 3: You said several things here which are new to me: “behavior is currently by design”, “‘allowElevation’ is an enterprise-only feature”. Is this documented anywhere official? You said “[non-admins would] need to provide credentials for a different (admin) user”, but that’s true anyway – that’s the UAC prompt! I understand that you’re no longer part of this team: would you be able to put me in touch with somebody who is, please?

        Thanks once again for your help. I do appreciate it.

        Like

      2. Re #1: I looked through my email notes from way back and found conversations about the need for appExecutionAlias in this scenario. The gist is that is was needed at the time to workaround a limitation in the OS. It’s possible this limitation has been removed in current versions of Win10. If you go without the alias I strongly recommend you also test it on a machine running build 1809 to make sure it works there, too. Unless you only target the build you are currently testing with.

        Re #2: When you launch a process from an (unelevated) fulltrust process you can specify arbitrary parameters using Process.StartInfo. In my sample I am not passing on the parameter to the elevated process as I use the existence of the parameter to differentiate whether the code was launched from the UWP vs re-launched as elevated process. That’s just a choice I make in the sample code, you can change that in your code as needed.

        Re #3: what I mean is that an app that uses ‘allowElevation’ isn’t suitable for Microsoft Store distribution (at least that was the policy at the time I was working on it). You would distribute it through your own channels, such as enterprise app distribution, where you control who can install the app vs any arbitrary Windows 10 user. What is the scenario for your app? How do you intend to distribute it?

        Like

  19. Hi, Stefan,
    Re #1: Thanks for the clarification. That makes sense to me. I’ll be sure to check on 1809 – thanks for the heads-up 🙂
    Re #2: What I’m trying to do is: if my full-trust process determines it needs elevated rights it elevates itself (that is, starts a copy of itself elevated) using the same parameters it was originally started with. I’m using Process.Start (much the way you illustrated here) to do that. When I launch the elevated version from the natural (installation) directory, it passes the parameters on correctly. But when I launch the elevated version from the aliased, windowsapps directory, something in the alias resolution mechanism strips off the parameters, and the program starts without any parameters passed-in. It’s something to do with the alias resolution mechanism. I suspect it’s because the way parameters are passed to a UWP app is different to the way they’re passed to a console app or a windows-native app, and aliasing is designed for making UWP apps launchable from cmd/powershell. What you and I are doing is the opposite way round, and I wondered whether there was some way of running the alias machinery without the parameter re-formatting.
    Re #3: I’m limited by confidentiality as to how much I can say here. What I can say is: this is a legacy app, written in C++, and comprising quite a lot of privileged functionality: it installs services, opens firewalls, all kinds of things! We want to package it into a store app, partly because the very sensitive nature of what it does means that the store will give us additional protection against counterfeit malware. We also want to be able to install this on W10s machines. For other reasons (not worth going into here), this is not suitable for simple desktop-bridge.
    The point I’ve reached is: Everything is working safely and correctly, and a version is now in the store and working well, except in the one case where a user has installed it but no admin has. In that case, it gets through UAC and then fails. Thing is: at this point I have no way of predicting whether it’s going to fail: UAC completes successfully, and the user’s installation can’t query whether an admin has installed it. I’ve not found any change in ACL or rights that the admin’s installation effects which would indicate that a failure is going to happen.
    That’s why I’m surprised by your view that this behaviour is by-design. If it were by-design, I would have expected it not to try UAC, or to have issued a warning during installation. What I’m seeking now is: is there a workaround for this, should this be reported as a bug (and if so, to whom), or is there some way to notate in the store that it should only be installed to admin accounts?
    Thanks, as always, for your continued help. It is very much appreciated.
    Jules.

    Like

    1. Re #2: using parameters with appExecutionAlias is expected to work, and it seems to work for me in the general case. If it doesn’t work in your specific scenario there may be a bug somewhere. I’d suggest you create a simplified repro project that demonstrates the bug and report it through an official channel. Using FeedbackHub and/or posting it as question on Stackoverflow are good options for that. On SO be sure to tag your question with ‘UWP’ and ‘desktop-bridge’ so the team will pick it up.

      Re #3: I am a bit surprised to hear your app is approved for Store distribution, but maybe the policies have changed in recent times. It’s problematic because a non-admin user can successfully install (and pay for) your app, but then won’t be able to run it. This by itself is by design – we can’t allow a non-admin user to run elevated code. I would completely agree that the experience around it needs improvement, for example the app should be able to determine in advance whether or not the elevation attempt can succeed. I don’t know if work for this is being done or is on the roadmap. Given that your app seems to be already in the Store, the best next step here might be to open a ticket with the Store and get support this way, as your app as it stands isn’t shippable to the general public.

      Hope this helps.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s