index > ClickOnce and Setup & Deployment Projects > Publish ClickOnce project with Team Build?

Publish ClickOnce project with Team Build?

Does anyone have any examples of how to create a Team Build BuildType that publishes the project similiar to the way you manually do it in visual studio?

I already have the BuildType created and working (it gets kicked off on a schedule). I've also created a BeforeDropBuild task that does GenerateApplicationManifest and GenerateDeploymentManifest that also works. This was a bit confusing -- when the BuildType is run not through the GUI many of the properties don't exist and most of the examples appear to assume they would. Anyway, these steps work in that the build does not fail.

Somehow I need to publish the manifest I suppose, but I can't find any examples of how to do it. I'm not even sure I know the right questions to ask.

Any help would be appreciated.

Thanks!
ongle

Here is a very good article that should cover everything you need

http://blog.gatosoft.com/PermaLink,guid,d0a0dd1e-c9ac-4fa9-a408-615454d49702.aspx

I adapted it for Team build and to use versioning, here is an example:

<?xml version="1.0" encoding="utf-8"?>

<Project DefaultTargets="DesktopBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!-- TO EDIT BUILD TYPE DEFINITION

To edit the build type, you will need to edit this file which was generated

by the Create New Build Type wizard. This file is under source control and

needs to be checked out before making any changes.

The file is available at -

$/{TeamProjectName}/TeamBuildTypes/{BuildTypeName}

where you will need to replace TeamProjectName and BuildTypeName with your

Team Project and Build Type name that you created

Checkout the file

1. Open Source Control Explorer by selecting View -> Other Windows -> Source Control Explorer

2. Ensure that your current workspace has a mapping for the $/{TeamProjectName}/TeamBuildTypes folder and

that you have done a "Get Latest Version" on that folder

3. Browse through the folders to {TeamProjectName}->TeamBuildTypes->{BuildTypeName} folder

4. From the list of files available in this folder, right click on TfsBuild.Proj. Select 'Check Out For Edit...'

Make the required changes to the file and save

Checkin the file

1. Right click on the TfsBuild.Proj file selected in Step 3 above and select 'Checkin Pending Changes'

2. Use the pending checkin dialog to save your changes to the source control

Once the file is checked in with the modifications, all future builds using

this build type will use the modified settings

-->

<Import Project="bin\Microsoft.Sdc.Common.tasks"/>

<!-- Do not edit this -->

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\TeamBuild\Microsoft.TeamFoundation.Build.targets" />

<Import Project="$(MSBuildExtensionsPath)\Microsoft\AssemblyInfoTask\Microsoft.VersionNumber.Targets"/>

<ProjectExtensions>

<!-- DESCRIPTION

The description is associated with a build type. Edit the value for making changes.

-->

<Description>

</Description>

<!-- BUILD MACHINE

Name of the machine which will be used to build the solutions selected.

-->

<BuildMachine>buildmac</BuildMachine>

</ProjectExtensions>

<PropertyGroup>

<!-- TEAM PROJECT

The team project which will be built using this build type.

-->

<TeamProject>xxx</TeamProject>

<!-- BUILD DIRECTORY

The directory on the build machine that will be used to build the

selected solutions. The directory must be a local path on the build

machine (e.g. c:\build).

-->

<BuildDirectoryPath>c:\localbuilds</BuildDirectoryPath>

<!-- DROP LOCATION

The location to drop (copy) the built binaries and the log files after

the build is complete. This location has to be a valid UNC path of the

form \\Server\Share. The build machine service account and application

tier account need to have read write permission on this share.

-->

<DropLocation>\\xxx\LocalBuilds</DropLocation>

<!-- TESTING

Set this flag to enable/disable running tests as a post build step.

-->

<RunTest>false</RunTest>

<!-- WorkItemFieldValues

Add/edit key value pairs to set values for fields in the work item created

during the build process. Please make sure the field names are valid

for the work item type being used.

-->

<WorkItemFieldValues>Symptom=build break;Steps To Reproduce=Start the build using Team Build</WorkItemFieldValues>

<!-- CODE ANALYSIS

To change CodeAnalysis behavior edit this value. Valid values for this

can be Default,Always or Never.

Default - To perform code analysis as per the individual project settings

Always - To always perform code analysis irrespective of project settings

Never - To never perform code analysis irrespective of project settings

-->

<RunCodeAnalysis>Never</RunCodeAnalysis>

<!-- UPDATE ASSOCIATED WORK ITEMS

Set this flag to enable/disable updating associated workitems on a successful build

-->

<UpdateAssociatedWorkItems>true</UpdateAssociatedWorkItems>

