Repository navigation
Paket Pack not working with .exe files #3862
Description
Description
Paket pack command fails on projects that contain a .exe, with an error like:
Paket failed with ->
C:\Users\Micael\source\repos\ConsoleApp4\ConsoleApp4\bin\Release\netcoreapp3.1\ConsoleAp>p4.exe: bad cli header, rva 0
with the full error message on verbose mode being:
Paket failed with
-> C:\Users\Micael\source\repos\ConsoleApp4\ConsoleApp4\bin\Release\netcoreapp3.1\ConsoleApp4.exe: bad cli header, rva 0
StackTrace:
at ProviderImplementation.AssemblyReader.look@1727(ILModuleReader this, Int32 v, String n, Int32 i, Int32 pos) in D:\code\Paket\paket-files\fsprojects\FSharp.TypeProviders.SDK\src\AssemblyReader.fs:line 1728
at ProviderImplementation.AssemblyReader.ILModuleReader..ctor(String infile, ByteFile is, ILGlobals ilg, Boolean lowMem) in D:\code\Paket\paket-files\fsprojects\FSharp.TypeProviders.SDK\src\AssemblyReader.fs:line 1737
at ProviderImplementation.AssemblyReader.ILModuleReaderAfterReadingAllBytes(String file, ILGlobals ilGlobals) in D:\code\Paket\paket-files\fsprojects\FSharp.TypeProviders.SDK\src\AssemblyReader.fs:line 3619
at Paket.PackageMetaData.readAssembly(String fileName) in D:\code\Paket\src\Paket.Core\Packaging\PackageMetaData.fs:line 69
at Paket.PackageProcess.merge$cont@29(String buildConfig, String buildPlatform, FSharpMap2 specificVersions, ProjectFile projectFile, TemplateFile templateFile, TemplateFile withVersion, Unit unitVar) in D:\code\Paket\src\Paket.Core\Packaging\PackageProcess.fs:line 29 at Paket.PackageProcess.convertRemainingTemplate@193.Invoke(String fileName) in D:\code\Paket\src\Paket.Core\Packaging\PackageProcess.fs:line 203 at Microsoft.FSharp.Collections.Internal.IEnumerator.map@74.DoMoveNext(b& curr) at Microsoft.FSharp.Collections.Internal.IEnumerator.MapEnumerator1.System-Collections-IEnumerator-MoveNext()
at Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.takeOuter@274[T,TResult](ConcatEnumerator2 x, Unit unitVar0) at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable1 source)
at Paket.PackageProcess.Pack[a](String workingDir, DependenciesFile dependenciesFile, String packageOutputPath, FSharpOption1 buildConfig, FSharpOption1 buildPlatform, FSharpOption1 version, IEnumerable1 specificVersions, FSharpOption1 releaseNotes, FSharpOption1 templateFile, FSharpOption1 excludedTemplates, Boolean lockDependencies, Boolean minimumFromLockFile, Boolean pinProjectReferences, FSharpOption1 interprojectReferencesConstraint, Boolean symbols, Boolean includeReferencedProjects, FSharpOption1 projectUrl) in D:\code\Paket\src\Paket.Core\Packaging\PackageProcess.fs:line 221 at Paket.Dependencies.Pack[b](String outputPath, FSharpOption1 buildConfig, FSharpOption1 buildPlatform, FSharpOption1 version, FSharpOption1 specificVersions, FSharpOption1 releaseNotes, FSharpOption1 templateFile, FSharpOption1 workingDir, FSharpOption1 excludedTemplates, FSharpOption1 lockDependencies, FSharpOption1 minimumFromLockFile, FSharpOption1 pinProjectReferences, FSharpOption1 interprojectReferencesConstraint, FSharpOption1 symbols, FSharpOption1 includeReferencedProjects, FSharpOption1 projectUrl) in D:\code\Paket\src\Paket.Core\PublicAPI.fs:line 753
at Paket.Program.handleCommand@853-23.Invoke(ParseResults1 results) in D:\code\Paket\src\Paket\Program.fs:line 853 at Paket.Program.processWithValidationEx$cont@42[a](Boolean silent, FSharpFunc2 commandF, a result, Unit unitVar) in D:\code\Paket\src\Paket\Program.fs:line 43
at Paket.Program.processWithValidationEx[a](FSharpFunc2 printUsage, Boolean silent, FSharpFunc2 validateF, FSharpFunc`2 commandF, a result) in D:\code\Paket\src\Paket\Program.fs:line 35
at Paket.Program.handleCommand(Boolean silent, Command command) in D:\code\Paket\src\Paket\Program.fs:line 853
at Paket.Program.main() in D:\code\Paket\src\Paket\Program.fs:line 934
For reference I tried this with a computer without a D: drive and it still showed as it trying/getting files from D:
Repro steps
-
Create an F# console project with visual studio on windows (visual studio might not be required but windows is)
-
Install paket on project and convert from nuget to paket
-
Create paket.template file in the project ConsoleApp folder and add this to it
type project -
Build project in Release mode.
-
Run the following command:
dotnet paket pack nugets --version 1.0.0 -v
Alternative skip step 1 to 3 by cloning this git https://github.com/MicaelMor/PaketPackExeError
Expected behavior
Paket should create a .nupkg file on the nugets folder with the name of the project and version provided.
Actual behavior
Paket fails with error
NameOfExecutable.exe: bad cli header, rva 0
Known workarounds
Using .Net SDK command dotnet pack works, but ofc this bypasses Paket.
Other potentially relevant information
The Pack command works fine with a library type project (which ofc has no .exe file), so it is quite likely I am just doing something wrong here,
Fails also on a C# project.
Activity
allykzam commentedon Jun 11, 2020
Coincidentally, I ran into this yesterday as well while trying to see if I could migrate a work project to .NET Core. Seems that this is related to the fact that when you build a .NET Core application and get an executable file, it isn't actually a .NET binary, so much as launcher of some kind; your program actually lives in the
NameOfExecutable.dllnext to the executable.I tried using the latest alpha of Paket (
6.0.0-alpha028at the moment) and had the same results. Unfortunately, for my purposes,dotnet packdoes not work, because it omits the executable and throws my application into thelibdirectory of the resulting NuGet package, rather thantools.MicaelMor commentedon Jun 11, 2020
I'm new to .Net Core publishing, in fact the reason why I ran into this problem is basically the same as yours, but I don't believe you are supposed to package the .exe files or any file that isn't necessary to the program (like debug symbols and so on) with the nuget.
The idea is that since .net core projects are multiplatform you need to choose what packaging and distribution you want to use for each platform you are publishing to.
For windows distribution you could for example package it with nuget and then use something like https://github.com/Squirrel/Squirrel.Windows which takes that nuget and creates an installer for it (you also get an updater if you modify your project and so on), being that there are ofc alternatives like Wix and InnoSetup which are to my knowledge supported by F# Fake.
That being said haven't used any of the methods mentioned above yet, so I could be saying something that isn't accurate, so far have published only 1 .net core app to Windows, and that was using the Visual Studio option to Publish, which essentially puts the necessary files to execute the application into a folder, and if you copy that folder to the Windows machine you want to run it, the application should run just fine.
If you positively need to have the executable inside the .nupkg file, like if for some reason you can only distribute the application using nuget, it would be possible to do so, these files are just renamed .zip files that follow a certain structure, so you could in theory have some build process that after it runs the dotnet pack command, opens the .nupkg file and copies the .exe and what ever other files you need/want into that .npukg.
allykzam commentedon Jun 11, 2020
I'm not new to publishing .NET Core projects, but the project in question has quite a bit of workflow around it that requires the executable to be packaged the same way it was when targeting .NET Framework. I'm aware of how the NuGet package format works, but currently Paket is the build process that handles this. I could certainly write my own code for packaging the project, but then I also wouldn't need to use
dotnet pack.Regardless of how the package is being used, I wouldn't think Paket is intended to crash and burn when asked to package a project.
allykzam commentedon Jun 11, 2020
I was able to locally modify Paket enough to bypass this issue by commenting out these two lines, removing associated code that used the values, and adding the missing data to my
paket.template. I also had to addV3_1and supporting code to theDotNetCoreAppVersiontypedef so it would recognizenetcoreapp3.1, but it looks like that's already been done in master.In production Paket builds, I'd assume that the
PackageProcess.mergefunction would fall back to reading the.dllwhen packaging a .NET Core or .NET 5+ application, rather than examining the.exefor CIL data. Since self-contained executables are created bydotnet publishseparately from the original build, the.dllshould always be there for Paket to reference - or at least, I haven't yet run into a .NET Core project where this wasn't the case.kowalgta commentedon Dec 14, 2021
I had the same issue and in my case removal of
<OutputType>Exe</OutputType>from the fsproj file fixed the problem. Weirdly output is still*.exeand looks identical to the previous one.flibustier7seas commentedon Jul 11, 2024
Any updates?
I encounter the same issue when I attempt to pack my dotnet tool.