Runtime: Aplicativo de console independente exe único

Criado em 3 nov. 2016  ·  98Comentários  ·  Fonte: dotnet/runtime

Publicar um aplicativo de console autocontido em .net core, conforme descrito aqui, resulta em um diretório com muitos arquivos, mesmo um com "área de cobertura menor".

É possível agrupar todas as dependências para obter um único executável? Um grande myapp.exe ao direcionar o Windows, por exemplo.

Suponho que estou procurando algo semelhante a ILMerge, mas para o núcleo .net. É possível por algum sinalizador de opção em dotnet publish ou algum outro comando? Se não, considere como um pedido de recurso. Obrigado.

area-Meta question

Comentários muito úteis

Isso é horrível. Eu me pergunto por que isso foi aprovado durante o processo de design, quero distribuir seu aplicativo para um de seus clientes, então boa sorte para ele encontrar o que abrir:
image

Isso é simplesmente feio e uma bagunça completa

tempo de execução/
MyProgram.exe
MyLib.dll

Esta teria sido uma ideia muito melhor

Até o Java lida melhor com isso:
explorer_2018-04-21_16-42-33

Todos 98 comentários

Este cenário não é compatível no momento. Fique de olho no https://github.com/dotnet/corert repo para ver o trabalho que o levará a esse caminho.

A CoreRT é o lugar certo para buscar essa solução.

Obrigado. Parece que o CoreRT é exatamente o que eu estava procurando.

Para outros que podem tropeçar nisso, leia aqui

Eu quero especificamente esse recurso sem compilação antecipada. Eu não quero corert– Eu quero o mesmo jit e depuração e experiência de tempo de execução que um aplicativo autocontido normal– mas também não quero distribuir quatro arquivos por utilitário. Isso é inconveniente para quem quiser usar o utilitário. Eu só quero embalado e executado a partir de um único exe. Isso está me fazendo escolher o .NET Framework em vez do .NET Core para muitos utilitários.

.NET Framework está "trapaceando", pois você já tem muitos arquivos presentes no sistema operacional.
Você pode conseguir o mesmo com o .NET Core, instalando o .NET Core compartilhado em toda a máquina, se desejar.

Refatorar CoreCLR para mesclar todos os seus arquivos em um (incl. Nativo + gerenciado) não é um trabalho trivial e não acho que o cenário seja tão interessante para muitos clientes.

A diferença é que toda máquina Windows tem a garantia de ter .NET Framework, mas não .NET Core, então, a menos que haja um motivo especial que valha a pena tornar a implantação mais complexa, acho que vou acabar ficando lá.
Eu acho que os clientes normalmente não escrevem utilitários exe único. Talvez um dia. :-)

a menos que haja um motivo especial que valha a pena tornar a implantação mais complexa

Existem MUITOS motivos para preferir o .NET Core ao .NET Framework. Desempenho, modularidade, facilidade de manutenção, isolamento, etc. E isso é ignorar o cross-platform-ness.

Ter um único utilitário exe é principalmente uma preocupação estética. Não há diferença funcional real (para todos os envolvidos) se o executável é um único arquivo ou uma única pasta com um punhado de arquivos.

@mellinoe Oh, concordo com projetos em geral, isso é verdade. Nos pequenos utilitários onde esse cosmético é desejável, o .NET Framework já fez um trabalho bom o suficiente. Concordo que é cosmético no mesmo sentido que ser capaz de especificar uma empresa de montagem e uma mensagem de copyright. Mas ser uma coisa cosmética não me faz gostar menos. Obviamente, não é uma prioridade aqui, isso é perfeitamente compreensível.

Possivelmente relacionado: https://github.com/dotnet/core/issues/600

Não é principalmente cosmético. Imagine que eu queira distribuir um aplicativo que tem vários componentes embutidos, como por exemplo Idsrv4 ou RavenDb + meu próprio material. Eles dependem dos bits principais do aspnet. Tudo isso funciona bem, desde que eles dependam da mesma versão do núcleo aspnet. Assim que um deles avançar para a próxima versão, provavelmente não funcionará mais. Se o OTOH eu conseguisse ilmergir cada componente em um único .dll, o problema desapareceria.

Uma coisa a ter em mente é que existem mais problemas técnicos do que apenas o ILMerge não funcionar. O tempo de execução em si é basicamente dividido em muitos arquivos e também há arquivos auxiliares como o host CLR, o arquivo de texto de dependências de tempo de execução e muito mais. A única razão pela qual um executável de arquivo único funcionou no passado é porque o .NET Framework, uma instalação global do sistema, era confiável. Comparar os dois cenários é um pouco injusto, porque o .NET Framework não tem realmente uma opção "independente".

Tudo isso funciona bem, desde que eles dependam da mesma versão do núcleo aspnet. Assim que um deles avançar para a próxima versão, provavelmente não funcionará mais.

Isso não é verdade. Você pode publicar vários aplicativos diferentes em versões de tempo de execução diferentes e, em seguida, agrupá-los no mesmo "uber-app". Você simplesmente não pode misturar suas dependências em uma única pasta. Mesmo se você usar a opção de publicação dependente da estrutura, ainda poderá misturar e combinar versões. Eu entendo que isso é menos conveniente do que ter literalmente um único arquivo e pode impedir coisas como incorporar um exe como um recurso no PE. Não tenho certeza se é a isso que você está se referindo, já que provavelmente ainda precisaria extrair o arquivo para executá-lo, o que ainda poderia ser feito com um diretório.

Não quis dizer versão runtime, sei que não vai funcionar. O que quero dizer é o que acontece no meu cenário quando cada componente assume uma dependência em [email protected]. O componente a é atualizado para [email protected]. Normalmente está tudo bem, mas nesta hipótese os autores de LibXYZ não sabem / não se importam com o versionamento semântico. Ilmerge eliminou esse problema.

Bem como o ponto pertinente do @thefringeninja , eu sugeriria que uma única unidade binária implantável reduz a sobrecarga de operações. Ele reduz a probabilidade de algo dar errado com uma implantação, diminui o fardo de avaliar cognitivamente o que você enviou e reduz a configuração do conjunto de ferramentas de operação, seja script ou estado desejado.