<!-- Title for the work item created on build failure -->

<WorkItemTitle>Build failure in build:</WorkItemTitle>

<!-- Description for the work item created on build failure -->

<DescriptionText>This work item was created by Team Build on a build failure.</DescriptionText>

<!-- Text pointing to log file location on build failure -->

<BuildlogText>The build log file is at:</BuildlogText>

<!-- Text pointing to error/warnings file location on build failure -->

<ErrorWarningLogText>The errors/warnings log file is at:</ErrorWarningLogText>

</PropertyGroup>

<ItemGroup>

<!-- SOLUTIONS

The path of the solutions to build. To add/delete solutions, edit this

value. For example, to add a solution MySolution.sln, add following line -

<SolutionToBuild Include="$(SolutionRoot)\path\MySolution.sln" />

To change the order in which the solutions are build, modify the order in

which the solutions appear below.

-->

<SolutionToBuild Include="$(SolutionRoot)\ClickOnce\ClickOnce.sln" />

<!--

<SolutionToPublish Include="$(SolutionRoot)\ClickOnce\ClickOnce.sln" />

-->

</ItemGroup>

<ItemGroup>

<!-- CONFIGURATIONS

The list of configurations to build. To add/delete configurations, edit

this value. For example, to add a new configuration, add following lines -

<ConfigurationToBuild Include="Debug|x86">

<FlavorToBuild>Debug</FlavorToBuild>

<PlatformToBuild>x86</PlatformToBuild>

</ConfigurationToBuild>

The Include attribute value should be unique for each ConfigurationToBuild node.

-->

<ConfigurationToBuild Include="Release|Any CPU">

<FlavorToBuild>Release</FlavorToBuild>

<PlatformToBuild>Any CPU</PlatformToBuild>

</ConfigurationToBuild>

</ItemGroup>

<ItemGroup>

<!-- TEST ARGUMENTS

If the RunTest is set to true then the following test arguments will be

used to run tests.

To add/delete new testlist or to choose a metadata file (.vsmdi) file, edit this value.

For e.g. to run BVT1 and BVT2 type tests mentioned in the Helloworld.vsmdi file, add the following -

<MetaDataFile Include="$(SolutionRoot)\HelloWorld\HelloWorld.vsmdi">

<TestList>BVT1;BVT2</TestList>

</MetaDataFile>

Where BVT1 and BVT2 are valid test types defined in the HelloWorld.vsmdi file.

MetaDataFile - Full path to test metadata file.

TestList - The test list in the selected metadata file to run.

Please note that you need to specify the vsmdi file relative to $(SolutionRoot)

-->

<MetaDataFile Include=" ">

<TestList> </TestList>

</MetaDataFile>

</ItemGroup>

<ItemGroup>

<!-- ADDITIONAL REFERENCE PATH

The list of additional reference paths to use while resolving references.

For example,

<AdditionalReferencePath Include="C:\MyFolder\" />

<AdditionalReferencePath Include="C:\MyFolder2\" />

-->

</ItemGroup>

<PropertyGroup>

<PublishDir>$(SolutionRoot)\..\Publish</PublishDir>

<SupportUrl>http://tempuri.org</SupportUrl>

<SigningCert>$(SolutionRoot)\ClickOnce\ClickOnce\ClickOnce_TemporaryKey.pfx</SigningCert>

<Company>Company yyyy</Company>

<ClickOnceAppName>ClickOnce</ClickOnceAppName>

<SourceDir>$(SolutionRoot)\..\Binaries\Release</SourceDir>

<ClickOnceVirtualRootDir>C:\Inetpub\wwwroot\ClickOnce\Dev</ClickOnceVirtualRootDir>

<ClickOnceUrl>http://localhost/ClickOnce/Dev/</ClickOnceUrl>

<ClickOnceApplicationUrl>$(ClickOnceUrl)$(ClickOnceAppName).exe.application</ClickOnceApplicationUrl>

<ClickOnceDescription>The application description</ClickOnceDescription>

<!-- Assembly version properties. Add others here -->

<AssemblyMajorVersion>1</AssemblyMajorVersion>

<AssemblyFileMajorVersion>0</AssemblyFileMajorVersion>

<!-- TF.exe -->

<TF>&quot;$(TeamBuildRefPath)\..\tf.exe&quot;</TF>

<!-- AssemblyInfo file spec -->

<AssemblyInfoSpec>AssemblyInfo.cs</AssemblyInfoSpec>

</PropertyGroup>

<ItemGroup>

<GetVersionAssembly Include="$(SourceDir)\$(ClickOnceAppName).exe"/>

