VsixSignTool fails without any output on Windows Server 2022 - vsix

I am establishing a new Azure DevOps build server on an Azure VM running Windows Server 2022. Running the VsixSignTool fails in the build pipeline on this server.
I am replacing an old build server where this pipeline runs correctly. The old build server has Visual Studio 2019 and 2022 Community installed; the new build server only has the Visual Studio Build Tools.
Setup
Visual Studio Build Tools 2022 (17.4.1) and other dependencies like WIX toolset etc are all installed on the server. As part of the Visual Studio Build Tools, the following components are installed (exported from the Visual Studio Installer):
{
"version": "1.0",
"components": [
"Microsoft.VisualStudio.Component.Roslyn.Compiler",
"Microsoft.Component.MSBuild",
"Microsoft.VisualStudio.Component.CoreBuildTools",
"Microsoft.VisualStudio.Workload.MSBuildTools",
"Microsoft.VisualStudio.Component.TestTools.BuildTools",
"Microsoft.Net.Component.4.8.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Component.Windows11SDK.22621",
"Microsoft.VisualStudio.Component.NuGet.BuildTools",
"Microsoft.VisualStudio.Web.BuildTools.ComponentGroup",
"Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
"Microsoft.VisualStudio.Component.TypeScript.TSServer",
"Microsoft.Net.Component.4.8.TargetingPack",
"Microsoft.Net.ComponentGroup.4.8.DeveloperTools",
"Microsoft.NetCore.Component.Runtime.6.0",
"Microsoft.NetCore.Component.Runtime.7.0",
"Microsoft.NetCore.Component.SDK",
"Microsoft.VisualStudio.Component.DockerTools.BuildTools",
"Microsoft.Component.ClickOnce.MSBuild",
"Microsoft.VisualStudio.Wcf.BuildTools.ComponentGroup",
"Microsoft.VisualStudio.Component.WebDeploy",
"Microsoft.Net.Component.3.5.DeveloperTools",
"Microsoft.VisualStudio.Workload.WebBuildTools",
"Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools",
"Microsoft.Net.Component.4.6.TargetingPack",
"Microsoft.VisualStudio.Component.VSSDKBuildTools",
"Microsoft.VisualStudio.ComponentGroup.VisualStudioExtensionBuildTools.Prerequisites",
"Microsoft.VisualStudio.Workload.VisualStudioExtensionBuildTools",
"Microsoft.VisualStudio.Component.SQL.SSDTBuildSku",
"Microsoft.NetCore.Component.Runtime.5.0"
]
}
One of the projects in my solution is a VSIX package. The project has a PackageReference to the current version of the VsixSignTool:
<PackageReference Include="Microsoft.VSSDK.Vsixsigntool">
<Version>16.2.29116.78</Version>
</PackageReference>
and it has an afterbuild target to sign the VSIX package:
<PropertyGroup>
<VsixSignTool>$(NuGetPackageRoot)microsoft.vssdk.vsixsigntool\16.2.29116.78\tools\vssdk\vsixsigntool.exe</VsixSignTool>
<VsixSignCommand>$(VsixSignTool) sign /f $(SIGN_CERTIFICATE) /p $(SIGN_PASSWORD) /sha1 $(SIGN_CERT_HASH) /fd sha256 /t $(SIGN_TIMESTAMPSERVER)</VsixSignCommand>
</PropertyGroup>
<Target Name="AfterBuild" DependsOnTargets="CoreCompile" Condition="Exists('$(SIGN_CERTIFICATE)')">
<Message Text="Signing $(TargetVsixContainer)" />
<Exec Command="$(VsixSignCommand) $(MSBuildProjectDirectory)\$(TargetVsixContainer)" />
</Target>
Problem
When the pipeline runs, it fails when attempting to sign the package. This is the output (slightly obfuscated):
"C:\Users\(AzureDevOpsAgentUser)\.nuget\packages\microsoft.vssdk.vsixsigntool\16.2.29116.78\tools\vssdk\vsixsigntool.exe sign /f (path to pfx file) /p (the password) /sha1 (the certificate hash) /fd sha256 /t (timestamp server) (path to newly built vsix file)" exited with code -1073741515.
The Azure DevOps Agent user is local administrator on the build server.
Apart from the fact that it fails, this all looks good. When I connect to the build server, the vsixsigntool.exe is indeed in the expected location. All options to the vsixsigntool are correct. In fact, I temporarily installed the OpenVsixSignTool and could use this from powershell to sign the vsix with the exact same options. So, the certificate, password, hash etc are all correct and work. A side note: I would prefer to stick to the official vsixsigntool and avoid shifting to the OpenVsixSignTool.
Trying to run the vsixsigntool by hand from an elevated PowerShell does not do anything at all. It does not sign the vsix and it gives absolutely no output whatsoever. As a matter of fact, even if I give the vsixsigntool utter rubbish as options, it just completes with absolutely no information or errors. Here a copy/paste from PowerShell (elevated):
PS C:\Users\(Azure DevOps Agent User)\.nuget\packages\microsoft.vssdk.vsixsigntool\16.2.29116.78\tools\vssdk> .\vsixsigntool.exe /absolute /rubbish /for /you mate
PS C:\Users\(Azure DevOps Agent User)\.nuget\packages\microsoft.vssdk.vsixsigntool\16.2.29116.78\tools\vssdk>
It just silently runs with bad input and gives no information at all. Nothing in the event log. I am at a total loss.
What am I missing here? Any help greatly appreciated!

