Is this a bug of Detokenise?

Nov 11, 2011 at 10:02 AM
Edited Nov 11, 2011 at 10:03 AM

I want generate files from a template file which have may $(tokens):

    <Package name="$(InstallPackageName).msi"/>
 <!--more xml node-->

the proj file(some PropertyGroups are defined in another proj file):
<Target Name="DumpIniFileFromTemplate">
   <FileCollection Include="$(PhysicalPath)\Template.xml"/>
   <FileCollection Include="$(PhysicalPath)\uninstall.vbs"/>
  <MSBuild.ExtensionPack.FileSystem.Detokenise TaskAction="Detokenise" TargetFiles="@(FileCollection)" TextEncoding="ASCII"/>

and then, i run msbuild in command line:
msbuild C:\test\install.proj /t:DumpIniFileFromTemplate
it's luck everything works well. the output content has all contents right
But if I build the target with parameter:
msbuild C:\test\install.proj /t:DumpIniFileFromTemplate /P:InstallPackageName=TestMsiService
Unfortunately the xml content isn't that I expected althrough the build is success:
    <Package name="MyTestMsi.Install"/>
 <!--more xml node-->
As see above, attribute 'name' is still "MyTestMsi.Install"。

Can anybody tell me is this a bug or my mistake?

Nov 13, 2011 at 12:04 PM

It's not a bug or a mistake but by current design. The task works in 'collection' mode or project mode. You are calling it in project mode which means the task reloads the calling project and uses the properties that it evaluates to detokenise the files. It loads this file as is and your properties passed on the command line therefore have no affect.

You could switch to 'collection' mode by using the CommandLineValues or ReplacementValues properties. In your case you would do this:

  <MSBuild.ExtensionPack.FileSystem.Detokenise TaskAction="Detokenise" TargetFiles="@(FileCollection)" TextEncoding="ASCII" CommandLineValues="$(clv)"/>

msbuild C:\test\install.proj /t:DumpIniFileFromTemplate /P:clv=InstallPackageName=TestMsiService

The issue that you may hit though is that the task does not support running in both modes, so you would loose access to all the properties defined in the proj file. I'll look at improving the task to support running in both modes for the next release.



Nov 14, 2011 at 2:35 AM

Thanks for your reply.

"CommandLineValues" may be not suitable in my case. In fact, my template.xml is more complicated than the shown .Also, some replacements are dynamicly set during the build so I can't determine the CommandLineValues before build.

I fixed my issue by using ReplacementValues Mode. But I have to wrote lots of TokenValues node which is 'smelly'. Support running in both modes will be an excellent idea:)

Nov 14, 2011 at 5:55 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Dec 29, 2011 at 4:51 PM

resolved here:

Jun 14, 2012 at 4:59 PM

Looking at the code for Detokenise, I observe that the method [DoDetokenise()] is always (from InternalExecute()) called.  The [DoDetokenise()] method proceeds to initialise a [Project] object by reloading the project file irrespective of whether the ReplacementValues Item set is populated or not.

Doesn't this bring unnecessary overhead whilst reloading the project where this is not needed? I was under the impression that once ReplacementValues is set, the project file will not be re-loaded.


Jun 19, 2012 at 10:27 PM

Yes I think we be a bit more efficient here. The task now supports 'SearchAllStores' which allows a combination of project and provided values. I'll see if I can add an optimization for the case where values are provided and SearchAllStores is false.


Jun 19, 2012 at 10:28 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Aug 14, 2012 at 11:44 PM

@ChikeOkor, this is now resolved ---