views:

78

answers:

4

I have a property in MSBuild to represent the directory above the MSBuildProjectDirectory:

<PropertyGroup>
    <BuildDir>$(MSBuildProjectDirectory)\..</PRSBuildDir>
</PropertyGroup>

I need to then use this property, but I need the directory string cleaned so that it doesn't include the ... In other words I need the .. evaluated, so that if the current project file is in C:\Test\Tom\MyDir, then I need a property containing the string C:\Test\Tom.

The reason I'm asking is because I'm trying to run a command like this:

msiexec /passive /i "D:\Build\2.3.84.40394\Deployment\..\Vendor\LogParser.msi"

But it's complaining about the path to the msi: This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.

+1  A: 

The best method I've got right now is below, but I was wondering if there might be a better way..

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;

    <PropertyGroup>
        <BuildDir>$(MSBuildProjectDirectory)\..</BuildDir>
    </PropertyGroup>

    <Target Name="Test">
        <ItemGroup>
            <CleanBuildDir Include="$(BuildDir)" />
        </ItemGroup>

        <PropertyGroup>
            <BuildDir>%(CleanBuildDir.FullPath)</BuildDir>
        </PropertyGroup>

        <Message Text="$(BuildDir)" />
    </Target>
</Project>
Tom
A: 

If you want to have wildcard evaluated, you should use Item instead of Property.

<ItemGroup>
  <BuildDir Include="$(MSBuildProjectDirectory)\.."/>
</ItemGroup>

<Target Name="ExecMSIExec">
  <Exec Command="msiexec /passive /i %(BuildDir.FullPath)\Vendor\LogParser.msi"/>
</Target>
madgnome
+1  A: 

There's a ConvertToAbsolutePath task, that any use?

Ruben Bartelink
Yep definitely useful, but please note that if you pass in an absolute path with .. in it, e.g. "$(MSBuildProjectDirectory)\..", the task will just spit out the same string. So you have to pass in a relative path for it to be "cleaned". Thanks
Tom
You could use the a [powershell msbuild task](http://stackoverflow.com/questions/78069/any-good-powershell-msbuild-tasks/3465029#3465029) or [Inline tasks](http://sedodream.com/2010/01/20/MSBuild40InlineTasks.aspx) in [MSBuild 4.0](http://msdn.microsoft.com/en-us/library/dd722601.aspx) to invoke [Path.GetFullPath](http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx)
Ruben Bartelink
+1  A: 

(deleted my answer as I didn't see that Tom had answered in exactly the same way!)

By the way, why don't you set the "WorkingDirectory" attribute of the Exec task where you actually call msiexec to be the location of your MSI - that way you won't run into an path length issues

Peter McEvoy