Aprecio que o ferramental dotnet é nascente e acabou de atingir 2.0, mas em comparação com alternativas como o golang, esse recurso está faltando. Por favor, considere adicioná-lo ao roteiro?

Como um desenvolvedor lib, eu gostaria de ter o ILMerge de volta no Core. 👍

Dotnet.exe é um único arquivo. NuGet.exe é um único arquivo. Eu acho que cosméticos são importantes, e um único exe de arquivo significa simplicidade de uma forma que uma pasta com 100 arquivos não consegue! Seria ótimo encontrar uma maneira de conseguir isso com dotnetcore

Achei que isso fosse possível e, após várias semanas de trabalho, comecei a publicar a ferramenta de console CLI em um único .exe ... hummm parece que no momento não consigo apenas obter um único * .exe ??
Eu pensei que era esse o objetivo de aplicativos centrais independentes?

@PRIMETSS

Eu pensei que era esse o objetivo de aplicativos centrais independentes?

O objetivo dos aplicativos independentes é que eles são independentes, ou seja, não exigem que o .Net Core seja instalado na máquina de destino, porque o próprio aplicativo contém tudo o que precisa para ser executado.

Para implantar esse aplicativo, você deve copiar um diretório inteiro de arquivos. Ter apenas um único arquivo tornaria a implantação mais fácil, mas é isso, ainda é um aplicativo independente, mesmo sem isso.

Para aplicativos grandes e semelhantes a serviços, isso pode não ser tão importante, mas é essencial que as ferramentas de linha de comando e os aplicativos pequenos sejam o mais simples possível e com implantação de cópia fácil.

Eu regularmente escrevo ferramentas de linha de comando em .NET e tê-las como 1 EXE torna as atualizações / implantações / empacotamento muito mais simples. Sempre coloco todos os arquivos .config e outros arquivos necessários dentro do EXE.

Pense naquele EXE único como um minicontêiner. Quase todos os benefícios das implantações baseadas em contêiner se aplicam aqui.

Isso é horrível. Eu me pergunto por que isso foi aprovado durante o processo de design, quero distribuir seu aplicativo para um de seus clientes, então boa sorte para ele encontrar o que abrir:
image

Isso é simplesmente feio e uma bagunça completa

tempo de execução/
MyProgram.exe
MyLib.dll

Esta teria sido uma ideia muito melhor

Até o Java lida melhor com isso:
explorer_2018-04-21_16-42-33

Sim, eu estava pensando na mesma linha, já que os aplicativos independentes precisam ter os arquivos de tempo de execução incluídos com eles (obviamente!) (E não temos uma maneira de mesclá-los), então eu também pensei que apenas uma separação de pastas seria seja mais organizado e, sim, também acho que os arquivos de tempo de execução devem ser armazenados em uma pasta de tempo de execução, para que qualquer pessoa que tente usar uma ferramenta de linha de comando escrita no núcleo, pelo menos a ache um pouco mais intuitiva quanto ao que executar.

@Scellow @PRIMETSS eu tenho que concordar

Como isso ainda é um problema? A demanda está nas alturas para isso.

sim a esta pasta separada com a adição de compactar isso em uma lixeira e ter dois arquivos, o exe e a lixeira. Distribuição fácil.

Outro +1 para reabrir e ter como recurso.

Eu esperava que a implantação independente fosse independente e encontrei meu caminho até aqui. Eu também gostaria de ver isso acontecer.

Como alguém pode dizer que isso é apenas uma questão cosmética? (Apenas desenvolvedores de framework ...)
Ninguém pensou em ferramentas que não estão instaladas? (.NET resolveu o inferno e .net core o traz de volta)

Eu só quero que minha ferramenta de linha de comando seja independente.

Isso é ruim, muito ruim!

+1

1 Eu acabei de tentar executar a atividade personalizada no Lote do Azure em um cluster sem .net core runtime e ele não consegue lidar com o grande número de arquivos que a versão "independente" cria.

Total size of resourceFiles cannot be more than 32768 characters

Esta não é uma solução oficial, mas pode ser útil. Sou o autor do warp, uma ferramenta que permite criar aplicativos binários únicos e independentes: https://github.com/dgiagio/warp

Eu acho que warp é basicamente o que todo mundo está procurando aqui! É apenas sobre a capacidade de ter um único arquivo exe, o que quer que esteja em segundo plano, nada mais. Pense nos pacotes NuGet: é um único arquivo .nuget e pronto; não é algo mais complexo do que um arquivo que contém outros arquivos.

warp é uma solução hacky, não é isso que queremos

O que queremos é:

dotnet publish --self-contained -c Release -r win10-x64

E produz:

App.exe
runtime/

Ou melhor como GO / Rust etc

App.exe

Todo o resto não é desejado

Warp produz um App.exe ... Como isso é hacky? Obviamente, não faz parte do framework, mas atinge o objetivo de "um arquivo exe".

Isso é o que quero dizer, deve ser o comportamento padrão, não usando solução de terceiros (eu acho)

Warp funciona muito bem. Obrigado pelo seu trabalho @dgiagio!

+1

Eu gostaria muito de ver algum tipo de arquivo de arquivo único que agrupe o executável e todas as dependências. Não precisa incluir os nativos - acho que é perfeitamente normal exigir que o núcleo dotnet seja instalado no sistema. Algo muito semelhante aos arquivos jar do Java. Um arquivo dar?

Algo como:
publicar dotnet - autocontido
dotnet run - autocontido MyApp.dar

Parece que há uma proposta para isso agora: https://github.com/dotnet/designs/pull/52/files?short_path=28dba55

Aqui está o problema de rastreamento: https://github.com/dotnet/coreclr/issues/20287

Eu li a proposta e vi o seguinte:

image

Não era isso que eu tinha em mente, parece um processo lento, basicamente fechando tudo.
Eu pensei que todo o código seria mesclado em um único executável / dll? ou talvez eu tenha esquecido algo na proposta?

@RUSshy Você está perguntando sobre a compilação nativa de todo o código gerenciado e a vinculação de tudo para obter um executável (como no CoreRT)? Este não é um objetivo para o trabalho de arquivo único atual no .Net Core.

