wixtoolset / issues

WiX Toolset Issues Tracker
http://wixtoolset.org/
129 stars 24 forks source link

VS2013 build events and preprocessor variables #5254

Closed NPatch closed 8 years ago

NPatch commented 8 years ago

Bugs

If this issue is a bug:

v3.10.2.2516(latest stable)

  • Which version of Visual Studio are you building with (if any)?

VS2013 Premium v12.0.40629.0 REL, 2015, all current Updates installed

  • Which version of .NET are you building with?

.NET 4.5

  • Describe the problem and the steps to reproduce it.

I have a WiX Project set up in VS. Using the project properties UI, I added a preprocessor variable called RootProductDir which is supposed to have a directory that contains whatever I want to bundle. That variable I use in two build events, one pre build, which xcopies the contents of RootProductDir into a project folder which is to be harvested by heat, and a post build event which will eventually xcopy the output msi into a folder called Installer inside RootProductDir.

sample code:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>Debug;RootProductDir=%25USERPROFILE%25\Desktop\Builds\v1.42\;</DefineConstants>
    <WixVariables>InternalProductDir=$(ProductDir)Product;</WixVariables>
  </PropertyGroup>
......
<PropertyGroup>
    <PreBuildEvent>xcopy "$(RootProductDir)%2a" "$(ProjectDir)Product\" /YE
"%25WIX%25bin\heat.exe" dir "$(ProjectDir)Product" -dr INSTALLFOLDER -gg -sreg -scom -srd -cg ProductComponents -out "$(ProjectDir)ProductComponents.wxs" -var wix.InternalProductDir</PreBuildEvent>
  </PropertyGroup>
  <PropertyGroup>
    <PostBuildEvent>xcopy "$(TargetPath)" "$(RootProductDir)Installer\" /YE</PostBuildEvent>
  </PropertyGroup>

But the post build event doesn't expand the RootProductDir variable even though its practically the same as the pre build event and the xcopy in the pre build event works.

I expected the xcopy in the post build event to be able to expand the RootProductDir variable inside the destination folder string just like it did in the xcopy used in the pre build event. But for some reason the post build xcopy produces the following error: Error 1 The command "xcopy "C:\Users\Documents\svn\bin\Debug.msi" "Installer\" /YE" exited with code 4. C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x\wix2010.targets

As you can see the destination folder is "Installer\". Also whitespace in the variable are not an issue since both directories are wrapped with "".

NPatch commented 8 years ago

I also tried moving the post build xcopy into

<Target Name="AfterBuild">
  <Exec Command="xcopy '$(TargetPath)' '$(RootProductDir)Installer\' /YSED" />
</Target>

but it was the same.

I guess it'd be pretty good if the Project Properties UI could expose a tab where we could define msbuild properties instead. They work with build events and anything else. As it is, I could define them manually through code but it would be much better if they were accessible or visible from the Properties UI as other people might need to use it eventually.

jozefizso commented 8 years ago

Where do you define the MSBuild $(RootProductDir) property? Check your verbose MSBuild output to see where the property is set and what value it has when PreBuildEvent and PreBuildEvent are evaluate by MSBuild.

NPatch commented 8 years ago

Actually they are not MSBuild properties so much as constant variables inside a wix MSBuild property.

Also, somehow it worked. No idea why. I didn't exactly change something. I think there might be a problem with whatever processes the changing of wix project properties in VS through UI.

For example, at some point even though I had problems only with the PostBuildEvent and PreBuildEvent was working fine and evaluating $(RootProductDir), even that stopped working. Basically it started evaluating it to "", so it failed on build every time.

Now they both work...and I use the same way to evaluate RootProductDir in both events as the one given above.

NPatch commented 8 years ago

And now they don't work again and I haven't changed a thing....I think this is probably a VS Integration thing. I did check evaluation at some point. I used a SET TEMP=$(RootProductDir)Installer\ and I did see it evaluated properly in the Build Output of VS. Now it doesn't evaluate correctly.

jozefizso commented 8 years ago

If you did SET RootProductDir=<some value> on command line MSBuild used it as it's $(RootProductDir) property value.

MSBuild properties are unrelated to the constants defined for WiX tools using the <DefineConstants> property.

NPatch commented 8 years ago

Right, I meant I didn't use MSBuild Properties. I defined a preprocessor constant since that's what I could use through the UI. But sometimes it doesn't evaluate correctly in pre/post build events. It evaluates to empty string.

The SET was just so I could try and expand the preprocessor constant, since batch code in the pre/post build events gets evaluated and printed in the Build Output.

You must have confused my statement "I guess it'd be pretty good if the Project Properties UI could expose a tab where we could define msbuild properties instead" . I'm new to WiX and it's a bit difficult to figure out how I'm supposed to evaluate each type of variable/constant depending on where it was defined and where its being called for evaluation. So I thought it'd be good if you could have MSBuild properties instead which can be seen through anything , be it MSBuild , or WiX and have a more constant way of calling the property.

barnson commented 8 years ago

There's nothing in wix.targets to convert preprocessor variables to MSBuild properties. It's more typical to want to go the other way. It's unusual to have a project system let you set raw MSBuild properties; that's something done via the command line or via an imported project.

NPatch commented 8 years ago

@barnson I only mentioned MSBuild properties since I think they have the scope closest to a global out of everything. The point was to be able to set a property of some kind (say ApplicationName) once that I could both access from a Pre/Post build event safely and from wix code as well. My problem was that I tried to use preprocessor variables(the way all tutorials on wix say) since I initially thought they had that scope and successfully used it in a Pre-Build event but it gave me grief in the Post-Build event. The part about MSBuild properties was just a suggestion. If you can tell me where I went wrong and whether there's an elegant solution to it, I'm happy to hear about it.

barnson commented 8 years ago

MSBuild properties are going to be useful in other targets.

NPatch commented 8 years ago

Can you tell me why the PostBuild event couldn't read the preprocessor variable? Does it go out of scope as soon as the build ends?

robmen commented 8 years ago

For support please contact the wix-users mailing list.