Run NuGet add in Visual Studio 2022 post build event - visual-studio

I've created a local NuGet feed for some testing. In an attempt to automate the process, I've tried to create a post-build event to execute the 'NuGet add' for the package. The NuGet add fails with:
Provided Nupkg file 'XXXXX\bin\x64\Debug\XXXXX.1.0.0.nupkg' is not
found.
However, when I look at the folder, the 'nupkg' file is where I expect it to be. I'm using the following command in the post-build event:
nuget add "$(ProjectDir)bin\$(Platform)\$(Configuration)\$(ProjectName).$(PackageVersion).nupkg" -Source "C:\XXXXX\NuGet Local Source"
Is this a problem with 'timing'?
How can I perform the 'NuGet add' in a post-build event?
I found How to run 'nuget add' as a post-build evnet in Visual Studio, but, I can't tell what I'm doing wrong.

After some more digging, I found a workaround. I found .Net Core 2.0 "Generate Nuget package on build" issue with Post-build events that mentioned using "Pack" as an 'AfterTargets'. The current build events tab does not offer 'Pack' as an option. So, the procedure I used was to fill in the post-build event, save the project and close it. Then, I edit the .csproj file and change this line in the file:
<Target Name="PostBuild" AfterTargets="Pack">
This allowed me to run the 'nuget' command from the post-build event.

Related

Is it possible to run a postbuildevent in an Azure Devops .yaml pipeline build event containing macros such as $(TargetPath)?

I'm trying to automatically rename the .dll resulting from VSBuild so it includes the version number. In order to do this I've tried to create a postbuild event in DevOps.
- task: VSBuild#1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:PostBuildEvent="rename $(TargetPath) $(TargetDir)$(TargetName).$(buildNumber)$(TargetExt)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
This post build event works fine when I put it in Visual Studio and run it locally. However, I don't want users to be able to change it, so I don't want to define it in Visual Studio but in the pipeline(.yaml) itself. On DevOps I get the following result:
PostBuildEvent:
rename $(TargetPath) $(TargetDir)$(TargetName).20221003.8$(TargetExt)
The system cannot find the file specified.
##[error]C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(5707,5): Error MSB3073: The command "rename $(TargetPath) $(TargetDir)$(TargetName).20221003.8$(TargetExt)" exited with code 1.
It seems as though the postbuild event macros, such as $(TargetPath), which are recognized in Visual Studio are not recognized when running the post build event through DevOps pipelines. Is this correct? If so, is there any way around it? I'd prefer not to hardcode anything since I want to reuse the pipeline for multiple repos/solutions with a variable number of projects and project names.
Thanks a lot!

Explanation on specific differences between my click once publish when done via command line and from Visual Studio

I am trying to understand why is my WindowsForm app publish behaving differently, when done via command line and via Visual Studio's Publish.
The differences are:
In my command line publish, a copy of the .exe is placed in the top-directory publish folder, while it is not there, when published via VS
In my command line publish, the .application file is missing in the [Application Files] folder, while it is there when published via VS
A screen shot illustrating the exposed above:
Anyone has any idea why does this happen ? I have tried playing with the publish settings, but still without success.
Below is what my command line statement looks like (ran via Jenkins):
Explanation on specific differences between my click once publish when done via command line and from Visual Studio
That because some features are done by Visual-Studio and not by the MSBuild command line. So the click-once-deployment behaves differently when it's executed from the command-line.
When you publish via command line, only Project.exe and Setup.exe are copied to the deployment folder. You can switch the deployment folder by property PublishDir:
msbuild "ProjectName.csproj" /target:publish /p:Configuration=Release;PublishDir=D:\TestPublishFolder
When you publish from Visual Studio, Visual Studio will do some more features, including Application Files folder and .application file into deployment folder.
If you want to have the same publish result as Visual Studio when you publish via command line, you can custom target to achieve it.
See ApplicationFiles folder missing when ClickOnce publish with command line for more detailed info.
Hope this helps.

.Net Core 2.0 "Generate Nuget package on build" issue with Post-build events

The new .NET Core 2.0 projects provide and easy and convenient way to create Nuget Package from the project output. Just click on the "Generate Nuget package on build" check box and it is done.
It works fine but I have an issue with Post-build events.
I want to copy all of the packages from a solution after each build to a specific folder. So I use the "Post-build event command line" with a script:
xcopy "$(ProjectDir)$(OutDir)..*.nupkg" "$(SolutionDir)..\WebServicePracticesNuget\" /Y /I
And sometimes it works fine sometimes not at all. So far my investigation concluded that the Nuget package creation is not part of the build process itself. So the script (sometimes) will triggered before the package was generated and it is unpredictable. My solution is to add some delay. Unfortunately "timeout x" is not working with Post-build events. So I used the fallback option:
ping 127.0.0.1 -n 4 > NUL
Which makes it almost reliable (~95%) but I think it is "poor man's" solution. And looks ridiculous in a Post-build event script. I have already reported this issue to the VS team. But not much comments or solution so far.
So my question is: does anybody have the same issue? Or any idea for a better solution then I have now?
Thanks.
The GeneratePackageOnBuild feature executes the Pack target after Build so the post build event will potentially run before the NuGet packages have been created. In VS 15.3+, when you create a post-build event, it will create a Target element in the project file. You can change the AfterTargets attribute on it to AfterTargets="Pack" to run after packing and not after the core .net build. But it is a bit of a fragile approach.
The pack target will respect the PackageOutputPath msbuild property, which is what dotnet pack's --output parameter would set.
Since xcopy only works on windows, the most versatile solution would be to use msbuild to set up the property during the build.
For example you could put a Directory.Build.props file next to the solution file (directory above all projects) with the following contents:
<Project>
<PropertyGroup>
<PackageOutputPath>$(MSBuildThisFileDirectory)nupkgs</PackageOutputPath>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
</Project>
This file will be automatically imported into all project files in the directory hierarchy blow this file and set the target directory for the generated .nupkg files to a folder named nupkgs next to the Directory.Build.props file. It also enables the "generate package build" feature for all projects that support it ("sdk-based" projects like .net standard / .net core libraries) so you don't have to set it up in VS or edit all project files.
You can configure msbuild task order inside the project file.

How can I automate updating NuGet packages and building a solution in Visual Studio

Here is my workflow.
Open Package Manager Console
Update-Package
Build Solution
Check into Plastic Source Control
Build in Teamcity
The problem is I keep forgetting to do #3! This is key because it updates my config files prior to check in. How can I set up a one click method to do 1-3? Or some kind of command line macro.
Have it defined in the 'Build Steps' in TeamCity instead. (under Configuration Settings)
Typically have one build step that would have
Runner Type: Command Line
Step Name: nuget restore (or anything you desire)
Run: Custom Script
Custom script: nuget.exe restore
If you add the necessary steps to TeamCity you wouldn't need to build them before you push into your source control.

Setting post-build event commands?

Is it possible to set a post-build in VS2013 and Multi-Device Hybrid Apps CTP3? I want to be able to copy the output APK to a different location.
You can use MSBuild Post build event to copy the apk from bin\Android\Debug to your custom location. You can add PostBuildEvent to project file to execute the copy command or can run task to copy apk from one location to another.
<ItemDefinitionGroup>
<PostBuildEvent>
<Command>copy source_apk_location target_apk_location</Command>
<Message>Making a copy of apk</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
To edit the project file go to solution explorer, under project node contextmenu click Unload Project --> Edit *.jsproj and after making the changes reload the project.

Resources