dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.1k stars 4.7k forks source link

Need a "web" installer for desktop app bundling #3379

Open rickbrew opened 5 years ago

rickbrew commented 5 years ago

I'm in the early stages of researching and planning for migrating Paint.NET (https://www.getpaint.net/) from .NET Framework 4.7 to .NET Core 3. I noticed that Core does not have a "web installer" -- that is, a small stub installer (~1.4MB for .NET Framework 4.7.2) that downloads the rest of what's needed on-demand from Microsoft's servers.

This is important for Paint.NET for several reasons. I need to be able to continue providing a "small" download package (currently 7.5MB) that won't greatly increase the bandwidth demands on my servers, and that will skip the .NET Core download when it's already installed on the system. This is also a big win for my users, many of whom do not yet have gigabit Internet ;)

Without this solution, the Paint.NET package would balloon in size by at least 30MB! And this doesn't yet take into account the additional size that WinForms and WPF will add to the package.

IIRC, the old releases of the .NET Framework "Client Profile" installer (3.5 SP1, right?) had instructions for how to modify the installer in order to download additional dependencies like the Visual C++ runtimes. I realize time and resources are always in short supply, so even instructions on how to modify the existing .NET Framework installer to instead pull down .NET Core would be immensely helpful. (other solutions and advice are welcome, too)

I'm not too worried about this for the Microsoft Store release of Paint.NET, but it's critical for the "Classic" desktop version.

rickbrew commented 5 years ago

btw, I do expect the Paint.NET download size to increase during the migration from Framework to Core. Going from 7.5MB to even ~15MB would be alright, but 40+ would be a problem.

rakeshsinghranchi commented 5 years ago

cc @vivmishra @leecow @dleeapho

dleeapho commented 5 years ago

@rickbrew thanks for surfacing a concrete scenario for a web installer for .NET Core deployment on the desktop. I'm assuming you are considering a framework-dependent deployment for Paint.NET, but have you considered a self-contained deployment? In particular the trimming you are looking for might be achieved through IL Linker.

rickbrew commented 5 years ago

@dleeapho Yes, FDD is what I'm going for. However, Paint.NET supports plugins and they will need access to portions of the framework that I can't really predict, so I can't just link-and-trim.

For the Windows Store release, SCD may be the way to go, but I haven't gotten that far in my research yet.

rickbrew commented 3 years ago

I'm currently working on the .NET Core port of Paint.NET, and this is still a major issue for me. Ballooning my download from 12MB to 50MB or 100MB is a difficult cost to swallow. The Store release can be self-contained, that's fine. But the "classic" (installer exe and MSI) needs to be as small as possible. My current prototype results in a ~50MB 7-zip file at maximum compression, and that's just for the x64 build. My download always contains all architectures (currently x86 and x64, but hoping to add arm64) to keep things as simple as possible for end-users (it really does reduce friction and customer support e-mails!).

It's frustrating because .NET Framework always had a nice small (~2MB) web installer, but Core does not. Surely the Framework one can be repurposed? I even remember the 3.5 Client Profile web installer had instructions on how to add additional dependencies by editing a bunch of XML, although it's dependent on having stable download URLs for the packages. I couldn't figure out how to repurpose the latest .NET Framework web installer to do the same.

Even a script that illustrated how to find, download, and execute the .NET Core installer would be extremely helpful. I could refactor that into my own web/stub installer written in C++ or C# (based on whichever version of .NET is available on my lowest supported OS).

dleeapho commented 3 years ago

/cc @NikolaMilosavljevic

jamshedd commented 3 years ago

@rickbrew, we don't have a bootstrapper like the .NET Framework one we can offer for .NET Core at this time unfortunately. You may want to take a look at our dotnet-install scripts:

https://dot.net/v1/dotnet-install.ps1 https://dot.net/v1/dotnet-install.sh.

The install script downloads the latest runtime from a well known location and copies them over to a specified folder. So it would give you something similar to an SCD deployment of .NET Core, but without your app carrying the payload yourself and bloating app size.