No entanto, existem soluções propostas para reduzir a extração de disco e o tempo de inicialização (ex: carregar certos tipos de arquivos diretamente do pacote , reutilizar arquivos extraídos ). Os estágios de desenvolvimento da solução de arquivo único são descritos aqui .

CC: @jeffschwMSFT

Por que os arquivos precisam ser extraídos? Costumávamos fazer isso no .NET com ILMerge.

@phillip-haydon, conforme descrito aqui , ILMerge e soluções de arquivo único alcançam objetivos diferentes.

ILMerge combina o IL de muitos assemblies em um, mas no processo, perde a identidade original dos assemblies mesclados. Portanto, coisas como usar reflexão com base em nomes de montagem originais falharão. Os aplicativos ainda podem usar ILMerge se puderem tolerar essa mudança.

CoreRT é outra coisa, compilação AOT de seu código .NET, parece interessante, mas ainda não está pronto (gostaria que a MS se concentrasse nisso e alocasse mais recursos ... isso é exatamente o que as pessoas desejam e por que mudaram para GO )

Enfim, não tenho conhecimento técnico para falar sobre o detalhe, mas o caso de uso é:

Publique um único executável autocontido e apenas isso, nada compactado, nada extraído, sem sobrecarga, apenas o executável

@ swaroop-sridhar você tem um exemplo disso funcionando para o núcleo dotnet no linux? de acordo com https://github.com/dotnet/ILMerge/blob/master/ILMerge/ILMerge.csproj#L13, este é um projeto somente Windows / mono.

@thefringeninja ILMerge é uma ferramenta do Windows, não sei de nenhum plano para portar o ILMerge para outras plataformas.
A solução de arquivo único será implementada em plataforma cruzada. Isso está em processo de desenvolvimento.

@karelz @mellinoe
Implantar Implantar Implantar!se for Único ou menos como 1-3 arquivos, isso será melhor para Implantar (Inlcude Publish, Update)!

CoreRT é AOT
mas as pessoas querem AOT?
o projeto (CoreRT) nem sempre Pronto para usar (é de 2014). Agora é 2019! ( Cerca de 5 anos )
Que 5 anos preciosos para uma linguagem de pragrama!o CoreRT nem tem planos para o próximo lançamento !!!deixe o ppl esperar mais 5 anos?

@ swaroop-sridhar Isso é lamentável. ILMerge / ILRepack é ótimo para desenvolvedores de bibliotecas para evitar o problema de dependência de diamante.

Há planos para oferecer suporte no .NET Core 3.0 - @richlander pode atualizá-lo sobre o status.
Ele foi mencionado em postagens de blog do .NET Core 3.0 - por exemplo, aqui: https://devblogs.microsoft.com/dotnet/net-core-3-and-support-for-windows-desktop-applications/ em "Side-by- lado e na seção Implantação local do aplicativo ".
Leia também: https://www.hanselman.com/blog/BrainstormingCreatingASmallSingleSelfcontainedExecutableOutOfANETCoreApplication.aspx

.net não deve precisar de todos esses hacks para produzir pequenos executáveis ​​autocontidos ... deve ser o comportamento padrão, você é comido vivo por GO, Rust também está chegando, foco em CoreRT ou ILMerge, aplicativos principais .net também estão muito tempo para começar por causa de todos os arquivos para carregar, não adicione mais ouvidos a isso com zip / unzip como mencionado na proposta, este não é o caminho a percorrer

.net não deve precisar de todos esses hacks para produzir pequenos executáveis ​​autocontidos ... deve ser o comportamento padrão, você é comido vivo por GO, Rust também está chegando, foco em CoreRT ou ILMerge, aplicativos principais .net também estão muito tempo para começar por causa de todos os arquivos para carregar, não adicione mais ouvidos a isso com zip / unzip como mencionado na proposta, este não é o caminho a percorrer

Como você gosta .net não precisa ficar vivo, porque ppl tem java.
go ou rust ou dlang não devem suportar o build target para um único programa executável, porque eles têm o Fuck Zip / Unzip!

@RUSshy

.net não deve precisar de todos esses hacks para produzir pequenos executáveis ​​autocontidos

Acordado. Ao mesmo tempo, o .NET fornece certos recursos em relação a outras linguagens que são desafiadores a conciliar com os requisitos de um vinculador estático (por exemplo, geração de código em tempo real, reflexão, vinculação de dados etc.) Experimentamos excluir esses recursos em cenários em que a vinculação estática / arquivo único é importante. Aprendemos com o feedback dos clientes que o resultado disso não parece mais com o .NET, em parte porque o número de bibliotecas que você pode consumir do ecossistema cai drasticamente.

Portanto, fazer um vinculador de maneira adequada que não comprometa a fidelidade dos recursos que todos nós consideramos uma dependência e amamos no .NET é um problema difícil. Como parte da solução disso, estamos experimentando várias abordagens. Você chama isso de hacks, eu chamo isso de mente aberta e disposta a pensar fora da caixa. Mas transformar cegamente o .NET em Go / Rust / C ++ não é a resposta certa.

Experimentamos excluir esses recursos em cenários em que a vinculação estática / arquivo único é importante. Aprendemos com o feedback dos clientes que o resultado disso não parece mais com o .NET, em parte porque o número de bibliotecas que você pode consumir do ecossistema cai drasticamente.

A equipe pensou em criar uma versão separada do .net focada no desenvolvimento nativo e em ambientes restritos, como o jetbrains fez com kotlin JVM / kotlin NATIVE?

Como você disse, tentar fazer .net se encaixar em todos os casos de uso não é a opção mais inteligente, então um tipo específico pode ser a resposta certa para este problema

E tbh, afaik, esse problema realmente não existia antes do .net core já que cada instalação do Windows já tinha o .net framework, então você só tinha que distribuir seus poucos KBs exe, e o que me irrita é que ninguém parece ter pensado neste tipo problema ao projetar o núcleo .net, que foi basicamente uma reescrita da estrutura .net .. é por isso que estou dizendo que essas opções mencionadas são simples hacks, elas estão aqui para corrigir erros de design

Depois de ler https://github.com/dotnet/designs/blob/master/accepted/single-file/staging.md , parece haver mais etapas para a proposta, e ela não termina em zip / unzip, então não luta perdida, espero que a equipe venha com algo mais leve, o que está mencionado naquele documento, bom!