Related

MSBuild Running Slow Called from PowerShell Script (Visual Studio 2019)

I set up a new TFS Build Server recently and I'm investigating some extended time periods during the build process. One of those periods is the recompiling of our Selenium test .dll. First, the packages are restored via MSBuild, which is fine. Then, the script hangs for about 10 minutes, while the .dll is actually compiled.
This worked fine on our Visual Studio 2017 Build Server, (took a few seconds to compile I believe) but seems problematic with 2019.
Here's the code. Am I missing an MSBuild parameter or two?
$msbuild = """C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe"""
# Rebuild the Test source .dll...
Write-Host "********** Running UI Tests **********"
# Restore Selenium packages...
Write-Host "********** Restoring Selenium Packages **********"
&"C:\Nuget.exe\Nuget.exe" restore $source\Development\12.0\Web\MyAppWeb\MyCo.SeleniumUITest\MyCo.SeleniumUITest.sln -DisableParallelProcessing
Write-Host "********** Selenium Packages Restored **********"
# Changes for new MSBuild....
$projfile = "$source\Development\12.0\Web\MyAppWeb\MyCo.SeleniumUITest\MyCo.SeleniumUITest.sln"
try
{
start-process $msbuild -ArgumentList #($projfile,'/t:Rebuild','/p:configuration=Release') -Wait
Write-Host "********** Selenium .dll compiled successfully! **********"
}
catch
{
Write-Host $_.Exception.Message
exit 1
}
Any Help Appreciated! If this should go in the PowerShell forum, let me know. I thought TFS/MSBuild would be the correct place as I'm hoping its just a parameter or call tweak.
MSBuild Running Slow Called from PowerShell Script (Visual Studio 2019)
State:
(It is difficult to give an accurate answer to this question of operating efficiency. There are many reasons for the problem, most of which are related to the environment, making it difficult for us to reproduce it. So we could not give the direct correct answer for this issue, we can only give you some troubleshootings. In order to avoid losing contact in the round-trip comments, I post those troubleshootings as answer instead of comments.)
First, use the script with Azure devops service instead of the TFS Build Server 2019, to check if this issue still occurred on the Azure devops service, if this issue also occurred on the Azure devops service, that mean this issue should not related to the TFS, more related to the MSBuild/environment/powershell scripts.
Second, use the build in task nuget restore and msbuild task instead of the powershell scripts, to check if you have this issue, if also have this issue, this issue should not related to the scripts. If not, this issue should related to the scripts. We need to check if this scripts need to update since we use the different TFS server.
Third, Check the powershell version in the Visual Studio 2017 Build Server and Visual Studio 2019 Build Server, make sure they use the same version.
If you still could not find the reason, you could enable the debug log and share the log about the hangs to us, so that we could get some more info.
Hope this helps.
I moved the MSBuild scripted tasks out to Build Definition tasks to remove the slowness. I did not determine the cause of the hang when MSBuild was called via the PowerShell script.
The later issue of trying to publish via a .proj file was solved when I noticed I was using a Visual Build task instead of the more appropriate MSBuild task.
One thing to note when using the MSBuild step. If pointing to a .proj file and compiling for Any CPU, set it in the Task as AnyCPU with no space in between.

How to Deploy a .Net web app to Azure using Powershell

