I'm currently looking into re-jigging our hacked together deployment system with something a little more elegant - Octopus. In doing so, I'm trying to get VS to package up a project when a release build is run. Well I have this fancy powershell script written and working, but when I try to EXEC from the msbuild script, visual studio just hangs!
At first I suspected the way stuff was being escaped in the shell, but I simplified it ridiculously, and it still freezes.
Here's the relevant MsBuild code:
<PropertyGroup>
<PowerShellExe Condition=" '$(PowerShellExe)'=='' ">
%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe
</PowerShellExe>
</PropertyGroup>
<Target Name="AfterBuild" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Exec Command="$(PowerShellExe) -NonInteractive -executionpolicy Unrestricted -command get-childitem" />
</Target>
All it should do is give a directory listing. Calling this from cmd.exe works fine:
C:\Users\smithj>%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe -noninteractive -executionpolicy unrestricted -command dir
Trying this:
msbuild Solution.sln /p:Configuration=Release
Gets me this:
AfterBuild:
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\\tf.exe" che
ckout Package.nuspec
Package.nuspec
%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe
-NonInteractive -executionpolicy Unrestricted -command dir
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.
After that, it just hangs forever. Any suggestions are welcome.
Not sure you're going to like the answer.
After a bit of play, it seems to be about the expansion of the property group. You put a new line in the value of PowerShellExe.
This works fine:
<PropertyGroup>
<PowerShellExe Condition=" '$(PowerShellExe)'=='' ">$(WINDIR)\System32\WindowsPowerShell\v1.0\powershell.exe</PowerShellExe>
</PropertyGroup>
<Target Name="AfterBuild">
<Exec Command="$(PowerShellExe) -NonInteractive -executionpolicy bypass -command "&{get-childitem}"" />
</Target>
Try:
<Exec Command='$(PowerShellExe) -NonInteractive -executionpolicy Unrestricted -command "& {Get-ChildItem}"' />
Related
I have an installer project that is generating .msi on build. In the pre-build event, I am calling Confuser.CLI.exe to obfuscate code, but exe is working asynchronous and taking too much time, and the compiler is finished before exe, so I have .msi with old DLLs and then when .msi is generated, new DLLs overwrite old ones. I even tried with the post-build event, but I get the same result.
Inside installer project - .wixproj, I put 2 targets that will execute different commands:
<Target Name="ConfuserExScript" AfterTargets="CopyReferencedProjects">
<Exec Command="Powershell.exe -executionpolicy remotesigned -File "$(SolutionDir)Installers\Scripts\Build\PostBuild_RunConfuserEx.ps1" "$(SolutionDir)\"" />
</Target>
<Target Condition=" '$(ConfigurationName)' == 'ReleaseDC' " Name="Obfuscator" AfterTargets="ConfuserExScript">
<Exec Command="$(SolutionDir)Installers\ConfuserEx\Confuser.CLI.exe $(ProjectDir)ConfuserOutput.crproj" />
</Target>
The first one is gathering DLLs and creating crproj file for ConfuserEx, the second one is running Confuser.CLI.exe and obfuscating code.
Important thing is that I use afterTargets so the second line is executed after the first one is finished.
ClickOnce publish with IDE works normal.
When trying to publish via MSBuild command line
%MSBUILD% /target:publish /p:Configuration=Release;PublishDir="REMOTE_FOLDER"
only Project.exe and Setup.exe copies.
When try to %MSBUILD% /target:publish command then all necessary files copies to the build\app.publish folder
How do I publish via command line same ClickOnce settings which IDE uses
PS this question similar but not the same
How do I publish via command line same ClickOnce settings which IDE uses
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.
If you want to publish via command line same ClickOnce settings which IDE uses, you can use a custom target to achieve it. Edit your project(csproj) file (right click project node -> unload project -> edit xxx.csproj) and add the following code in it:
<PropertyGroup>
<ProjLocation>D:\Test\Projects\ClickOncePublish\ClickOncePublish</ProjLocation>
<ProjLocationReleaseDir>$(ProjLocation)\bin\Debug</ProjLocationReleaseDir>
<ProjPublishLocation>$(ProjLocationReleaseDir)\app.publish</ProjPublishLocation>
<DeploymentFolder>D:\Test\Publish\</DeploymentFolder>
</PropertyGroup>
<Target Name="Test" DependsOnTargets="Clean">
<MSBuild Projects="$(ProjLocation)\$(ProjectName).csproj"
Properties="$(DefaultBuildProperties)"
Targets="Publish"/>
<ItemGroup>
<SetupFiles Include="$(ProjPublishLocation)\*.*"/>
<UpdateFiles Include="$(ProjPublishLocation)\Application Files\**\*.*"/>
</ItemGroup>
<Copy SourceFiles="#(SetupFiles)" DestinationFolder="$(DeploymentFolder)\" />
<Copy SourceFiles="#(UpdateFiles)" DestinationFolder="$(DeploymentFolder)\Application Files\%(RecursiveDir)"/>
</Target>
<Target Name="Clean">
<Message Text="Clean project" />
<MSBuild Projects="$(ProjLocation)\$(ProjectName).csproj"
Properties="$(DefaultBuildProperties)"
Targets="Clean"/>
</Target>
Then you can build the project with the MSBuild command line:
msbuild /target:test
After execute the build command, all the expected files are publish via command line same ClickOnce settings which IDE uses.
Note: You should change the value of ProjLocation to the path of your project.
We have a WinXP Jenkins build machine that I'm in the process of moving over to a 64bit Win-7 machine. We are utilizing Wix to build the msi's via MSBuild..all these projects sit in TFS. We are getting the TFS changeset number in order set to current build in each project. The line in question in many of our [projectname].wixproj files looks like :
<Target Name="BeforeBuild">
<MSBuild.Community.Tasks.Tfs.TfsClient ToolPath="C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE" Command="history /stopafter:1 /version:T /format:detailed /recursive $(ProjectDir)">
<Output TaskParameter="Changeset" PropertyName="Changeset" />
</MSBuild.Community.Tasks.Tfs.TfsClient>
<Message Text="TFS ChangeSetNumber: $(Changeset)" />
<PropertyGroup>
<DefineConstants>ChangesetNumber=$(Changeset)</DefineConstants>
</PropertyGroup>
</Target>
This works fine on our 32-bit machine but fails on the new 64 bit because the toolpath for TF.EXE is now in c:\Program Files (x86)... instead of C:\program files... I'm trying to figure out a way to make this toolpath variable so we can continue to use both build machines (for now) without dedicating the wix project file to one or the other (without breaking one of the build machines, basically).
This tf.exe toolpath is configured easily in Jenkins on a per-machine basis, but this isn't propagated down into the projects themselves...unless there's a path variables I'm unaware of? Thanks.
You can calculate the root tool path in a msbuild variable.
First set the default value for windows 64 bits subfolder and then depending on an environment variable set the value for 32 bits where that variable is undefined in 32 bits machine.
<PropertyGroup>
<MyProgramFiles>C:\Program Files (x86)\</MyProgramFiles>
<MyProgramFiles Condition=" '$(CommonProgramW6432)' == '' ">C:\Program Files\</MyProgramFiles>
</PropertyGroup>
So passing that variable to your .wixproj will look something like:
<Target Name="BeforeBuild">
<PropertyGroup>
<MyProgramFiles>C:\Program Files (x86)\</MyProgramFiles>
<MyProgramFiles Condition=" '$(CommonProgramW6432)' == '' ">C:\Program Files\</MyProgramFiles>
</PropertyGroup>
<MSBuild.Community.Tasks.Tfs.TfsClient ToolPath="$(MyProgramFiles)\Microsoft Visual Studio 10.0\Common7\IDE" Command="history /stopafter:1 /version:T /format:detailed /recursive $(ProjectDir)">
<Output TaskParameter="Changeset" PropertyName="Changeset" />
</MSBuild.Community.Tasks.Tfs.TfsClient>
<Message Text="TFS ChangeSetNumber: $(Changeset)" />
<PropertyGroup>
<DefineConstants>ChangesetNumber=$(Changeset)</DefineConstants>
</PropertyGroup>
</Target>
I hope this help you.
I have a standard sql server 2008 project which has been created using vs2010. I have been trying to modify the build process so that at the end a custom task should fire which would call VSDBCMD to generate a deploy script by comparing the output of the build (the dbschema file) against a static DBschema file. When I run this command from a VS2010 command prompt
vsdbcmd.exe /a:deploy /dd:- /dsp:sql /model:obj\Release\EnterpriseBuild.Services.Database.dbschema /targetmodelfile:VersionedSchemas\v1.0.dbschema /DeploymentScriptFile:NewDeploymentScript.sql /p:TargetDatabase="EnterpriseBuild.Database"
Everything works great and the newdeployment.sql file is generated. However when I modify my .dbproj file and include this as a AfterBuilds Target
<Target Name="AfterBuild">
<!--<Message Text="sample text" Importance="high"></Message>-->
<Exec IgnoreExitCode="false"
WorkingDirectory="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VSTSDB\Deploy\"
Command="vsdbcmd.exe /a:deploy /dd:- /model:obj\Release\EnterpriseBuild.Services.Database.dbschema /targetmodelfile:VersionedSchemas\v1.0.dbschema /DeploymentScriptFile:NewDeploymentScript.sql /p:TargetDatabase="EnterpriseBuild.Database"" />
</Target>
the build fails with a
EnterpriseBuild.Services.Database.dbproj(211,5): error MSB3073: The command "vsdbcmd.exe /a:deploy /dd:- /model:obj\Release\EnterpriseBuild.Services.Database.dbschema /targetmodelfile:VersionedSchemas\v1.0.dbschema /DeploymentScriptFile:NewDeploymentScript.sql /p:TargetDatabase="EnterpriseBuild.Database"" exited with code 1.
message.
Can anyone suggest what I am doing wrong?
Visual Studio also exposes $(VSTSDBDirectory) - location of VSDBCMD
MSBuild task could look as follows:
<Exec Command=""$(VSTSDBDirectory)\Deploy\VSDBCMD" /a:Deploy /q+ /dd:+ /dsp:sql /manifest:"$(OutDir)Database.deploymanifest" /cs:"Integrated Security=SSPI;Persist Security Info=False;Data Source=(local)" /p:AlwaysCreateNewDatabase=true /p:CommentOutSetVarDeclarations=false /p:TargetDatabase="MyDatabase" /Script:"$(OutDir)MyDatabase.sql"" ContinueOnError="false" />
I managed to solve it. Basically doing this
<Target Name="AfterBuild">
<!--<Message Text="sample text" Importance="high"></Message>-->
<Exec IgnoreExitCode="false"
WorkingDirectory="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VSTSDB\Deploy\"
Command="vsdbcmd.exe /a:deploy /dd:- /model:obj\Release\EnterpriseBuild.Services.Database.dbschema /targetmodelfile:VersionedSchemas\v1.0.dbschema /DeploymentScriptFile:NewDeploymentScript.sql /p:TargetDatabase="EnterpriseBuild.Database"" />
</Target>
rightly sets the working directory to C:\Program Files(x86)....where my VersionedSchemas\v1.0.dbschema etc. don't exist. The trick was to keep the working directory same as the ProjectDirectory and still call VSDBCMD. I managed this by doing
<Exec IgnoreExitCode="false" Command=""C:\Program Files (x86)\Microsoft Visual Studio 10.0\VSTSDB\Deploy\vsdbcmd" /a:deploy /dd:- /model:obj\Release\EnterpriseBuild.Database.dbschema /targetmodelfile:VersionedSchemas\v1.0.dbschema /DeploymentScriptFile:NewDeploymentScript.sql /p:TargetDatabase="EnterpriseBuild.Database"" />
The trick was to use & quot; around C:\Pro...
Is there a way to have Visual Studio 2008 execute the "Publish Now" button from the command line?
I've seen posts that suggest to use msbuild /target:publish to call it. That is OK, but MSBuild doesn't increment the revision number. I'm hoping for something like:
devenv mysolution.sln /publish
To increment build numbers, I am using MSBuild Extension pack inside my .csproj file as follows:
<Target Name="BeforeBuild" Condition=" '$(Configuration)|$(Platform)' == 'Release-VersionIncrement|AnyCPU' ">
<CallTarget Targets="CleanAppBinFolder" />
<MSBuild.ExtensionPack.VisualStudio.TfsSource TaskAction="Checkout" ItemCol="#(AssemblyInfoFiles)" WorkingDirectory="C:\inetpub\wwwroot\MySolution" ContinueOnError="true" />
<!-- Microsoft's task that goes over assembly files and increments revision number. -->
<MSBuild.ExtensionPack.Framework.AssemblyInfo Condition="'$(Optimize)'=='True' " AssemblyInfoFiles="#(AssemblyInfoFiles)" AssemblyRevisionType="AutoIncrement" AssemblyFileRevisionType="AutoIncrement">
<Output TaskParameter="MaxAssemblyVersion" PropertyName="MaxAssemblyVersion" />
</MSBuild.ExtensionPack.Framework.AssemblyInfo>
<Message Text="----current version---: '$(MaxAssemblyVersion)'" />
</Target>
This way, anytime the configuration is set to Release-VersionIncrement, the version number is changed. When this is done, I can use the following MSBuild command to publish it:
msbuild c:\projects\MyProject.csproj
/t:ResolveReferences;_CopyWebApplication
/p:Configuration=Release;BuildingProject=true;WebProjectOutputDir=c:\inetpub\wwwroot\OutputProject\MyProjectOutput;OutDir=c:\inetpub\wwwroot\OutputProject\MyProjectOutput
Note that this is for an ASP.NET 3.5 web application.