clowd / Clowd.Squirrel

Quick and easy installer and automatic updates for cross-platform dotnet applications
427 stars 39 forks source link

Feature Request: Require UAC (Elevation) for setup.exe #163

Closed tjcwilk closed 1 year ago

tjcwilk commented 1 year ago

Hi,

I have a .net 7.0 Application that I am building, and it legitimately needs to run with elevated permissions to function. This is causing me issues with the installer file that squirrel.exe creates. If I run setup.exe elevated, its working fine.

From reading the squirrel.windows github issue trackers, it sounds like this is by design and one of the dev's didn't want to budge on that decision. The intention being that squirrel only support normal user apps running from the AppData folder. However, my app legitimately needs to do this by design.

Would it be possible to request this feature be included in the more modern leaning clows.squirrel version? Perhaps with a --requires-elevation flag when using squirrel.exe to pack the release then embed that in the manifest of the setup.exe binary?

In the mean time, is there a way to edit the setup.exe post build, to require elevation when run?

The error I'm getting is a gnarly setup error popup box when I run setup.exe as non-admin, and it has the following error message.

Setup encountered fatal error: one or more errors occurred
...
The requested operation requires elevation.

Apart from this one issue i'm having, I really love the look of squirrel and thank you for forking the original and keeping it going.

caesay commented 1 year ago

It's currently not supported. Can you explain what legitimate reason your app has for setup.exe needing elevation?

tjcwilk commented 1 year ago

It's currently not supported. Can you explain what legitimate reason your app has for setup.exe needing elevation?

setup.exe itself doesn't need elevation, but when it launches my app after it has run, it needs to run my application elevated. That's the point at which I get the error mention above.

My application needs to regularly create and remove registry entries, and using that API required admin. It also needs to call a number of other windows API's, that also need admin rights.

Basyras commented 1 year ago

As workaround we wrapped squirrel [app]Setup.exe inside our own application [appSetupWrapper].csproj with manifest requiring elevated permissions and AOT enabled (so dotnet runtime is not required and exe size is small). You need to play little bit how you embed the Setup.exe inside your[appSetupWrapper].csproj. This is how we do it in pipeline (nuke build)

  1. build [app].csproj
  2. squirrel csq pack [app].csproj
  3. move [app]Setup.exe to [appSetupWrapper].csproj resources folder (aka update embeded resource source file)
  4. build [appSetupWrapper].csproj
  5. use [appSetupWrapper].exe as setup

[appSetupWrapper].csproj only contains manifest, empty embeded resource (which will be populated during pipeline) and simple Program.cs:

string exeFilePath =
    Extract("<app>Setup", "exe", Resources.<YourEmbedResourceName>);
ExecuteAsAdmin(exeFilePath);
File.Delete(exeFilePath);

static void ExecuteAsAdmin(string fileName)
{
    var proc = new Process();
    proc.StartInfo.FileName = fileName;
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.Verb = "runas";
    //TODO: Run squirrel setup with --silent
    //proc.StartInfo.Arguments
    proc.Start();
    proc.WaitForExit();
}

static string Extract(string friendlyFileName, string fileExtension, byte[] data)
{
    string fileName = $"{Path.GetTempPath()}{friendlyFileName}_{Random.Shared.Next()}.{fileExtension}";
    File.WriteAllBytes(fileName, data);
    return fileName;
}
caesay commented 1 year ago

I don't recommend that any of you run setup.exe as admin. Anything you do that requires administrative privileges to install is going to require those same permissions to uninstall or update - and Squirrel does not support elevation in those other circumstances either. So you'll be leaving behind a bunch of random stuff on people's PC's when they uninstall your app.

Although just to be thorough, I would definitely not recommend wrapping squirrel's Setup.exe with your own. If you're going to ignore advice and do it anyway, why not just use rcedit to just update the manifest of the Setup.exe which ships with Squirrel?

rcedit "path-to-squirrel-tools/Setup.exe" --set-requested-execution-level "requireAdministrator"
Squirrel.exe pack ...

Again, not recommending the above, just pointing out that it's far superior to creating a wrapper.

I do not plan on implementing this properly any time soon, if someone wants to work on a PR I'd consider it but it will not be trivial. Elevated updating needs to be supported, meaning Squirrel updating needs it's own updater UI to inform the user before asking for consent. And this probably needs to happen while the app is not running, because probably the common use-case for this is installing or updating global components which will be locked/immutable while the app is running. So many edge cases to consider and is a huge departure from the original goals of Squirrel.