12 ms·
Support Single-File Apps in .NET 5
- moron4hire 6y agoI'm confused. Isn't this already a feature of .NET Core?
- w-j-w 6y agoWhich is on core version 3.1 They are disjoint, with .NET core being billed as the successor to .NET
- janwillemb 6y agoNo, publishing a .NET core project gives you tons of dlls in the publish directory, especially when publishing self-contained.
- Ididntdothis 6y agoThere is a flag that makes it into a single file. But the load time of this exe is very slow. It looks like it just packs all the assemblies together and extracts them during load.
- bmitc 6y agoI just did this for a simple project. I indeed noticed that the startup time was extremely slow. The subsequent run-time was faster though, although still not that fast. So something interesting was going on via a per-terminal session basis.
- efdee 6y agoThat's because the first time you start it, it actually unzips itself to a temporary folder, and then runs from there.
- techntoke 6y agoWhich is why people should use a language that isn't riddled with issues like this. The documentation on compilation and flags is horrible BTW.
- Ididntdothis 6y ago"Which is why people should use a language that isn't riddled with issues like this." You can't pick a language based on one characteristic. Show me a language that doesn't have a long series of stupid issues. Usually you have to pick the lesser evil.
- techntoke 6y agoAny compiled language for Linux really don't have these types of issues. Go, Rust, C, C++, Nim, etc.
- withinboredom 6y ago> Any compiled language for Linux really don't have these types of issues. Go, Rust, C, C++, Nim, etc. They have their own set of issues...
- deleted 6y ago[deleted]
- tybit 6y agoCurrently the single file solution is a zip that unzips into directory with many files. It was a great stop gap solution but not the final thing (hopefully).
- moron4hire 6y agoOkay, didn't realize that was the case. I had used the single-file solution a few times, but mostly just for the convenience of deployment, never really paying attention to any other aspects of it.
- monadic2 6y agoAre the resulting files mutable?
- ripley12 6y agoYes, this is already a thing in .NET Core 3: https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#single-file-executables https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotne... It's not clear to me how the .NET 5 feature is different.
- moron4hire 6y agoI'm guessing the significance is that .NET 5 unifies .NET Framework and .NET Core, and this feature is not available in .NET Framework 4.8.
- tonyedgecombe 6y agoMy understanding is that .Net 5 is a new version of .Net Core and that the .Net framework is dead.
- appleflaxen 6y agoMicrosoft naming has been executed poorly. If you don't have daily familiarity with these tools, they are absolutely inscrutable.
- ak39 6y agoCorrect. This is also double trouble when Microsoft changes the names of the same product for a future release.
- moron4hire 6y agoIf you actually use the tech, it's really not that confusing
- miffy900 6y ago.NET 5 unifies Mono and .NET Core, not .NET Core and Framework. Previously Mono and .NET Core had different base class libraries and machine code generators (Mono using LLVM).
- techntoke 6y agoYes and no. .NET static binary isn't truly static. It has to decompile a folder with the dependencies in order to run.
- at_a_remove 6y agoAbout a decade back I had to write this goofy little custom client-server deal. I hadn't done Visual Basic since 6, but I thought I'd give the client a go in VB.NET, using whatever we had at the time. Aside from feeling like a chimpanzee dropped into the cockpit of a F-22 at the IDE (which kept doing things), the people who wanted the project were fairly annoyed that I couldn't figure out how to smash everything down into a single .exe. I ended up being so annoyed by the experience I wrote the server backend in Python and trying out the Python "compilers" for the next client. When you have something that is going to be scattered across maybe ten or twenty machines tops for a small project, for whatever reason, people just like the .exe and I can't say I blame them.
- bad_user 6y agoI'm confused, how did Python solve your problem?
- at_a_remove 6y agoThe first project was VB.NET client, Python server. Project two was a different problem, and compiled Python client, Python server. I dimly recall using something like "freeze" for Python to generate something with many fewer files. I changed my methodology partially based on my dislike of the IDE that Visual Basic had at the time and partially due to the criticisms of the VB.NET client I had produced.
- kyriakos 6y agoEven small utilities in dot net core are ridiculously big and have tens of dll files. Maybe a proper dependency management is needed so that only what parts of the framework that are actually used are included in the executable.
- giulianob 6y agoTrimming is already supported and they're investing heavily into making it more aggressive. A web app was about 17mb in one of the demos at the conference that I saw. You can get it smaller if you make it more aggressive yourself but you may have to whitelist specific namespaces if it accidentally removes that you're using that it can't detect.
- Ididntdothis 6y agoHow do you make it more aggressive? Are there options in project file?
- throwaway8941 6y agohttps://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#assembly-linking https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotne...
- Ididntdothis 6y agoI think I have tried all the options but could get my app only from 180 to 150MB. It uses WPF. Maybe that’s the problem.
- MarkSweep 6y agoWith the right flags you can get Hello World down to about 2MB of managed assemblies. You will still have about 16 MB of native: https://github.com/AustinWise/IlLinkerExample https://github.com/AustinWise/IlLinkerExample You basically have to directly fiddle with the flags to the IL linker to really get the size down. It's a pain. They are working on designs to make it better: https://github.com/dotnet/designs/pull/123 https://github.com/dotnet/designs/pull/123 I think these changes can make self contained .NET apps compare more favorably to Go apps, at least for larger applications. It would probably take something more like CoreRT to get app size to be competitive with Rust and C.
- rb808 6y agoBTW One thing I've always liked about dotnet is the binary is an executable and you run that not the interpreter/vm process. When you look at list of prcesses running you see your process, not java or python. On windows the dotnet runtime is so ubiquitous I'm a bit surprised this is needed.
- rndgermandude 6y agoIt's not just the runtime, but dependent assemblies too. E.g. I have one app that has 4 aseemblies (the program + 3 internal libraries), 5 more "internal" general assemblies/libraries of mine, and 12 dependencies from nuget, for a grand total of 21 (+ 1 wrapper .exe) files. Now double that number if you want the pdbs (debug/symbol files) too. Without the runtime. Shipping 21 files isn't horrible (I have seen node_modules directories in the hundreds of thousands of files), but shipping one single self-contained .exe would be even nicer. You can kinda use IlMerge (and some hacking) to achieve a similar result, but it can break in subtle ways (especially when you try to debug something) and does not work with netcore as far as I know. And it's not officially supported either.
- rb808 6y agoOK I get it, makes sense.
- AnonC 6y agoWill this make .NET. a contender for Go in places where .NET is used widely and Go is used to develop standalone tools that are easily distributed?
- tybit 6y agoAs a .NET fan this is one less thing for me to tempted by Go for. The other large remaining point is start up time for e.g CLIs and AWS Lambdas. .NET Core has been making great progress there but I think a true native executable will always beat it.
- mdasen 6y agoWhat is truly native is debatable. Go has a runtime too. .NET has some AOT compilation to native code now and it has trimming so that it doesn't include things you don't need. Go will likely continue to have a bit of an advantage for short-running processes, but .NET and Java are both likely to start getting into this space. Micronaut is advertising "startup in tens of milliseconds with GraalVM". Microsoft is working on integrating all the Xamarin/Mono/Framework/Core work into one .NET and there's a lot of great stuff there. CoreRT isn't going to be productized, but it's likely that a lot of the ideas will become part of .NET in the future. We've seen announcements about compile-time code generation which will help .NET avoid reflection in AOT-compiled scenarios. Go is very successful for a reason, but Java and .NET aren't ignoring Go's advantages. I think there was a bit of complacency for a while. Java was the open-source statically-typed platform and C# was the Microsoft one. As new languages like Scala, Kotlin, and Go came on the scene, there was renewed interest in pushing Java forward and as Microsoft pivoted away from a Windows-first-and-only state of mind, there were a lot of areas to push C# into (with help from the Mono/Xamarin folk). AOT compilation is going to be important for things like iOS development and WebAssembly which both look like they're going to be big emphases for Microsoft going forward (they've announced how they're going to unify iOS/Android/Windows/Mac development with .NET 6 and Blazor seems like one of the more exciting WASM attempts). Again, not taking anything away from Go, but I think Java and .NET will both be making strides in startup times and AOT compilation.
- MarkSweep 6y ago
- 2bitencryption 6y agoI'm confused about something -- does this "single-file" contain the full .NET runtime, a-la a Go executable? Or is this single-file just the full set of managed code, packed together, and still requires a runtime to execute?
- deleted 6y ago[deleted]
- computerex 6y agoThey describe 3 ways of "packing" here: https://github.com/dotnet/designs/blob/master/accepted/2020/single-file/design.md https://github.com/dotnet/designs/blob/master/accepted/2020/... In Unix we will have single executables with the runtime bundled inside. This mode is being referred to as "SuperHost". Windows however will have some files left on disk: > Ideally, we should use the SuperHost for self-contained single-file apps on Windows too. However, due to certain limitations in debugging experience and the ability to collect Watson dumps, etc., the CoreCLR libraries are left on disk beside the app.
- mdasen 6y agoYes, it can contain the .NET runtime like a Go executable. You can already (mostly) do this today with .NET Core 3/3.1 (I say "mostly" just because it simply unzips the runtime on first run). I deploy to Linux with everything in a single file and it's been perfect - headache-less deploys. You can read more at https://github.com/dotnet/designs/blob/master/accepted/2020/single-file/design_3_0.md https://github.com/dotnet/designs/blob/master/accepted/2020/... and https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-pu.... I haven't had any problems with it at all. The size is a bit bigger, but I don't really care about that and then I can just run it like anything else without worrying about making sure that the .NET runtime is on my deploy system and kept up to date. You can also use the PublishReadyToRun flag to do AOT compilation so that startup times are faster (https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#readytorun-images https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotne...). It still keeps the IL (intermediate language) around for certain things so the file sizes can be a bit larger, but if startup times are a concern, it's an option.
- polskibus 6y agoThere is a fody plugin that can combine assemblies into one, works also for Net framework: https://github.com/Fody/Costura https://github.com/Fody/Costura
- gfody 6y agothis plugin is obsolete since .net core 3 introduced single-file executables and assembly linking
- netacean 6y agoI just really wish they start investing into true static compilation for .NET. Some serious projects [1] started adopting CoreRT [2], despite Microsoft's neglect for their own runtime. CoreRT seems to really deliver on the single-file fast-startup small-size .NET promise. Getting this project folded into the LTS .NET 6 release should be a priority. The source generators [3] that are coming to .NET 5 easily cover 99% of our Reflection.Emit use cases, so the JIT is going to be more of a legacy burden once .NET 5 comes out. I want Go's small size, fast compile times, fast startup, without Go's bs (explicit error checking, seriously?). Pieces of our software get deployed over a satellite link so yeah, megabytes matter (and that's why I don't even dare to propose using .NET for those parts). Sharing code with the rest of our .NET stack is a PITA though so people are getting itchy to rewrite the rest of our .NET stuff in Go for better sharing (the Reflection.Emit parts would be replaced with "go generate" which is... a source generator). It would be good to get some clarity on the static compilation roadmap in .NET because I like my job, but I also don't want to become a fulltime Go developer. [1] https://github.com/dotnet/corert/issues/7200#issuecomment-624618015 https://github.com/dotnet/corert/issues/7200#issuecomment-62... [2] https://github.com/dotnet/corert https://github.com/dotnet/corert [3] https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/ https://devblogs.microsoft.com/dotnet/introducing-c-source-g...
- jeswin 6y agoCoreRT is definitely the most exciting project in the .Net stable. But there seems to be some people within MS who don't want to go in that direction - mostly for the reason that it won't be compatible with all of the existing code out there. I just wish they'll see that most users would gladly trade some compatibility for smaller size and faster execution.
- akerro 6y agoInteresting to see Java moving fast enough to overtake .Net in some aspects that .Net needs to copy from Java now
- ak39 6y agoBut hasn't .NET been always copying from Java from day 1?
- makach 6y agoI wrote an amalgamation tool once that took all my project files hierarchically together and built one big source file, after compiling it became one EXE file. Made it super easy to move projects to different machines for compilation. on most windows machines where the .net framework is installed you can find a compiler. my motivation for building this tool was to have access to some basic tools in a locked-down enterprise environment ducks
- alkonaut 6y agoSingle exes are nice, but people still don't want to download and run single exes. Once you use an installer or package manager to grab it anyway, doesn't the benefit become smaller? I guess for some scenarios such as deploying webapps etc, it might be very handy to copy ONE file and run it. But for client apps, is there a visible improvement to having 1 exe instead of 1 exe and 5 dlls, which are the same size together?
- pathartl 6y agoI've written a few utilities that have been released to the public. In my eyes the most important aspect of a single executable is simplicity. I personally prefer applications that I can just drag to any folder. I think, even though I don't like the OS as a whole, macOS does a pretty good job at creating a compromise with .app folders. You can keep framework dependencies, embedded resources, etc contained within one area that you can move around easily, but you don't have to package it up in the binary. I see the whole thing as more of an issue of your target demographic and the scale of your application. Things that run as background services would make sense to distribute as an installable package. Larger applications like Office or Visual Studio are much too large to throw in a single executable. Something else though like Acrobat Reader or FileZilla I think would make sense to distribute as a single executable. Most times I just don't want to install anything. I use FTP so seldomly that I'd rather want to just download a portable FTP client than keep something installed or even have to extract a multi-file archive somewhere.