Coisas como essa são a razão pela qual o Windows continua sendo um sistema operacional de brinquedo.

@kjkrum Coisas como o quê?

@cryru é o que as pessoas dizem quando não sabem o que estão fazendo.

@Cryru Coisas como não ser capaz de construir um executável autônomo e a desconsideração da necessidade real de fazê-lo. Praticamente todos os outros sistemas de construção existentes não apenas construirão um executável estaticamente vinculado, como também retirarão as partes não utilizadas das dependências. Eliminar dependências tem sido um recurso padrão por pelo menos uma década; vinculação estática desde a invenção dos compliers.

@Cryru Coisas como não ser capaz de construir um executável autônomo e a desconsideração da necessidade real de fazê-lo. Praticamente todos os outros sistemas de construção existentes não apenas construirão um executável estaticamente vinculado, como também retirarão as partes não utilizadas das dependências. Eliminar dependências tem sido um recurso padrão por pelo menos uma década; vinculação estática desde a invenção dos compliers.

Concordo, isso está realmente relacionado à posição dos programas C # no sistema operacional.
Os programas C # sempre não conseguem se tornar cidadãos de primeira classe.Apenas para ser a segunda classe.

Isso está resolvido.
TLDR: dotnet publish -r win10-x64 /p:PublishSingleFile=true

Detalhes:
https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#single -file-executables
https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md

Isso está resolvido.
TLDR: dotnet publish -r win10-x64 /p:PublishSingleFile=true

Detalhes:
https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#single -file-executables
https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md

Em qual versão do dotnet-core esse recurso foi adicionado? Estou usando 3.0.100-preview5-011568 e recebo este erro:
error MSB4030: "/p:PublishSingleFile=true" is an invalid value for the "SelfContained" parameter of the "ResolveFrameworkReferences" task. The "SelfContained" parameter is of type "System.Boolean".

LE: Na verdade está funcionando, parece que só há um erro de sintaxe em https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md que declara publicação com dotnet publish -r win10-x64 --self-contained /p:PublishSingleFile=true e realmente está sem adicionar --self-contained .

Obrigado @mihaimyh . Vou corrigir o erro de digitação no documento de design.

Sou sempre contra o uso de solução zip / unzip para o recurso único exe independente .
porque isso causará o próximo problema.
Como reduzir o tamanho do arquivo EXE único!

Na verdade, desde o início deve usar formas semelhantes IL-Merge.

Não deveria haver um debate, isso é perda de tempo, ninguém pediu para zip / unzip a coisa toda, e mesmo assim eles vieram com esse design e perderam seu tempo e o nosso

As pessoas pedem um único executável e AOT, pare de perder nosso tempo Microsoft

Quero explicitamente um único arquivo sem AOT. Eu prefiro a capacidade de JIT para que eu possa usar reflexão, genéricos e código gerado em tempo de execução.

Acho que MS não quer ouvir ok

Sou sempre contra o uso de solução zip / unzip para o recurso único exe independente .
porque isso causará o próximo problema.
Como reduzir o tamanho do arquivo EXE único!

Não tenho certeza se entendi, como se seu Zipado já estivesse compactado. Ou você está se referindo à redução de dependências redundantes e, portanto, ao tamanho reduzido antes da compactação?

Não entendendo a negatividade. Eu não usei ainda, exceto o teste rápido. Mas parece que o único executável funciona bem para a situação de implantação de um aplicativo no cliente ou como uma ferramenta CLI. E é aí que acredito que esse recurso seja útil. Fora isso, no Dev ou em outro ambiente, não vejo um caso de uso para isso, então o que eles fizeram funciona bem como uma solução por enquanto.

@RUSshy

Acho que MS não quer ouvir ok

Ao contrário, eles estão solicitando e coletando uma ampla gama de casos de uso que você pode ver em threads relacionados. Sua opinião é importante, mas as opiniões de outras pessoas na comunidade são igualmente importantes e você não deve zombar da Microsoft por ouvi-las.

Com base em sua declaração, acho que você pode ter me confundido com a Microsoft. Sou apenas um membro da comunidade como você, que não fala pela Microsoft de forma alguma.

Sou sempre contra o uso de solução zip / unzip para o recurso único exe independente .
porque isso causará o próximo problema.
Como reduzir o tamanho do arquivo EXE único!

Não tenho certeza se entendi, como se seu Zipado já estivesse compactado. Ou você está se referindo à redução de dependências redundantes e, portanto, ao tamanho reduzido antes da compactação?

se você usar WebApi, MVC ou ConsoleApp, escreva um HelloWorld! vc bem sabe o que quero dizer.
o arquivo compactado é muito grande. ele traz muito código, mas nunca será executado.
se as formas IL-Merge irão reduzir o desvio de código não utilizado.

Sim, claro que fiz um console HelloWorld e sim, é 68K
Capture
O nada independente era 67K
Mas seu C # não é assembly. Se eu quisesse um <1K HelloWorld, por que usar c #?
Aplicativos maiores usam mais a estrutura, então em um ponto seu código é mais personalizado do que a estrutura.
Estamos realmente preocupados com alguns 100K? Se sim, não use um framework e gaste o tempo escrevendo tudo do zero ??
O que estou perdendo aqui?

Sou sempre contra o uso de solução zip / unzip para o recurso único exe independente .
porque isso causará o próximo problema.
Como reduzir o tamanho do arquivo EXE único!
se você usar WebApi, MVC ou ConsoleApp, escreva um HelloWorld! vc bem sabe o que quero dizer.
o arquivo compactado é muito grande. ele traz muito código, mas nunca será executado.
se as formas IL-Merge irão reduzir o desvio de código não utilizado.

@sgf, existem dois problemas um tanto separados aqui:

  • Como reduzir o código de um aplicativo?
  • Como empacotar o aplicativo em um único arquivo?

Para redução de código, existem várias outras técnicas

  • Mesclando IL: isso não é para todos os aplicativos, porque perde a identidade do assembly no processo. Este não é um objetivo para o atual trabalho single-exe.
  • Cortando IL não usado: O ILLinker visa cortar IL não usado. Este recurso é integrado ao dotnet SDK (propriedade PublishTrimmed ), e mais otimizações no ILLinker estão em desenvolvimento.
  • Compactar / descompactar: ​​o dotnet publish não compacta atualmente o arquivo único publicado, mas pode ser feito.