MichaelSimons commented 3 years ago

[Triage] Assigning to @NikolaMilosavljevic to research and create a proof of concept on how required components can be detected and installed.

rickbrew commented 3 years ago

@rickbrew, we don't have a bootstrapper like the .NET Framework one we can offer for .NET Core at this time unfortunately. You may want to take a look at our dotnet-install scripts:

These are documented as being intended for scenarios like CI, and download what's necessary for a self-contained deployment. I wasn't able to figure out how to get them to grab the end-user installer EXE.

From https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script :

Description The dotnet-install scripts perform a non-admin installation of the .NET SDK, which includes the .NET CLI and the shared runtime.

(it can also install the runtime w/o the SDK, AFAICT)

I need the full installer that runs w/ admin privileges.

jamshedd commented 3 years ago

@rickbrew , you asked for a pointer/example so I was using these install scripts as an example that illustrates detection, download and deployment of .NET packages to influence your own scripts or installer to do something similar.

rickbrew commented 3 years ago

Yeah, true, thanks :) Unfortunately I think my needs are just slightly off-angle from what dotnet-install is meant to do. Maybe the installer EXEs are right there in the same directory (on the server) as the ZIPs that dotnet-install downloads, but I'm wary of depending on that w/o some official documentation granting me the blessing to do that.

Misiu commented 2 years ago

Something like https://github.com/Tyrrrz/DotnetRuntimeBootstrapper would be an awesome solution! @rickbrew how did you solve this issue?

rickbrew commented 2 years ago

@Misiu I no longer need this because I wrote my own bootstrapper/downloader. It was a huge amount of work.

https://mobile.twitter.com/rickbrewpdn/status/1408597059930771460

I was thinking of open sourcing it once I get some time, maybe after my 4.3.3 release that migrates to .NET 6, which is already in alpha testing. https://forums.getpaint.net/topic/118900-paintnet-433-alpha-build-7988/

Misiu commented 2 years ago

@rickbrew I don't want to spam this thread, but why did you create your own solution instead of using the one I linked? Open-sourcing it would be awesome! I'm in process of creating a Winforms app that I'd like to deploy as an "easy to run" app. Please let us know when it will be released šŸ¤žšŸ¤žšŸ¤ž

rickbrew commented 2 years ago

@Misiu , I already knew about @Tyrrrz 's bootstrapper (I even helped him with a few things, and vice versa) and it covers a different type of deployment scenario. His is for wrapping an EXE so it can be launched directly, mine is meant to be part of the setup process for a whole application.

Misiu commented 2 years ago

@rickbrew that's my use case :) I have an exe that is a windows service and a second exe that is a setup utility. It creates registry entries, configuration files. The part that is missing is the runtime setup. I can't use any installed software because I need to be able to run (and install) a couple of instances per machine. Something like an on-premise GitHub action runner.

rickbrew commented 2 years ago

@Misiu You could also think about using self-contained deployment. Makes all this a whole lot easier, unless you're targeting Win7/Win8.1, in which case there are still some prereqs that .NET needs installed. https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net60

Misiu commented 2 years ago

@rickbrew ideally I'd like to create a package as small as possible, that will be capable of downloading everything it needs. My app must run mostly on Windows servers + Windows 8.1 up. Currently each time it is deployed the user must install all the dependencies by hand. For now, I'll use https://github.com/Tyrrrz/DotnetRuntimeBootstrapper, but ideally, this should be handled by "the installer".

Misiu commented 2 years ago

@rickbrew any updates on open-sourcing "the installer"? I have a use case: my project has 3 parts, two Winforms apps, and a windows service hosting REST endpoints. Bootstrapper works great for two Winforms apps, but it doesn't work with windows service (it should install ASP.NET Core 5.0 Runtime). I don't mind adding another project that will install all requirements, set up my service, and add requirement permissions to folders. If you need testers, count me in :)