chocolatey / choco

Chocolatey - the package manager for Windows
https://chocolatey.org
Other
10.34k stars 903 forks source link

Choco - make support for making standalone installer... #2147

Open tapika opened 4 years ago

tapika commented 4 years ago

At the moment choco is written on .net framework - meanwhile it's deprecated framework from Microsoft perspective - Microsoft is targeting to .net core, which is also compatible with other OSes like Linux, Android.

Theoretically it's possible to upgrade .net framework to .net core and get choco to be more portable accross other OS's.

Another thing which could be considered - .net core possesses built-in support for ReadyToRun feature: https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#readytorun-images

Which in theory could be used to compile choco to standalone installer technology.

Most probably this will compete with other install technologies available out there, like msix, etc...

What I have briefly tested by myself - at the moment choco uses AlphaFS, which somehow windows optimized file system API's - suspect that needs to be replaced with .net official API's (maybe for other OS's except windows ?).

Have you considered something like this ?

tapika commented 3 years ago

What I've briefly analyzed - chocolatey is based on couple years old Nuget core - dll which is not developed any further.

Nuget itself has evolved quite heavily since then - API splited into several nuget packages, like NuGet.Commands, NuGet.Packaging, NuGet.Protocol, NuGet.PackageManagement.

ReadyToRun technology does work - but it works only on .net core level, not on .net framework - current chocolatey base.

But readytorun basically is whole .net core's "core" encapsulated and potentially executed in one executable file. Overhead comes to .exe size, which is can be 29 Mb (console "hello world") towards winforms executable 51 (TrimMode=link) -130 Mb (TrimMode=CopyUsed).

chocolatey cross compiled to .net core weights ~92 Mb.(TrimMode=CopyUsed)

So need approximately 29 - 150 Mb to host whole installer (choco.exe + UI).

Downside is required installer size, advantage is that everything is in one self-installing, self-extracting executable.

Btw, self-extracting support could be simply done by placing files as a resource inside .exe file.

tapika commented 3 years ago

More precise estimate: 61 Mb / .net core 3.1 port with more or less all functionalities of choco enabled.

Trimming configuration (full):

  <PropertyGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' ">
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <PublishTrimmed>true</PublishTrimmed>

    <TrimMode>link</TrimMode>
    <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
    <PublishSingleFile>true</PublishSingleFile>
    <!--<TieredCompilationQuickJit>false</TieredCompilationQuickJit>-->
    <TieredCompilation>false</TieredCompilation>

    <TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>
    <DebuggerSupport>false</DebuggerSupport>

    <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
    <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
    <EventSourceSupport>false</EventSourceSupport>
    <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
    <InvariantGlobalization>true</InvariantGlobalization>
    <UseSystemResourceKeys>true</UseSystemResourceKeys>
    <StartupHookSupport>false</StartupHookSupport>
    <CustomResourceTypesSupport>false</CustomResourceTypesSupport>
  </PropertyGroup>

  <Target Name="EnsureAllAssembliesAreLinked" BeforeTargets="PrepareForILLink">
    <ItemGroup>
      <ManagedAssemblyToLink>
        <TrimMode>link</TrimMode>
      </ManagedAssemblyToLink>

      <!-- If anyone wonders where I've took this list - I've started from <TrimMode>copyused</TrimMode> - everything worked ok, then
           switched to <TrimMode>link</TrimMode> - and took full list of assemblies in output directory and removed by half list, until reached problematic point. -->
      <!-- The type initializer for 'System.Runtime.Serialization.Formatters.Binary.Converter' threw an exception. -->
      <TrimmerRootAssembly Include="mscorlib" />
      <!-- Unhandled exception. System.MissingMethodException: No parameterless constructor defined for type 'log4net.Repository.Hierarchy.Hierarchy'. -->
      <TrimmerRootAssembly Include="log4net" />
      <!--log4net:ERROR Exception while reading ConfigurationSettings. Check your .config file is well formed XML.
      System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize
      System.MissingMethodException: No parameterless constructor defined for type 'System.Configuration.ClientConfigurationHost'.-->
      <TrimmerRootAssembly Include="System.Configuration.ConfigurationManager" />
      <!-- Entry point was not found. -->
      <TrimmerRootAssembly Include="System.Private.CoreLib" />
      <!-- Sequence contains no elements -->
      <TrimmerRootAssembly Include="NuGet.Core" />
      <!-- some exception -->
      <TrimmerRootAssembly Include="chocolatey" />
      <!-- The application to execute does not exist: 'C:\Users\%USERNAME%\AppData\Local\Temp\.net\choco\xbxud0jf.iun\choco.dll'. -->
      <TrimmerRootAssembly Include="choco" />
      <!--Error deserializing response of type chocolatey.infrastructure.app.configuration.ConfigFileSettings:
      Parent does not have a default constructor. The default constructor must be explicitly defined.-->
      <TrimmerRootAssembly Include="System.Xml.XmlSerializer" />
      <!--The type initializer for 'System.Data.Services.Client.TypeSystem' threw an exception.-->
      <TrimmerRootAssembly Include="System.Spatial" />
    </ItemGroup>
  </Target>