Como empacotar o aplicativo em um único arquivo?
O dotnet publish oferece suporte à publicação em um único arquivo - o arquivo publicado será tão grande quanto o aplicativo seria de outra forma.

Em relação à geração de código nativo:

  • Atualmente, o suporte para geração de código nativo é através do compilador pronto para executar (propriedade PublishReadyToRun ).
  • Publicar por compilação AOT é ótimo ( CoreRT ), mas ainda não está disponível. Também com a compilação AOT, o tamanho do executável depende das opções de compilação: ex: incluímos o jit para executar o código gerado, etc.?

Sim, claro que fiz um console HelloWorld e sim, é 68K
Capture
O nada independente era 67K
Mas seu C # não é assembly. Se eu quisesse um <1K HelloWorld, por que usar c #?
Aplicativos maiores usam mais a estrutura, então em um ponto seu código é mais personalizado do que a estrutura.
Estamos realmente preocupados com alguns 100K? Se sim, não use um framework e gaste o tempo escrevendo tudo do zero ??
O que estou perdendo aqui?

desculpe como ur img mostrado, com auto contianed. Isso é 68626KB, é cerca de 68mb = 68KK, não apenas 68K
não precisaremos de <1kb (com autoconfiança Isso é impossível), <3000KB está ok, aceite.
Mas 68 MB é mais 30X +
Você não vai sempre escrever apenas um Programa HelloWorld !!!

Desculpas, tarde da noite erro com o K's
Obrigado pela explicação / informação adicionada swaroop-sridhar, algumas novas opções que eu não tinha conhecimento.
Tentei com 3.preview 6 com as seguintes opções

dotnet publish -r RID / p: PublishTrimmed = true / p: PublishSingleFile = true
e agora caiu para 29.000K

Claro que nem todos os aplicativos serão Hello World, mas para um aplicativo autocontido C # Core, que também contém o tempo de execução ... Pessoalmente, não estou preocupado. Claro que entendo que se você estiver escrevendo uma pequena ferramenta de console, seria bom tê-la 3K. Mas por que usar C # para isso em primeiro lugar?
Discussão interessante, embora pessoal!

image
Capture

30mb rsrs, me liga quando for algo como 1-3mb, o runtime está cheio de inchaço, olha GO, as pessoas migram no wave

https://www.jetbrains.com/lp/devecosystem-2019/

Até mesmo o kotlin começa a ganhar partes, e com o kotlin nativo isso deixa c # envergonhado

E o Swift está chegando ao Windows https://forums.swift.org/t/swift-win32-programming/20686

Então aqui estão algumas sugestões:

  • Adicionar opção para remover reflexo
  • Adicionar opção para remover coisas JIT
  • Otimize melhor o código C # para não confiar no JIT

30mb rsrs, me liga quando for algo como 1-3mb, o runtime está cheio de inchaço, olha GO, as pessoas migram no wave

https://www.jetbrains.com/lp/devecosystem-2019/

Até mesmo o kotlin começa a ganhar partes, e com o kotlin nativo isso deixa c # envergonhado

E o Swift está chegando ao Windows https://forums.swift.org/t/swift-win32-programming/20686

Então aqui estão algumas sugestões:

  • Adicionar opção para remover reflexo
  • Adicionar opção para remover coisas JIT
  • Otimize melhor o código C # para não confiar no JIT

Eu acho que isso não é justo. .NET não foi projetado para construir os menores aplicativos de console de arquivo único. Nós o usamos para sites e apis Asp.Net. Portanto, o próprio framework traz uma tonelada de recursos com ele, além de toneladas de pacotes nuget que você pode incluir. Não consigo imaginar que haja uma preocupação se um aplicativo da web tiver 50 ou várias centenas de megabytes de tamanho. A principal preocupação é a velocidade, o uso de memória e a manutenção em longo prazo. Quem se importa com o tamanho do servidor.

Se sua única intenção é construir um aplicativo de console de tamanho pequeno e único MB, por que não usar a ferramenta certa para o trabalho. Em vez de reclamar que um aplicativo com uma estrutura completa empacotada em um único arquivo tem várias dezenas de megabytes de tamanho, mesmo para um "mundo alô", por que não ir com o Rust, por exemplo?

A Microsoft está fazendo um ótimo trabalho com o .NET desde o seu início e ainda mais nos últimos anos, então, obrigado por isso.

O que responder a tamanha falta de sentido, mentiras e falta de senso de eficiência?

Você não consegue perceber como a direção do núcleo .net estava errada, e apenas recentemente eles começaram a perceber isso trabalhando em Distribution / IL Merge / AOT

E agora, para avançar no vagão de web-assembly, eles não podem, porque o tempo de execução .net é um inchaço ENORME que eles não conseguem implantar arquivos de tamanhos decentes

E você ainda ficou com "Quem se importa com o tamanho no servidor?", Essa maneira de pensar é o que transformou o núcleo .net "supostamente moderno" em uma pilha de tecnologia já desatualizada e irrelevante

A Microsoft não está fazendo um bom trabalho com .net, eles falharam porque queriam agradar os idosos pela compatibilidade do framework .net, foi um de seus erros

Desculpe se pareço rude, mas às vezes você precisa ser para fazer alterações

Desculpe se pareço rude, mas

Você parece rude, ponto final. Isso, e suas rejeições e conclusões precipitadas, não têm o efeito de ser persuasivo.

Desculpas, tarde da noite erro com o K's
Obrigado pela explicação / informação adicionada swaroop-sridhar, algumas novas opções que eu não tinha conhecimento.
Tentei com 3.preview 6 com as seguintes opções

dotnet publish -r RID / p: PublishTrimmed = true / p: PublishSingleFile = true
e agora caiu para 29.000K

Claro que nem todos os aplicativos serão Hello World, mas para um aplicativo autocontido C # Core, que também contém o tempo de execução ... Pessoalmente, não estou preocupado. Claro que entendo que se você estiver escrevendo uma pequena ferramenta de console, seria bom tê-la 3K. Mas por que usar C # para isso em primeiro lugar?
Discussão interessante, embora pessoal!

