Zip files after build completes in Visual Studio - c#

I have a requirement where I need to zip some files after I build a solution file.
Could this be achieved automatically once I build my project in Release/Debug mode?

Using powershell, only when doing Release build:
if $(ConfigurationName) == Release (powershell Compress-Archive -Path '$(TargetDir)*.dll', '$(TargetDir)*.pdb', '$(TargetDir)*.config' -DestinationPath '$(SolutionDir)PublishOutput\YourNameHere.zip' -Force)
It only zips the dll, pdb and config files.
-Force is used to overwrite the zip file on each build.

Usually I don't put stuff like creating zip files, installers, NuGet packages etc. into my actual project.
Why? Because when I put it there, it gets executed each time I'm building the project in Visual Studio, for example when I'm debugging.
But zip files, installers etc. are only needed when I do a release, so I don't want to wait for them to be re-generated each time I press F5 in Visual Studio.
To make a release, I usually create a batch file that executes a MSBuild project file, which creates everything that's necessary to make a release.
IMO creating a ZIP file belongs into that MSBuild project file as well.
You can find all the information you need in these two previous answers by me:
How to create a basic batch file and MSBuild project file
(the actual question there is about building an installer with WiX, but in the beginning I'm creating a MSBuild project file)
How to create a ZIP file with MSBuild Community Tasks
Plus, here's an example MSBuild project file from one of my projects, which does the following:
build the project
run unit tests
create two release folders with binaries (one DLL and one .exe)
create two zip files, one for each of the folders with binaries
create a NuGet package for the DLL
create a ClickOnce setup for the .exe
automatically set the correct version number for everything
The great thing about this approach is that I can make a release, which includes everything I have just listed, with a single click (running a batch file).
Creating all this stuff takes some time, but as it's not part of the Visual Studio solution, it doesn't run each time I do a build in Visual Studio - I only execute it when I really need it.

Go to the properties of your project and in the 'Build Events' tab write your commands in the Post-Build event area. The commands there execute just like (or as) a Cmd batch file.
Also: there ara a few 'makros' available there, which may help referring to the project folders etc.. Check it out.
And, to add to Jason's comment, you can also call the batch file itself as the post-build command.
(One caveat about post-build events: They are executed after the build. But if you have CSC targets they are compiled after the build and after the post-build events. If you want to e.g.copy the output files of these CSC targets you need to do it in a post-compile event.)

This worked for me:
if $(ConfigurationName) == Debug (powershell -Command "Get-ChildItem -Path '$(TargetDir)publish' -Recurse|Compress-Archive -DestinationPath '$(SolutionDir)PublishOutput\$(ProjectName)-$(ConfigurationName).zip' -Force")

Right Click on Project=> Select Properties
Click on BuildEvent
Add below Code in post-Build event command Line
if exist $(AssemblyName).zip ( Del $(AssemblyName).zip)
powershell.exe -command Compress-Archive -Path $(AssemblyName).dll, *dll -DestinationPath $(AssemblyName).zip
It will Generate the zip file of all .dll in "bin/release" folder

I could not get Build Events to work so I modified the MS Build configuration file - the *.csproj file. It's actually not black magic and documented by MS here: https://learn.microsoft.com/en-us/visualstudio/msbuild/build-process-overview?view=vs-2022
You have to Unload your project in VS, modify the *.csproj file (VS will load it automatically when you unload the project) and then Reload the project from Solution Explorer.
Here is a snipped from the Build target (in this case it only zips the application files):
<Target Name="Build">
<CreateItem Include="app\**">
<Output ItemName="ApplicationFiles" TaskParameter="Include" />
</CreateItem>
<Zip ZipFileName="out\$(AssemblyName).zip" WorkingDirectory="$(MSBuildProjectDirectory)\app" Files="#(ApplicationFiles)" />
</Target>
This Zip 'task' of MS Build seems to be much faster than the PowerShell Compress function.
Here is a list of available MS Build 'tasks':
https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-task-reference?view=vs-2022
There is also an MS Build task that will zip an entire directory including subdirectories, like so:
<ZipDirectory SourceDirectory="dist" DestinationFile="out\$(AssemblyName).zip" />

Related

Can't run code using the 'dotnet' run command in Visual Studio. "Couldn't find a project to run"

I have tried running this program a million times. I am in the correct directory, C:\Users\DylanT\Desktop\Project, and the file is just named Program.cs. When I use the dotnet run command, I get the error
Couldn't find a project to run. Ensure a project exists in C:\Users\DylanT\Desktop\Project, or pass the path to the project using --project.
I only have one folder named "Project" and the only file inside the folder is the program, so there shouldn't be any reason it shouldn't execute the program. How can I do it?
The .NET Build System does not work with loose .cs files (or F# or VB.NET for that matter); it needs at least a project. You can generate a project file by using dotnet new <template> as follows:
md MyProject
cd MyProject
dotnet new console
Now you have a folder MyProject, containing MyProject.csproj and a default Program.cs file.
To run it, you can now do
dotnet run
This will open and read the .csproj file, and it will use the settings and properties that are inside it to build all the source files into an executable, and then it will run that.
As you can read here you have to call the command on a .csproj-file. You simply can not call it on a source code file.

Adding pre-build commands to copy files to a project in VS 2017

I have a folder which has a bunch of scripts in it. These are NOT in a project or solution.
What I need to do is using the pre-build event in VS, is copy these files using xcopy into the debug folder of a project.
I have worked out how to do this with stuff inside a solution or project. But trying to do it with external files is eluding me
Can anybody point me in the right direction please?
Projects have a Pre-build event that can be used for doing what you are looking to do.
You can find this in the Project Properties in the Build Events section.
Try the command as per:
c:\windows\system32\xcopy D:\source\*.* "$(TargetDir)" /s /e
For a list of the Build Parameters see MSDN: https://msdn.microsoft.com/en-us/library/42x5kfw4.aspx
The quotes around the $(TargetDir) are important if you have a space in any of your folder/file names

When I create a clickonce project using msbuild, the executable is double up. Why?

I have a WinForms project. When I publish it to click once using the visual studio publish option, I get pretty much what I would expect in the main folder - the Application Files, the EULA (which I add as a dep), the Application Manifest (myapp.UI.winforms.application) and my setup.exe
When I publish the exact same project from the command line with MSBuild I get the identical output, except the main application is now included twice - one at Application Files => version => myapp.UI.winforms.exe, but also in the main folder as per attached.
Everything works, I just don't really want to be adding double ups to the build.
Strangely, when I build with VS, I get two copies of myapp.UI.winforms.application - one in the main directory and one in Application Files => version => myapp.UI.winforms.application, but I don't get this when I build from the command line. I would far rather this were the double up file if one needs to be though because it is only 3kb vs 9Mb
In both cases the double up files are identical.
The command I use to run the build is;
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release
/p:PublishDir="C:\Users\me\Documents\Deploy\web\\

How to create an .exe file with external .dll?

I've tried almost everything found on the net to solve this problem, but it just seems to not work!
I created a .exe file from a visual studio 2013 project using wpf. I want this file to create pdfs, so I added as references .dlls concerning itextsharp.
Everything works fine if I keep my .exe file in the same directory as itextsharp's .dlls. But when I try to run the .exe outside, the program crashes.
I've tried to use ILMerge, I read it is pretty good to merge .exe and .dll, but when I double-click one the newly-created .exe file nothing happens.
The command I wrote in my command window, once in the ILMerge folder, was:
ilmerge C:\Users\Utente\Desktop\PDFWriter.exe C:\Users\Utente\Desktop\itextsharp.dll /out:C:\Users\Utente\Desktop\merged.exe /target:winexe /targetplatform:"v4,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5"
Thanks for your help!
Use Fody.Cosura project for merging. A lot nice to work with than ILMerge.
All you need to do is to install nuget package in your project:
PM> Install-Package Costura.Fody
And you are pretty much done. You can adjust the configuration, but that is not always required as just installing the package does the bulk for you.

ILMerge and Visual Studio and PostEvent build

Met a problem. VS2013 doesnt allow to merge files into same exe which created after build.
"$(SolutionDir)ILMerge\ILMerge.exe" "$(TargetPath)" "$(SolutionDir)..\Lib\Soft.dll" /out:"$(TargetPath)"
My idea was to merge built exe with 1 dll (uses in references) and to have the same exe filename.
I can do this without any problem apart of VisualStudio.
But i prefer to do merge exactly in post-build event, and do not change the exe filename.
Is there some workaround ?
PS. I dont want to have a dll in resources, because its used a lot, and its easy to have as usual in references

Categories