I have a "Web app" in Azure to which I deploy/publish a .Net web application using Visual Studio. (Build --> Publish), and it works.
I want to be able to deploy/publish my application using a Powershell script. I got the following script to work for the build portion:
CMD> "c:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe" WebApplication1.sln
To make it also deploy, I need to add a few parameters:
CMD> "c:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe" WebApplication1.sln /p:DeployOnBuild=true /p:PublishProfile="C:\Users\jgodse\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1\Properties\PublishProfiles\jg-7-web-app-1 - Web Deploy.pubxml" /p:Configuration=Release
I got an error:
Build FAILED.
"c:\Users\jgodse\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1.sln" (default target) (1) ->
"c:\Users\jgodse\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1\WebApplication1.csproj" (default target) (2) ->
(MSDeployPublish target) ->
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.targets(4295,5): msdeploy error ERROR_USER_UNAUTHORIZED: Web deployment task failed. (Connected to the remote computer ("jg-7-web-app-1.scm.azurewebsites.net") using the Web Management Service, but could not authorize. Make sure that you are using the correct user name and password, that the site you are connecting to exists, and that the credentials represent a user who has permissions to access the site. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_USER_UNAUTHORIZED.) [c:\Users\jgodse\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1\WebApplication1.csproj]
0 Warning(s)
1 Error(s)
I am obviously missing my Azure credentials (seeing as Visual Studio was able to capture them), and I am also not running in Powershell.
So I took the entire command and put it into a file called deploy.bat, opened up a Powershell window and did the following:
PS> Login-AzureRmAccount
(I typed in my user/password in the GUI popup).
PS> cmd /c .\deploy.bat
The build was fine, but I got the same error when trying to publish. I guess that the Azure credentials did not carry through when shelling out to the CMD program.
How do I use Powershell to call MSBuild on my .Net project to publish to an Azure web app?
You can use your existing .pubxml file but you need the password in order to be able to deploy. There are several ways to get it. The most obvious one is to get it from the portal by navigating to the blade of you Web app and then clicking on "More" and finally on "Get publish profile"
This file contains all sorts of data but the one that you need is called userPWD - this is the password that you need to use. Copy the password and add it to your MsBuild command:
CMD> "c:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe" WebApplication1.sln /p:DeployOnBuild=true /p:PublishProfile="C:\Users\jgodse\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1\Properties\PublishProfiles\jg-7-web-app-1 - Web Deploy.pubxml" /p:Configuration=Release /p:Password="Value of userPWD"
Obviously storing this value in your build scripts is not recommended. What you could do is download the publish settings using Powershell (Get-AzurePublishSettingsFile), extract the userPWD value, pass it to MsBuild to publish your app, and finally clean everything up.
There are various ways to implement you build infrastructure and what I have proposed might not be the best solution for you but it is up to you to experiment and decide what works best for you.
Some resources:
Automate Everything (Building Real-World Cloud Apps with Azure) - This one uses ASM instead of Resource Manager but you can easily tweak it to use ARM
Using Windows PowerShell scripts to publish to dev and test environments
Hope this helps.

TFS - Run Powershell script against package before Deployment