</ItemGroup>

<ItemGroup>

<SourceFiles Include="$(SourceDir)\**\*.*" Exclude="$(SourceDir)\**\*.pdb;$(SourceDir)\**\*.vshost*;$(SourceDir)\**\*.manifest;$(SourceDir)\**\*.application"/>

</ItemGroup>

<ItemGroup>

<ClickOnceLandingPage Include="$(SolutionRoot)\**\ClickOnceLandingPage.htm"/>

</ItemGroup>

<!-- Set this to non-existent file to force rebuild. -->

<ItemGroup>

<IntermediateAssembly Include="$(SolutionRoot)\foobar.dll"/>

</ItemGroup>

<Target Name ="BeforeDropBuild" DependsOnTargets="PrepareClickOnceDeployment;DeleteVirtualRootFiles;CopyFilesToVirtualRoot">

</Target>

<Target Name="GetVersion">

<Message Text="Getting version info..."/>

<GetAssemblyIdentity AssemblyFiles="@(GetVersionAssembly)">

<Output TaskParameter="Assemblies"

ItemName="GetVersionAssemblyInfo"/>

</GetAssemblyIdentity>

</Target>

<Target Name="GetPublishContent">

<MakeDir Directories="$(PublishDir)" />

<Copy SourceFiles="@(SourceFiles)"

DestinationFiles="@(SourceFiles->'$(PublishDir)\%(RecursiveDir)%(Filename)%(Extension)')"/>

<Copy SourceFiles="@(AppConfigFile)"

DestinationFiles="$(PublishDir)\$(ClickOnceAppName).exe.config"/>

<Copy SourceFiles="@(ClickOnceLandingPage)"

DestinationFiles="$(PublishDir)\default.htm"/>

<Exec Command="del /f /s /q $(PublishDir)\*.manifest"/>

<Exec Command="del /f /s /q $(PublishDir)\*.application"/>

</Target>

<Target Name="PrepareClickOnceDeployment" DependsOnTargets="GetPublishContent;GetVersion">

<Message Text="Preparing for ClickOnce deployment for version %(GetVersionAssemblyInfo.Version)..."/>

<CreateItem Include="$(PublishDir)\**\*.*">

<Output TaskParameter="Include" ItemName="AppManifestContents"/>

</CreateItem>

<ModifyFile

Path="$(PublishDir)\default.htm"

RegularExpression="#APPLICATION_NAME#"

NewValue="$(ClickOnceAppName).exe"

Force="true"/>

<ModifyFile

Path="$(PublishDir)\default.htm"

RegularExpression="#TITLE#"

NewValue="$(ClickOnceAppName)"

Force="true"/>

<ModifyFile

Path="$(PublishDir)\default.htm"

RegularExpression="#VERSION#"

NewValue="%(GetVersionAssemblyInfo.Version)"

Force="true"/>

<ModifyFile

Path="$(PublishDir)\default.htm"

RegularExpression="#COMPANY#"

NewValue="$(Company)"

Force="true"/>

<ModifyFile

Path="$(PublishDir)\default.htm"

RegularExpression="#SUPPORT_URL#"

NewValue="$(SupportUrl)"

Force="true"/>

<Exec

Command="mage.exe -New Application -TrustLevel FullTrust -ToFile &quot;$(PublishDir)\$(ClickOnceAppName).exe.manifest&quot; -Name &quot;$(ClickOnceAppName)&quot; -Version %(GetVersionAssemblyInfo.Version) -FromDirectory &quot;$(PublishDir)&quot;"

WorkingDirectory="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin" />

<ModifyFile

Path="$(PublishDir)\$(ClickOnceAppName).exe.manifest"

RegularExpression="&lt;application /&gt;"

NewValue="&lt;description asmv2:iconFile=&quot;$(ClickOnceAppName).ico&quot; xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot; /&gt;&lt;application /&gt;"

Force="true"/>

<Exec

Command="mage.exe -Sign &quot;$(PublishDir)\$(ClickOnceAppName).exe.manifest&quot; -CertFile &quot;$(SigningCert)&quot;"

WorkingDirectory="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin"/>

<GenerateDeploymentManifest AssemblyName="$(ClickOnceAppName).exe.application"

AssemblyVersion="%(GetVersionAssemblyInfo.Version)"

DeploymentUrl="$(ClickOnceApplicationUrl)"

Description="$(ClickOnceDescription)"

Product="$(ClickOnceAppName)"

Publisher="$(Company)"

SupportUrl="$(SupportUrl)"

EntryPoint="$(PublishDir)\$(ClickOnceAppName).exe.manifest"

Install="true"

