views:

552

answers:

2

I think the question title neatly sums up what I am after. I have a web app and a service and I would like the build script to check if the service has been updated since the last build and if so, run the "update service reference" script that is available when you right-click on a service.

Any ideas?

A: 

I'm not sure, but I think there's a way to do this through the Visual Studio SDK. I recall that, for instance, there's an object model that you can reference to display the "Add Web Reference" dialog. No doubt you can also do an "Update Web Reference". It should then be possible to create an MSBUILD task that will do this for you.

You should also consider that there may already be such tasks out there. Check on Codeplex and other such places for public collections of MSBUILD tasks, some of which may help.

John Saunders
A: 

We use a PowerShell script to run the wsdl.exe tool for us(or in your case svcutil.exe). The script runs out to the service and pulls a fresh wsdl and re-gens the proxy. You can use to get to PS. The only trickery is to get the namespacing correctly, but there is an option on wsdl.exe for that.

<Target Name="UpdateWebReferences">

<Exec WorkingDirectory="$(SolutionRoot)" 
      Command="$(PS) -Noninteractive -Command $(SolutionRoot)\tools\PowerShell\Compile-Wsdl.ps1 -ukf $(ConfigFilePath)" 
      Condition=" Exists('$(ConfigFilePath)') And Exists('$(SolutionRoot)\tools\PowerShell\Compile-Wsdl.ps1') " />

The above goes in your team build. The meat of the powershell function is as follows:

$projectFile = [xml]( Get-Content $projectFilePath ) 

if ( $projectFile -and $WSDL_LANGUAGE -ne "VB")
{
    $ns = $projectFile.Project.PropertyGroup[ 0 ].RootNamespace
}
else
{
    $ns = $NAMESPACE_PREFIX
}

foreach( $webRefDir in Get-ChildItem $dir.FullName )
{
    $webRefName = $webRefDir.Name

    if ( [System.String]::IsNullOrEmpty( $ns ) )
    {
        $namespace = $webRefName
    }
    else
    {
        $namespace = $( "{0}.{1}" -f $ns, $webRefName )
    }

    Write-Host $( "Compiling Web Reference: {0} using Namespace: {1}..." -f $webRefName, $namespace )

    $outputPath = $( "{0}\{1}" -f $webRefDir.FullName,$REFERENCE_FILE )

    $xpath = "/configuration/appSettings/add[@key='{0}']" -f $webRefName

    if ( $URL_KEY_FILE )
    {
        $xml = [xml](Get-Content $URL_KEY_FILE)
        $url = $xml.SelectSingleNode( $xpath )

        if ( $url )
        {
            $urlOrPath = $url.Value
        }
        else
        {
            Write-Warning $( "Could not find key {0} in {1}..." -f $webRefName, $URL_KEY_FILE )
        }
    }
    else
    {
        $urlOrPath = $( Get-ChildItem $webRefDir.FullName -r -filter "*.wsdl" ).FullName
    }   

    if ( $urlOrPath )
    {
        wsdl /nologo /language:$WSDL_LANGUAGE /n:$namespace /o:$outputPath /urlkey:$webRefName $urlOrPath
    }

    Write-Host "....................................................."
}

All that is required for this is you must have the "Web References" folder checked in. It loops over each directory and creates the correct namespace. The script is long, but I'd be willing to email it.

Adam Fyles
can you provide a code sample?
Jaguar