Crea un'applicazione console .NET Core per generare un file EXE


414

Per un progetto di applicazione console indirizzato a .NET Core 1.0, non riesco a capire come ottenere un file .exe per l'output durante la compilazione. Il progetto funziona bene nel debug.

Ho provato a pubblicare il progetto, ma non funziona neanche. Ha senso poiché un file EXE sarebbe specifico della piattaforma, ma deve esserci un modo. Le mie ricerche hanno rivelato solo riferimenti a versioni .NET Core precedenti che utilizzavano project.json.

Ogni volta che costruisco o pubblico, questo è tutto ciò che ottengo:

Directory di costruzione



2
@geekzster, per favore, deseleziona - So che non hai risposto alla domanda OP, ma hai risposto alla mia, e sospetto che quella di molti altri dicendo dotnet <path>.dll(non stavo pensando e digitando dotnet run <path>.dllsenza successo per ovvie ragioni)! (Riflettendoci sarebbe bene se questo fosse chiuso a favore dell'altra domanda che ha un simile set di risposte)
Ruben Bartelink,

Risposte:


480

Ai fini del debug, è possibile utilizzare il file DLL. Puoi eseguirlo usando dotnet ConsoleApp2.dll. Se si desidera generare un file EXE, è necessario generare un'applicazione autonoma.

Per generare un'applicazione autonoma (EXE in Windows), è necessario specificare il runtime di destinazione (che è specifico del sistema operativo di destinazione).

Solo Pre-.NET Core 2.0 : in primo luogo, aggiungere l'identificatore di runtime dei runtime di destinazione nel file .csproj ( elenco di RID supportati ):

<PropertyGroup>
    <RuntimeIdentifiers>win10-x64;ubuntu.16.10-x64</RuntimeIdentifiers>
</PropertyGroup>

Il passaggio precedente non è più necessario a partire da .NET Core 2.0 .

Quindi, impostare il runtime desiderato quando si pubblica l'applicazione:

dotnet publish -c Release -r win10-x64
dotnet publish -c Release -r ubuntu.16.10-x64

15
Penso che questo possa essere fatto solo con la CLI. A proposito, a partire da .net core 2, non è necessario impostare il RuntimeIdentifierin csproj.
Meziantou,

26
per .NET Core 2.0 questo può essere fatto in Visual Studio? O devo digitare questi comandi a mano?
Tomasz Sikora,

77
Oltre 60 MB per un'app console mondiale Hello!
shox,

13
@mikolaj Esiste un solo runtime di destinazione "portatile". C'è un modo per coinvolgere tutti gli obiettivi? Sono d'accordo con l'uso della riga di comando, tuttavia penso che sia un passo indietro.
gsharp,

10
Questo non crea un eseguibile autonomo. Questo crea un eseguibile, insieme a una miriade di altri file (nella cartella di rilascio intendo). Comprese alcune sottocartelle con i propri file. C'è un modo per creare un vero eseguibile autonomo ?
Matteo,

122

AGGIORNAMENTO (31-OTT-2019)

Per chiunque voglia farlo tramite una GUI e:

  • Sta usando Visual Studio 2019
  • .NET Core 3.0 è installato (incluso nell'ultima versione di Visual Studio 2019)
  • Vuole generare un singolo file

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Nota

Notare le dimensioni del file di grandi dimensioni per un'applicazione così piccola

Inserisci qui la descrizione dell'immagine

È possibile aggiungere la proprietà "PublishTrimmed". L'applicazione includerà solo i componenti utilizzati dall'applicazione. Attenzione : non farlo se si utilizza la riflessione

Inserisci qui la descrizione dell'immagine

Pubblica di nuovo

Inserisci qui la descrizione dell'immagine


Messaggio precedente

Per chiunque utilizzi Visual Studio e desideri farlo tramite la GUI, vedere i passaggi seguenti:

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine


19
Peccato che l'output sia un mucchio di file, non solo un EXE come il vecchio .NET Framework.
Tomas Karban,

2
@Tomas Karban - È stato il caso fino a quando ho cambiato la modalità di distribuzione in "autonomo" Dopo che il file exe di modifica è apparso anche nella cartella di pubblicazione :-)
Mariusz,

@TomasKarban .NET Core non è un runtime generico. È specificamente progettato per 1) distribuzione cloud / container, 2) multipiattaforma. È anche pensato per essere temporaneo - è solo un trucco "rapido" fino a quando tutto .NET non può essere reso open source. .NET 5.0 sarà il prossimo scopo generale .NET.
Luaan,