image
Capture

como uma linguagem moderna não deveria ter um pouco de ambição de unificar o mundo?
Você quer que todos os desenvolvedores que escrevam c # voltem para casa em C ++? ou empurrá-los para Go, Kotlin, Swift?
Participação de mercado e corroer ainda mais o c #?

.Net porque não implementa plataforma cruzada perdeu os primeiros 15+ anos da grande oportunidade de desenvolvimento.
Mas agora .net está de volta ao caminho certo.

Sim, como comentei antes, não tenho certeza por que a negatividade.
.Net Core tem sido fantástico se você está vindo do Full Framework. E a visão do amálgama .Net Standard + Core eu acho sensata e progressiva.

Comparar .NET com GO ou qualquer outra linguagem / estrutura é inútil.
De qualquer forma, estou DESCONHECIDO neste tópico, pois acho que a solução que eles estão trabalhando e melhorando para o .exe único resolveu muito bem o meu pedido de vários anos atrás ... Bom o suficiente para mim e atende às minhas necessidades imediatas.

Então, obrigado Pessoal e Garotas!

FORA

Gostaria de lembrar a todos neste tópico sobre o Código de Conduta .

Não há problema em discordar ou ter opinião diferente, mas, por favor, sejamos educados e expressemos isso como uma discussão técnica. Não há necessidade de usar palavras fortes.
Além disso, direcionar ideias e implementações com suas opiniões é um jogo justo. NO ENTANTO, NÃO É ACEITÁVEL atacar PESSOAS por trás delas. Por favor, sejamos todos respeitosos uns com os outros, vamos ouvir opiniões diferentes e vamos evitar declarações fortes e comentários ofensivos.

Além disso, gostaria de pedir a todos que estivessem abertos a outros pontos de vista e opiniões. Antes de fazer julgamentos, normalmente é bom ouvir o outro lado - geralmente há uma história por trás de por que as coisas são do jeito que são. Cutucar ideias e soluções quando se sabe por que são do jeito que são normalmente é mais produtivo.

Obrigado!

Sou sempre contra o uso de solução zip / unzip para o recurso único exe independente .
porque isso causará o próximo problema.
Como reduzir o tamanho do arquivo EXE único!
se você usar WebApi, MVC ou ConsoleApp, escreva um HelloWorld! vc bem sabe o que quero dizer.
o arquivo compactado é muito grande. ele traz muito código, mas nunca será executado.
se as formas IL-Merge irão reduzir o desvio de código não utilizado.

@sgf, existem dois problemas um tanto separados aqui:

  • Como reduzir o código de um aplicativo?
  • Como empacotar o aplicativo em um único arquivo?

Para redução de código, existem várias outras técnicas

  • Mesclando IL: isso não é para todos os aplicativos, porque perde a identidade do assembly no processo. Este não é um objetivo para o atual trabalho single-exe.
  • Cortando IL não usado: O ILLinker visa cortar IL não usado. Este recurso é integrado ao dotnet SDK (propriedade PublishTrimmed ), e mais otimizações no ILLinker estão em desenvolvimento.
  • Compactar / descompactar: ​​o dotnet publish não compacta atualmente o arquivo único publicado, mas pode ser feito.

Como empacotar o aplicativo em um único arquivo?
O dotnet publish oferece suporte à publicação em um único arquivo - o arquivo publicado será tão grande quanto o aplicativo seria de outra forma.

Em relação à geração de código nativo:

  • Atualmente, o suporte para geração de código nativo é através do compilador pronto para executar (propriedade PublishReadyToRun ).
  • Publicar por compilação AOT é ótimo ( CoreRT ), mas ainda não está disponível. Também com a compilação AOT, o tamanho do executável depende das opções de compilação: ex: incluímos o jit para executar o código gerado, etc.?

Conforme necessário, mescle DLLs nativas para um nome como: XXX.exe (não gerenciado).
Uso de análise estática para análise ao compilar a vinculação de nível de função NativeDLLs (UnManaged).

api-ms-win-core-console-l1-1-0.dll
api-ms-win-core-datetime-l1-1-0.dll
api-ms-win-core-debug-l1-1-0.dll
api-ms-win-core-errorhandling-l1-1-0.dll
api-ms-win-core-file-l1-1-0.dll
api-ms-win-core-file-l1-2-0.dll
api-ms-win-core-file-l2-1-0.dll
api-ms-win-core-handle-l1-1-0.dll
api-ms-win-core-heap-l1-1-0.dll
api-ms-win-core-interlocked-l1-1-0.dll
api-ms-win-core-libraryloader-l1-1-0.dll
api-ms-win-core-localization-l1-2-0.dll
api-ms-win-core-memory-l1-1-0.dll
api-ms-win-core-namedpipe-l1-1-0.dll
api-ms-win-core-processenvironment-l1-1-0.dll
api-ms-win-core-processthreads-l1-1-0.dll
api-ms-win-core-processthreads-l1-1-1.dll
api-ms-win-core-profile-l1-1-0.dll
api-ms-win-core-rtlsupport-l1-1-0.dll
api-ms-win-core-string-l1-1-0.dll
api-ms-win-core-synch-l1-1-0.dll
api-ms-win-core-synch-l1-2-0.dll
api-ms-win-core-sysinfo-l1-1-0.dll
api-ms-win-core-timezone-l1-1-0.dll
api-ms-win-core-util-l1-1-0.dll
api-ms-win-crt-conio-l1-1-0.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-locale-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-multibyte-l1-1-0.dll
api-ms-win-crt-private-l1-1-0.dll
api-ms-win-crt-process-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
aspnetcorev2_inprocess.dll
clrcompression.dll
clretwrc.dll
clrjit.dll
coreclr.dll
dbgshim.dll
dotnet-aspnet-codegenerator-design.dll
hostfxr.dll
hostpolicy.dll
mscordaccore_amd64_amd64_4.6.27317.07.dll
mscordbi.dll
mscorrc.dll
mscorrc.debug.dll
sni.dll
sos.dll
sos_amd64_amd64_4.6.27317.07.dll
ucrtbase.dll
...etc...

se fizer um bom trabalho, o resultado pode ser 2-3 MB. quando estou diretamente embalado todos eles com 7zip, leva cerca de 4,85 MB. Agora temos XXX.exe