I currently have a CI Setup in TFS 2013 which does the following
Pulls code down from Git on every commit to a branch
Builds the Solution
Runs N-Unit Tests Against the solution
Runs Jasmine Front-end Tests against the javascript
Deploys on success via WebDeploy to chosen server.
I have now managed to install Grunt and NodeJS on the server to do some manipulation of the Javascript between steps 5-6. Does anyone have any advice on how this might be done?
I've tried post-tests scripts to minify the javascript successfully on both the src and bin/_PublishedWebsites directory but this does not seem to persist over to the deployment server. And infact, the _PublishedWebsites route puts the build folder in an undeletable state due to maxmimum character limits on Windows files (argh).
You should switch over to using Release Management for Visual Studio 2013 (works with 2012 as well). This allows you to parameterize your release and push the same output through multiple environments. Very configurable and even makes sure that the tools you need end up on the server that you are deploying to. Supports Puppet, Chef, DSC, and create your own.
http://nakedalm.com/installing-release-management-server-tfs-2013/
And for an overview: http://nakedalm.com/building-release-pipeline-release-management-visual-studio-2013/
I managed to get this working with the addition of two extra steps to the pubxml file used for the deployment.
First, i added a dependency powershell script which ran NPM install and grunt tasks.
<PipelineDependsOn>
CustomBeforePublish;
$(PipelineDependsOn);
</PipelineDependsOn>
<Target Name="CustomBeforePublish">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -file Pre_Deploy_Javascript_Build.ps1 $(ProjectDir)"/>
</Target>
Following this. I had now created additional files which did not exist in the project. I had to now ensure that these were published. To do this, i added another step.
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CopyMinJSFiles;
$(CopyAllFilesToSingleFolderForMsdeployDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn >
<Target Name="CopyMinJSFiles">
<ItemGroup>
<_MinJSFiles Include="$(ProjectDir)\App\*.js" />
<FilesForPackagingFromProject Include="%(_MinJSFiles.Identity)">
<DestinationRelativePath>App\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>

TFS Web Deploy doesn't execute via Build but executes locally?

I have a solution that I am trying to get TFS 2010 to deploy after it builds.
When I run the following msbuild command locally, it deploys fine:
msbuild C:\Path\to\Solution.sln /p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=True /p:MSDeployPublishMethod=WMSVC /p:MSDeployServiceUrl=https://[Server]:8172/MsDeploy.axd /p:DeployIisAppPath="TestSite" /p:UserName=Domain\Username /p:Password=NotTheRealPassword /P:AllowUntrustedCertificate=True
However, when I stick those same options into the TFS 2010 build MS Build arguments:
...it doesn't appear to execute anything.
The build finishes correctly:
But I see nothing in the entire log file related to deployment, etc. It's as if the parameters were never even passed in to MSBuild from TFS.
The MSBuild Command Being Called by TFS
The log has it as (scrubbed sensitive data): C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe /nologo /noconsolelogger "C:\Builds\1\[Scrubbed]\Daily6am\Sources\[Scrubbed].sln" /m:1 /fl /flp:"logfile=C:\Builds\1\[Scrubbed]\[Scrubbed]\Sources\[Scrubbed].log;encoding=Unicode;verbosity=normal" /p:SkipInvalidConfigurations=true /p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=True /p:MSDeployPublishMethod=WMSVC /p:MSDeployServiceUrl=https://[Scrubbed]:8172/MsDeploy.axd /p:DeployIisAppPath="TestSite" /p:UserName=[Scrubbed]\farmservice /p:Password=[Scrubbed] /p:AllowUntrusted=True /P:AllowUntrustedCertificate=True /p:OutDir="C:\Builds\1\[Scrubbed]\[Scrubbed]\Binaries\\" /p:Configuration="Debug" /p:Platform="Any CPU" /p:VCBuildOverride="C:\Builds\1\[Scrubbed]\[Scrubbed]\Sources\[Scrubbed].sln.Any CPU.Debug.vsprops" /dl:WorkflowCentralLogger,"C:\Program Files\Microsoft Team Foundation Server 2010\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;BuildUri=vstfs:///Build/Build/23;InformationNodeId=4504;TargetsNotLogged=GetNativeManifest,GetCopyToOutputDirectoryItems,GetTargetPath;TFSUrl=http://[Scrubbed]:8080/tfs/[Scrubbed]_Collection;"*WorkflowForwardingLogger,"C:\Program Files\Microsoft Team Foundation Server 2010\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;"
Questions
How can I get TFS to tell MSBuild to build the deployment?
How can I verify whether the parameters were even passed in?
How can I correctly read the logs to know if this has taken place or not?
Assistance on any of these would be much appreciated.
I was able to find the answer on a SO question from a bit ago :)
According to the answer at this SO Question, #marvc1 (credit where it's due) suggested copying the following files:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications
I had copied WebApplications, but not Web. Copying web resolved the issue.

Is there a system that I can use to update my projects on my VPS?

Hey guys, So I recently got a VPS, just so I can start gaining experience. But I'm looking for a service/program where I can code on my PC, then when I'm done, I run a script or do a command or something to have it updated to my VPS.
I thought I was looking for Git, but apparently git does not do what I'm looking for.
Any suggestions?
Windows or Linux?
On Windows, there's a host of tools.
First of all you code. Visual Studio is the most common. You get a sln-file and a batch of *.*proj-files.
When talking about deploying to remote servers, often a continuous integration server is used. We are using TeamCity (http://www.jetbrains.com/teamcity/). Download it locally, install and create a new project, selecting the "SLN-runner". Point it to the sln file of yours.
When you want the deployment part working, create a small build file such as "MyProj.build", that contains something along the lines of
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="BuildProject"
InitialTargets="CheckRequiredProperties"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0">
<Target Name="BuildProject">
<Message Text="Starting $(Configuration) build. Web site publish location $(OutputWebSite)" />
<MSBuild Projects="$(SolutionPath)"
Targets="Build"
Properties="BuildOutputPath=$(BuildOutputPath);
BuildOutputPathBin=$(BuildOutputPathBin);
Configuration=$(Configuration);
BuildConstants=$(BuildConstants);
MSBuildTargets=$(MSBuildTargets);
TargetFrameworkVersion=$(TargetFrameworkVersion);
TargetFrameworkProfile=$(TargetFrameworkProfile)">
...
Where SolutionPath points to your sln-file.
You will then update the TeamCity config to point to MyProj.build instead, using the MsBuild runner.
Then you need a way of having TeamCity upload everything to your server. Powershell is a nice scripting environment that can run .Net code, but you'd be invoking it through MsBuild...
Something like this
http://community.bartdesmet.net/blogs/bart/archive/2008/02/16/invoking-powershell-scripts-from-msbuild.aspx
And then you can script with MsDeploy accross to your server:
http://blogs.iis.net/jamescoo/archive/2008/08/21/using-msdeploy-in-powershell.aspx
"rsync" or "scp" tools may be useful