3
Tuttavia, è ridicolo che L'IDE per .NET semplicemente non supporti le funzionalità più basilari quando si prende di mira .NET Core. Ed è quello che tutti devono mirare a creare applicazioni da riga di comando multipiattaforma, ad esempio un compilatore.
Ripristina Monica il

18

Quanto segue produrrà, nella directory di output,

  • tutti i riferimenti del pacchetto
  • il gruppo di uscita
  • l'exe bootstrap

Ma non contiene tutti gli assembly di runtime .NET Core.

<PropertyGroup>
  <Temp>$(SolutionDir)\packaging\</Temp>
</PropertyGroup>

<ItemGroup>
  <BootStrapFiles Include="$(Temp)hostpolicy.dll;$(Temp)$(ProjectName).exe;$(Temp)hostfxr.dll;"/>
</ItemGroup>

<Target Name="GenerateNetcoreExe"
        AfterTargets="Build"
        Condition="'$(IsNestedBuild)' != 'true'">
  <RemoveDir Directories="$(Temp)" />
  <Exec
    ConsoleToMSBuild="true"
    Command="dotnet build $(ProjectPath) -r win-x64 /p:CopyLocalLockFileAssemblies=false;IsNestedBuild=true --output $(Temp)" >
    <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
  </Exec>
  <Copy
    SourceFiles="@(BootStrapFiles)"
    DestinationFolder="$(OutputPath)"
  />

</Target>

L'ho racchiuso in un campione qui: https://github.com/SimonCropp/NetCoreConsole


ad eccezione di ($ Temp) punta al mio c: \ Users \ xxx \ AppData \ Local \ Temp che ovviamente non può essere rimosso / pulito - né è consigliabile farlo
Adaptabi

1
@Adaptabi Temp è definito come una proprietà all'inizio della sceneggiatura
Simon

2

Se un file .bat è accettabile, puoi creare un file bat con lo stesso nome del file DLL (e posizionarlo nella stessa cartella), quindi incollare il seguente contenuto:

dotnet %~n0.dll %*

Ovviamente, ciò presuppone che la macchina abbia .NET Core installato e disponibile a livello globale.

c:\> "path\to\batch\file" -args blah

(Questa risposta deriva dal commento di Chet .)


0

Ecco la mia confusa soluzione: generare un'applicazione console (.NET Framework) che legge il proprio nome e argomenti, quindi chiama dotnet [nameOfExe].dll [args].

Ovviamente ciò presuppone che .NET sia installato sul computer di destinazione.

Ecco il codice. Sentiti libero di copiare!

using System;
using System.Diagnostics;
using System.Text;

namespace dotNetLauncher
{
    class Program
    {
        /*
            If you make .NET Core applications, they have to be launched like .NET blah.dll args here
            This is a convenience EXE file that launches .NET Core applications via name.exe
            Just rename the output exe to the name of the .NET Core DLL file you wish to launch
        */
        static void Main(string[] args)
        {
            var exePath = AppDomain.CurrentDomain.BaseDirectory;
            var exeName = AppDomain.CurrentDomain.FriendlyName;
            var assemblyName = exeName.Substring(0, exeName.Length - 4);
            StringBuilder passInArgs = new StringBuilder();
            foreach(var arg in args)
            {
                bool needsSurroundingQuotes = false;
                if (arg.Contains(" ") || arg.Contains("\""))
                {
                    passInArgs.Append("\"");
                    needsSurroundingQuotes = true;
                }
                passInArgs.Append(arg.Replace("\"","\"\""));
                if (needsSurroundingQuotes)
                {
                    passInArgs.Append("\"");
                }

                passInArgs.Append(" ");
            }
            string callingArgs = $"\"{exePath}{assemblyName}.dll\" {passInArgs.ToString().Trim()}";

            var p = new Process
            {
                StartInfo = new ProcessStartInfo("dotnet", callingArgs)
                {
                    UseShellExecute = false
                }
            };

            p.Start();
            p.WaitForExit();
        }
    }
}

6
Se hai intenzione di avere un file aggiuntivo comunque, perché non creare semplicemente un file bat che contienedotnet [nameOfExe].dll %*
Chet
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.