desenvolver o vínculo de nível de função semelhante com IL-merge.
Para uma DLL gerenciada, o mesmo velho truque novamente.
Por último, incorpore o DLL gerenciado como as Seções PE.exe (marque como seção .net).

Para refletir, DLL de análise do tipo de reflexão. Reter metadados e tipo de reflexão (incluindo função) e todos os seus dependentes de árvore.

Peço desculpas, não quero perder mais tempo para participar da discussão sobre isso. As opiniões não podem ser unificadas.
No começo eu esperava o resultado. Mas agora, eu provavelmente deveria considerar outras linguagens de programação para atender às minhas necessidades (talvez Dlang, talvez Go, talvez Kotlin, talvez Nim ou talvez Rust seja a melhor).

obrigado por tudo falar isso comigo. desculpe por minha insistência. Fora

@sgf Acho que você fez alguns pontos positivos e sei que você já

  1. Mono já suporta compilação AOT com Linking para reduzir o tamanho do arquivo. Este é um dos motivos pelos quais mono foi escolhido para a implementação do tempo de execução .net do navegador. https://www.mono-project.com/docs/advanced/aot/ e presumo que seja por isso que os projetos do Blazor podem ter um Linker.

  2. A Microsoft declarou que deseja consolidar seus tempos de execução .NET em um "todo poderoso". Em vez de ter mono para algumas coisas e .NET Core para outras, eles querem um único tempo de execução que pode ser usado em todos os cenários. Este fato significa que ele precisará suportar AOT e Linking / Code stripping etc. Portanto, espero que nos próximos anos, o tempo de execução do .NET Core obtenha esses recursos ou os recursos Mono e .NET Core sejam consolidados em um novo Tempo de execução.

Se alguém souber melhor, por favor me informe.

+ 2 ¢

Acho que o problema é que parece que as decisões estão sendo tomadas sem muita informação. Hoje em dia, para onde quer que eu olhe, as pessoas estão falando sobre isso; a grande maioria das pessoas que implantam programas tem isso no topo de sua lista de desejos e muitos estão mudando do C # para outras linguagens com melhor AOT / implantabilidade. Acho que é um fato bastante estabelecido que se torna muito evidente se você é ativo na comunidade. No entanto, não parece estar afetando as decisões em nada.

A questão é que parece que ninguém sabe exatamente até que ponto isso é importante. Para mim, pessoalmente, é extremamente importante, então é claro que sou muito tendencioso, mas a impressão que tenho é que no geral isso é de extrema importância e parece que a MS não está dando a atenção que merece, deixando muitos de nós a impressão eles estão tomando decisões uniformes, o que, por sua vez, não nos deixa confiantes sobre o futuro da tecnologia como um todo.

Eu concordo com @RUSshy. CoreRT é um projeto incrível e definitivamente está indo na direção certa, mas no geral parece que todos os esforços estão focados em tecnologias de servidor / web. Coisas como tempos de execução, jits e binários grandes falam por si a esse respeito. Ninguém implantando software quer essas coisas.

Dito isso, eu pessoalmente ainda estou usando a tecnologia, embora não esteja realmente prendendo a respiração sobre seu futuro em algumas áreas.

Eu gostaria de ver mais participação da comunidade na direção que está sendo tomada, mesmo que seja o oposto do que eu pessoalmente espero. Mas até agora parece que as decisões estão sendo tomadas sem levar isso em consideração. Parece que servidor / web é o que faz dinheiro e as pessoas que implantam programas são uma minoria insignificante (pelo menos em termos de lucros), mas se for esse o caso, eu pelo menos gostaria de saber em que estão baseando suas decisões ( é muito provável), porque do lado de fora parece que eles estão jogando uma moeda.

@ Alan-FGR

Mas até agora parece que as decisões estão sendo tomadas sem levar isso em consideração.

Você tem exemplos específicos de tais decisões para compartilhar, pois estou curioso para saber mais.

Acho que a MS está muito ciente das deficiências do atual tempo de execução do núcleo dotnet e é por isso que eles buscarão paridade de recursos com tempo de execução mono no futuro.

Basta olhar as notas de lançamento do .net core 3.0.0 preview 6:

Hoje, estamos anunciando o .NET Core 3.0 Preview 6. Ele inclui atualizações para compilar assemblies para inicialização aprimorada, otimizando aplicativos para tamanho com linker e melhorias de EventPipe. Também lançamos novas imagens do Docker para Alpine no ARM64.

Parece que eles estão bem cientes de que o tamanho do aplicativo é importante para certos cenários - especialmente agora com o Blazor na mistura.

@ Alan-FGR Concordo, o foco na web é bastante estranho, considerando que o IIS tem cerca de 8% de participação de mercado e está caindo. ASP.NET é irrelevante, e nenhuma melhoria no C # ou em suas bibliotecas padrão vai mudar isso. C # está sendo sustentado por aplicativos de console, serviços do Windows, aplicativos móveis e jogos de PC. Ele deve sua existência continuada à Unity e Xamarin. O que é uma pena, porque C # é uma linguagem realmente agradável para desenvolver. Isso é um grande elogio vindo de um desenvolvedor Java de longa data que ainda acha que a Microsoft deixou sua marca d'água alta com o Windows XP.

Conforme necessário, mescle DLLs nativas para um nome como: XXX.exe (não gerenciado).
Uso de análise estática para análise ao compilar a vinculação de nível de função NativeDLLs (UnManaged).

Não tenho certeza do que você quer dizer com mesclagem dinâmica, mas há um plano para vincular estaticamente os componentes nativos junto com o host. Por favor, veja esta seção .

desenvolver o vínculo de nível de função semelhante com IL-merge.
Para refletir, DLL de análise do tipo de reflexão. Reter metadados e tipo de reflexão (incluindo função) e todos os seus dependentes de árvore.

Discutimos a opção de mesclar assemblies em um e ter tabelas de metadados laterais para oferecer suporte a recursos dinâmicos. Ele oferece economias de tamanho consideráveis. Mas o custo de implementação é bastante alto - por causa do novo suporte a metadados e das mudanças necessárias nos depuradores / criadores de perfil, etc. para lidar com isso.