UpdateEnabled="true"

UpdateMode="Foreground"

OutputManifest="$(PublishDir)\$(ClickOnceAppName).exe.application"

MapFileExtensions="true"/>

<Exec

Command="mage.exe -Sign &quot;$(PublishDir)\$(ClickOnceAppName).exe.application&quot; -CertFile &quot;$(SigningCert)&quot;"

WorkingDirectory="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin" />

<GetFrameworkSdkPath>

<Output TaskParameter="Path" PropertyName="SdkPath" />

</GetFrameworkSdkPath>

<GenerateBootstrapper

ApplicationFile="$(ClickOnceAppName).exe.application"

ApplicationName="$(ClickOnceAppName)"

ApplicationUrl="$(ClickOnceUrl)"

BootstrapperItems="@(BootstrapperFile)"

Culture="en"

FallbackCulture="en-US"

CopyComponents="true"

Validate="false"

Path="$(SdkPath)\Bootstrapper"

OutputPath="." />

</Target>

<Target Name="DeleteVirtualRootFiles">

<Message Text="Deleting files/directories from $(ClickOnceVirtualRootDir)..."/>

<Exec Command="del /f /s /q $(ClickOnceVirtualRootDir)\*.*"/>

</Target>

<Target Name="CopyFilesToVirtualRoot" DependsOnTargets="PrepareClickOnceDeployment;DeleteVirtualRootFiles">

<Message Text="Copying files to $(ClickOnceVirtualRootDir)..."/>

<CreateItem Include="$(PublishDir)\**\*.*">

<Output TaskParameter="Include" ItemName="ClickOnceInstallationFiles"/>

</CreateItem>

<Copy SourceFiles="@(ClickOnceInstallationFiles)" DestinationFolder="$(ClickOnceVirtualRootDir)\%(ClickOnceInstallationFiles.RecursiveDir)" />

<Copy SourceFiles="@(AppManifestContents)"

DestinationFiles="@(AppManifestContents->'$(ClickOnceVirtualRootDir)\%(RecursiveDir)%(Filename)%(Extension).deploy')"/>

</Target>

<Target Name="AfterGet" Condition="'$(IsDesktopBuild)'!='true'">

<!-- Set the AssemblyInfoFiles items dynamically -->

<CreateItem Include="$(SolutionRoot)\**\$(AssemblyInfoSpec)">

<Output ItemName="AssemblyInfoFiles" TaskParameter="Include" />

</CreateItem>

<!-- Check out the assembly info files for version change -->

<Exec WorkingDirectory="$(SolutionRoot)"

Command="$(TF) checkout /recursive $(AssemblyInfoSpec)"/>

</Target>

<Target Name="AfterCompile" Condition="'$(IsDesktopBuild)'!='true'">

<!-- Check in the assembly info files after version change -->

<Exec WorkingDirectory="$(SolutionRoot)"

Command="$(TF) checkin /comment:&quot;Auto-Build: Version Update&quot; /noprompt /override:&quot;Auto-Build: Version Update&quot; /recursive $(AssemblyInfoSpec)"/>

</Target>

<!-- In case of Build failure, the AfterCompile target is not executed. Undo the changes -->

<Target Name="BeforeOnBuildBreak" Condition="'$(IsDesktopBuild)'!='true'">

<Exec WorkingDirectory="$(SolutionRoot)"

Command="$(TF) undo /noprompt /recursive $(AssemblyInfoSpec)"/>

</Target>

</Project>

alan_b

That's awesome Alan. Thank you so much. It really helps to see the steps laid out in a working script. I had come across most of these parts but wasn't sure how to fit them together. I'm still having issues with the CertFile but not with the script itself.

For anybody else who had the same question, here is some more information needed to get the script working.

  • Download the Sdc.Tasks MSBuild extensions from GotDotNet (click here). You will need them for the ModifyFile steps in the script.
  • I had to add Exists conditions to the DEL commands because the first time I run it there are no files to delete and DEL returns an error code (there might be a better way of doing this, but the condition worked (e.g. <Exec Command="del /f /s /q $(PublishDir)\*.manifest" Condition="Exists('$(PublishDir)\*.manifest')"/>)
  • The script assumes you have an html file to prompt the user to install the click once application (default name is ClickOnceLandingPage.htm in script). I think one gets created for you when you manually publish ClickOnce. The one the script is using is an edited version of the ClickOnce created file. It is available as part of the download available at the link referenced at the beginning of Alan's post (Mike Bouck's blog). You add the htm file to your solution somewhere so Team Build sucks it down when it gets the source.

 

ongle

More notes:

To use the versioning stuff you need to install the AssemblyInfoTask (also available from GotDotNet, click here).

I had a lot of problems relating to mage.exe picking up the results of previous builds. The script has EXEC DEL tasks but that didn't seem to do the trick. I ended up adding a RemoveDir task and that solved most of my issues. see below (note that without the Message tasks the directory wouldn't get created sometimes. dunno why, maybe a timing or caching issue):

<Target Name="GetPublishContent">
<
Message Text="Removing Publish Directory: $(PublishDir)..."/>
<
RemoveDir Directories="$(PublishDir)" />
<
Message Text="Creating Publish Directory: $(PublishDir)..."/>
<
MakeDir Directories="$(PublishDir)" />
.......

I tried not to use the test certificates but I had issues getting MSBuild to open the file. I assume that i need to somehow register the cert file with the user that MSBuild is running under (otherwise I would get errors saying the network password was incorrect). For now, I just created a test certificate in VS2k5.

 

ongle

Hi alan

I saw your url of Team build for Clickonce. I did all the procedures mentioned for deploying QA,Prod & Dev. Everything was fine up to that. But after surfing to the clickonce deployment path. I am getting error like Erro Downloading the Required Files. This is the same problem i got in Sandbox mode of VS Clickonce.do you know what is the problem?.

Thanks

With regards

tej.

TEJKIRAN
Hard to say tej. Do you have any extra prerequisites that need to be installed?
alan_b

I am also trying to publish a project using Team Build but I am having many problems.

I have setup a build type witha project file that has all the information alan posted.  I am very new to ClickOnce deployments so I am struggling in reading the script and understanding whats going on.  I am still getting errors on my build, one of which appears to be a path syntax error but I havent nailed down yet.  The other problem/question that I have concerns publishing it to a website.  Does this script automatically configure the virtual directory on IIS or do you guy do that manually?  Or do you just publish to a UNC path or CD?

Thanks for any assistance.

Update:  Got around my pathing error but this configuration still seems fishy to me when it comes to publishing to a website.  The files that get copied to a directory for IIS are alot different when publishing the project manually from Visual Studio. 

The Team Build version of the project completes successfully, yet the html file and information deployed to the publisheddir does not allow for a "ClickOnce" Deployment.  Should the output from the Team Build be identical to the output from a manual publish?

S_GMAN
reply 7

You can use google to search for other answers

 

More Articles

• Run application after installation.
• How to access auto updater in code?
• Making "Everyone" the default option while installing t...
• Vis studio 2003 style deployment
• Deployment Help
• Newbie with uninstall and update questions
• FYI - "Fixing" javascript events with .NET Framework 1....
• Versions
• Deployment options
• latest, the very latest smartClient sample app that includes the ...
Bookmark and Share
Welcome to Bokebb   New Update  
 

New Articles

• ClickOnce Deployment from Web and IE &qu
• ClickOnce FAQ Now Available
• Handler don't work
• version management in deployment server
• "Do you want to run the application
• Packaging multiple pre-existing software
• Moving published ClickOnce deployment fi
• Creating Windows Installer Package (Setu
• Does developing and ditributing applicat
• Problem with windows app not running aft
• Deploying files not listed in the Publis
• Code Groups: What am I doing wrong?
• Problems with MIME settings at the hosti
• disribute my application without install
• Publishing Problem in RC1 - 8.05727.26 (

Hot Articles

• Can I change how Publish.html looks like?
• No Touch Deploying From A Unix Server?
• Walk-through / FAQ for non-IIS servers
• Host WinForm UserControl in ASP.NET 2.0
• How do I fix InvalidDeploymentException
• Problems in deploying an application wit
• Point usercontrols in IE to 1.0 framework
• Cruisecontrol, nsbuyild,
• Newbie: How do controls work in IE?
• troubleshooting AppUpdater
• Exception when rising event to javascrip
• Shortcuts could not be removed. Try agai
• ClickOnce Deployment And Browsers
• Building deployment project causes SQL S
• How to access auto updater in code?

Recommend Articles

• Can I install prerequisites from the CD
• ClickOnce doens't install application lo
• How to use MsgBox in c# for a class libr
• ClickOnce: how to specify credentials fo
• When I publish my sample 'Personal Websi
• Question on VS 2005 publishing ClickOnce
• Setup Project, Custom Actions Editor
• Configure Client & Server to run Win
• Insufficient Privileges during My applic
• Error when Deploying ClickOnce Applicati
• In Win2000 OS, add/remove program can't
• ClickOnce publish failes when project ha
• Retrieve Query String Information
• Distribute framework
• Dos name in task manager