Existem algumas outras opções para reduzir o tamanho do binário - por exemplo, quando podemos executar um único arquivo diretamente (sem ter que extrair para arquivos), podemos descartar a assinatura / certificados em cada DLL em favor de assinar o aplicativo como um todo. Isso pode economizar alguns MBs às vezes.

Mas até agora parece que as decisões estão sendo tomadas sem levar isso em consideração.

Você tem exemplos específicos de tais decisões para compartilhar, pois estou curioso para saber mais.

Acho que a MS está muito ciente das deficiências do atual tempo de execução do núcleo dotnet e é por isso que eles buscarão paridade de recursos com tempo de execução mono no futuro.

@dazinator Acho que o próprio fato de a MS achar que o Mono é uma solução decente para qualquer coisa mostra que eles realmente não conhecem seus produtos. Eu usei o Mono e, embora seja uma peça importante de tecnologia e tenha ajudado a popularizar o .NET imensamente, está definitivamente faltando alguma qualidade ... Xamarin fez um ótimo trabalho de marketing promovendo sua tecnologia, mas foi baseado em promessas excessivas e insuficientes. entregando, e parece que quem está tomando essas decisões na MS apenas viu um pouco de seu material promocional e nunca realmente usou a tecnologia. CoreRT, por outro lado, é uma tecnologia que até agora ofereceu muito mais do que eu. Está em outro nível de qualidade, na minha opinião, e ainda assim está sendo negligenciado pela MS em favor de alguma tecnologia que eu suspeito que seja mantida com fita adesiva.

Concordo, o foco da web é um tanto estranho considerando que o IIS tem cerca de 8% de participação de mercado e está caindo. ASP.NET é irrelevante, e nenhuma melhoria no C # ou em suas bibliotecas padrão vai mudar isso. C # está sendo sustentado por aplicativos de console, serviços do Windows, aplicativos móveis e jogos de PC.

@kjkrum esse é o ponto. No entanto, talvez para eles 8% do mercado na web ainda seja muito mais importante do que o Windows e os aplicativos móveis. Bons técnicos da web ajudam pelo menos as vendas de servidores Windows, então seu interesse nisso é bastante óbvio, mas focar tanto nisso também é uma estratégia muito superficial e me recuso a acreditar que é isso que guia suas decisões. A MS parecia estar indo na direção certa com a fundação dotnet e tantos projetos promissores em andamento, mas parece que eles estão deixando a oportunidade de ter uma tecnologia dominante passar.

Eu sei que isso é anedótico, então provavelmente sem sentido, mas todas as pessoas que eu conheço que estavam usando C # em seus projetos (principalmente desenvolvedores de jogos) mudaram para outra coisa por causa de limitações que eram totalmente resolvíveis. Eles mudaram para Rust, D, Go e C ++. Eu mesmo uso C ++ regularmente e estou aprendendo Rust, mas ainda estou usando C # para alguns projetos pessoais porque é muito melhor, embora implantar um produto de qualidade seja uma dor de cabeça.

Ele deve sua existência continuada à Unity e Xamarin.

Sim, o que é uma bênção e uma maldição por causa dos muitos problemas técnicos. O Unity, por exemplo, tem uma reputação muito ruim, mas felizmente isso não afetou o .NET / C #.
O XNA, entretanto, embora longe de ser perfeito, ainda tem uma reputação incrivelmente grande entre usuários e desenvolvedores.

Fico feliz em ver esta aterrissagem com o .NET Core 3.0 hoje. Obrigado pessoal! 👍

Não tenho certeza se é isso que as pessoas querem, se acabarmos com uma calculadora simples que é 141 MB exe, então o recurso é uma falha (e eu acredito que o custo real é 141 MB * 2, já que vai extrair coisas em algum lugar certo)

image

Sim, é definitivamente o que eu quero. Ainda é menor do que uma implantação independente regular.

Um corte de montagem mais agressivo e agitação de árvores seriam bem-vindos, mas este é um começo muito útil. A melhoria incremental é a maneira mais inteligente de agregar valor.

Oh é isso que você quer? meu mal, eu não sabia que aplicativos inchados eram populares

Uma calculadora não precisa de JIT, nem mesmo de Reflection, mas como é isso que você quer, acho que estou errado desde o início, devo parar de programar

@RUSshy Não é mais inchado do que qualquer outra implantação independente, certo?

A remoção do JIT e do reflexo independe de tudo estar empacotado em um único exe. Ou seja, você pode remover JIT e reflexão sem single-exe, e você pode ter single-exe sem remover JIT e reflexão. Eles são peças separadas de trabalho.

Não tenho certeza se é isso que as pessoas querem, se acabarmos com uma calculadora simples que é 141 MB exe, então o recurso é uma falha (e eu acredito que o custo real é 141 MB * 2, já que vai extrair coisas em algum lugar certo)

ele extrai os arquivos em C: Users [YourUserName] AppDataLocalTemp.net

Existe alguma maneira de substituir onde exe único será descompactado?
Tive problemas ao tentar extrair em / var / .... onde o usuário não tem permissão para escrever.

@eiva qual sistema operacional era esse? Foi AWS lambda?
https://github.com/dotnet/core-setup/issues/7940 rastreia a correção desse problema.

Enquanto isso, você pode definir a variável de ambiente DOTNET_BUNDLE_EXTRACT_BASE_DIR para controlar onde os arquivos agrupados são extraídos.

@ swaroop-sridhar Obrigado pela resposta!
É centos.7 lançando aplicativo da conta de serviço "restrita".

@ jnm2 Agradeço que você ame C #, eu também. Mas vamos ser honestos, é uma loucura que uma calculadora tenha 128 megabytes.

@TechnikEmpire Acho necessário salientar que "Eu amo C #" é uma redução bastante intensa do que eu disse acima: D

Eu pessoalmente não vou me sentir totalmente satisfeito até que eu tenha a capacidade de fazer trepidação de meu próprio código e libs, libs de terceiros referenciadas e o próprio .NET. Mas isso não torna o recurso de exe único menos valioso para mim hoje. É um passo ao longo de uma dimensão. O sacudir de árvores é uma dimensão independente e espero que receba muita atenção.

Esta página foi útil?
0 / 5 - 0 avaliações