Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WixHelper directory names containing spaces not building #1129

Closed
devfunkd opened this issue Feb 4, 2016 · 18 comments
Closed

WixHelper directory names containing spaces not building #1129

devfunkd opened this issue Feb 4, 2016 · 18 comments

Comments

@devfunkd
Copy link

devfunkd commented Feb 4, 2016

When I attempt to run my build script and use a directory name with a space the script fails. If I remove the space in the directory name it works. Looks like WixHelper does not work with directory names containing spaces.

This line Fails...
let applicationDirectoryString = wixDir (fun file -> not (file.Extension = ".config")) true (DirectoryInfo (buildDir @@ "/Some Application"))

This line Passes...
let applicationDirectoryString = wixDir (fun file -> not (file.Extension = ".config")) true (DirectoryInfo (buildDir @@ "/SomeApplication"))

Error Message:

 1) System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
   at System.String.Substring(Int32 startIndex, Int32 length)
   at Fake.WiXHelper.getComponentIdsFromWiXString@620.Invoke(String f) in C:\code\fake\src\app\FakeLib\WiXHelper.fs:line 620
   at Microsoft.FSharp.Collections.IEnumerator.map@111.DoMoveNext(b& )
   at Microsoft.FSharp.Collections.IEnumerator.MapEnumerator`1.System-Collections-IEnumerator-MoveNext()
   at System.String.Concat(IEnumerable`1 values)
   at Fake.WiXHelper.getComponentIdsFromWiXString(String wiXString) in C:\code\fake\src\app\FakeLib\WiXHelper.fs:line 618
   at FSI_0005.Build.clo@103-5.Invoke(Unit _arg6) in C:\Workspaces\MyApp\main\build.fsx:line 120
   at Fake.TargetHelper.runSingleTarget(TargetTemplate`1 target) in C:\code\fake\src\app\FakeLib\TargetHelper.fs:line 484
@DigitalFlow
Copy link
Contributor

@devfunkd: Can you post the error message?

@devfunkd
Copy link
Author

 1) System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
   at System.String.Substring(Int32 startIndex, Int32 length)
   at Fake.WiXHelper.getComponentIdsFromWiXString@620.Invoke(String f) in C:\code\fake\src\app\FakeLib\WiXHelper.fs:line 620
   at Microsoft.FSharp.Collections.IEnumerator.map@111.DoMoveNext(b& )
   at Microsoft.FSharp.Collections.IEnumerator.MapEnumerator`1.System-Collections-IEnumerator-MoveNext()
   at System.String.Concat(IEnumerable`1 values)
   at Fake.WiXHelper.getComponentIdsFromWiXString(String wiXString) in C:\code\fake\src\app\FakeLib\WiXHelper.fs:line 618
   at FSI_0005.Build.clo@103-5.Invoke(Unit _arg6) in C:\Workspaces\MyApp\main\build.fsx:line 120
   at Fake.TargetHelper.runSingleTarget(TargetTemplate`1 target) in C:\code\fake\src\app\FakeLib\TargetHelper.fs:line 484

@devfunkd
Copy link
Author

Can we confirm is this a bug?

@devfunkd
Copy link
Author

Can we confirm is this a bug or not because I am not sure what to do as far this is concerned? Please let me know.

@DigitalFlow
Copy link
Contributor

I can confirm that this is a bug, seems to be an issue in the getComponentIdsFromWiXString function, I will have a look at this.

@devfunkd
Copy link
Author

devfunkd commented Mar 2, 2016

Any idea when this could be fixed, I have a QA pushing to get this resolved... would like to tell them something? thanks for confirming this, appreciated.

@forki
Copy link
Member

forki commented Mar 2, 2016

I would merge a pull request and release it if someone can help here.
On Mar 2, 2016 3:03 AM, "Ross" notifications@github.com wrote:

Any idea when this could be fixed, I have a QA pushing to get this
resolved... would like to tell them something? thanks for confirming this,
appreciated.


Reply to this email directly or view it on GitHub
#1129 (comment).

@DigitalFlow
Copy link
Contributor

Already found the problem, it's with the regex in getComponentIdsFromWiXString, line 604 in current master. I'll change this one and send a PR.

@DigitalFlow
Copy link
Contributor

Hello @devfunkd,

can you test, whether the changes in above PR fix your issues?

Kind Regards

@devfunkd
Copy link
Author

devfunkd commented Mar 2, 2016

Getting this error now:

C:\Workspaces\Project\main.build.compile\setup.template.wxs(41) : error CNDL0014 : The Directory/@id attribute's value, 'Project 4', is not a legal identifier. Identifiers may contain ASCII characters A-Z, a-z, digits, underscores (_), or periods (.). Every identifier must begin with either a letter or an underscore.

Here is my WXS template:

`


<!-- Installer Properties -->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
<PropertyRef Id="WIX_IS_NETFRAMEWORK_46_OR_LATER_INSTALLED"/>

<!-- Installer Resources -->
<Icon Id="ApplicationIcon" SourceFile="Project\Project 4_vista.ico"/>
<Property Id="ARPPRODUCTICON" Value="ApplicationIcon" />
<WixVariable Id="WixUILicenseRtf" Value="Project/license.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="WixUIBannerBmp.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="WixUIDialogBmp.bmp" />
<!-- Check Existing Install -->
<Upgrade Id="9e578e3d-0119-425c-8633-f54ffaaa4929">
    <UpgradeVersion Minimum="@product.version@" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
    <UpgradeVersion Minimum="0.0.0" Maximum="@product.version@" IncludeMinimum="yes" IncludeMaximum="no" Property="OLDERVERSIONBEINGUPGRADED"/>   
</Upgrade>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>

<!-- Prerequisites -->
<Condition Message="This application requires .NET Framework 4.6 or newer. Please install the .NET Framework then run this installer again.">
  <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_46_OR_LATER_INSTALLED]]>
</Condition>
<Condition Message="This application requires at least Windows 7 or Windows Server 2008 R2. Please upgrade your computer to a supported operating system and run this installer again.">
  <![CDATA[Installed OR (VersionNT >= 601)]]>
</Condition>

<!-- Define the directory structure -->
<Directory Id="TARGETDIR" Name="SourceDir">
          <Directory Id="ProgramFilesFolder" Name="ProgramFiles">
            <Directory Id="INSTALLDIR" Name="@product.company@">
                @product.applicationfiles@
                @product.servicefiles@
            </Directory>
          </Directory>
          <Directory Id="ProgramMenuFolder">
            <Directory Id="ApplicationProgramsFolder" Name="@product.name@"/>
            <Directory Id="ServiceProgramsFolder" Name="@product.name@"/>
          </Directory>
          <Directory Id="DesktopFolder" Name="Desktop" /> 
        </Directory>           

<DirectoryRef Id="ApplicationProgramsFolder">
        <Component Id="ApplicationShortcut" Guid="1e578e4d-0229-425c-8633-f54ffaaa4901">
            <Shortcut Id="ApplicationStartMenuShortcut" 
                Name="@product.name@ @product.version@" 
                Description="@product.company@ @product.name@ @product.version@"
                Target="[INSTALLDIR]Project\Project.UserInterface.exe"
                WorkingDirectory="INSTALLDIR"
                Icon ="ApplicationIcon"/>                   
            <Shortcut Id="HelpStartMenuShortcut" 
                Name="@product.name@ Help" 
                Target="[INSTALLDIR]Project\Project.chm"
                WorkingDirectory="INSTALLDIR"/> 
            <Shortcut Id="SupportStartMenuShortcut" 
                Name="Technical Support (Acme)" 
                Target="[INSTALLDIR]Project\Acme-support.exe"
                WorkingDirectory="INSTALLDIR"/>
            <Shortcut Id="UninstallProduct"             
                      Name="Uninstall @product.name@"
                      Target="[SystemFolder]msiexec.exe"
                      Arguments="/x [ProductCode]"
                      Description="Uninstall @product" />                    
            <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
            <RegistryValue Root="HKCU" Key="Software\Microsoft\Acme" Name="application-installed" Type="integer" Value="1" KeyPath="yes"/>
            <Shortcut Id="desktopshortcut" 
                      Directory="DesktopFolder" 
                      Name="@product.name@" 
                      WorkingDirectory="INSTALLDIR" 
                      Target="[INSTALLDIR]Project\Project.UserInterface.exe" />
       </Component>
</DirectoryRef>

<DirectoryRef Id="ServiceProgramsFolder">
       <Component Id="ServiceShortcut" Guid="9e578e3d-0229-425c-8633-f54ffaaa4901">
            <Shortcut Id="ServiceStartMenuShortcut"
                Name="@product.name@ Reporting Service" 
                Description="@product.name@ Reporting Service"
                Target="[INSTALLDIR]Reporting\Project.ReportingService.exe"
                WorkingDirectory="INSTALLDIR"
                Icon ="ApplicationIcon"/>
            <RemoveFolder Id="ServiceProgramsFolder" On="uninstall"/>                    
            <RegistryValue Root="HKCU" Key="Software\Microsoft\Acme" Name="service-installed" Type="integer" Value="1" KeyPath="yes"/>                   
       </Component>
</DirectoryRef>           

<!--  Feature: Project Application -->            
<Feature Id="Feature.Application"
                 Title="@product.name@ Maintenance Management Application"
                 Description="Project is an asset management and maintenance application designed to optimize asset value and improve manufacturing productivity."
                 ConfigurableDirectory="INSTALLDIR"
                 Level="1"
                 AllowAdvertise="no">
                @product.applicationcomponents@
                <ComponentRef Id="ApplicationShortcut" />                    
</Feature>

<!--  Feature: Reporting Service -->
<Feature Id="Feature.Service"
                 Title="@product.name@ Reporting Service (Server Installation)"
                 Description="This service generates and delivers reports that have been scheduled in the Project Maintenance Management System."
                 ConfigurableDirectory="INSTALLDIR"
                 Level="3"
                 AllowAdvertise="no">
                @product.servicecomponents@    
                <ComponentRef Id="ServiceShortcut" />                    
    <Component Id="ReportingServiceInstaller" Guid="B72CAA3F-F2DB-48D2-90DD-061209AB2CE5" Directory="INSTALLDIR">
        <CreateFolder />
        <File Id="ReportingService.exe" Name="ReportingService.exe" KeyPath="yes" Source="@product.sourcedir@\Reporting\Project.ReportingService.exe"/>
        <ServiceInstall Id="ReportingServiceInstaller"
            Type="ownProcess"
            Vital="yes"
            Name="Project Reporting Service"                    
            DisplayName="Project - Reporting Service"
            Description="This service generates and delivers reports that have been scheduled in the Project Maintenance Management System."
            Start="auto"
            Account="NT AUTHORITY\LocalService"
            ErrorControl="ignore"
            Interactive="no" />
    </Component>        
</Feature>

<InstallExecuteSequence>
    <RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>   

<UIRef Id="WixUI_FeatureTree" />
<UI>
  <DialogRef Id="FilesInUse" />
  <DialogRef Id="MsiRMFilesInUse" />
  <!-- Add the GUI logic for installation -->
</UI>
`

Build.fsx:

`Target "Setup" (fun _ ->

// Copy all mobile CAB files to the application directory
!! ("./dependencies/MobileInstall/*.*")
  |> Copy (buildDir + "/Project 4/Mobile/") 

// Copy setup template to the build directory
!! (setupDir + "/*.*")
  |> Copy buildDir

// Copy resources to the application directory
!! (setupDir + "/resources/*.*")
  |> Copy (buildDir + "/Project 4/")

let TRUE = fun _ -> true

// Generate directory and component IDs for application
let applicationDirectoryString = wixDir (fun file -> not (file.Name = "dataConfiguration.config")) true (DirectoryInfo (buildDir @@ "/Project 4"))
let applicationComponentIds = getComponentIdsFromWiXString applicationDirectoryString

// Generate directory and component IDs for service
let servivceDirectoryString = wixDir (fun file -> not (file.Name = "Project.ReportingService.exe")) true (DirectoryInfo (buildDir @@ "/Reporting"))
let serviceComponentIds = getComponentIdsFromWiXString servivceDirectoryString

let replacements = [
    "@product.name@", "Project 4"
    "@product.company@", "Acme"
    "@product.description@", "Project 4 is an asset management and maintenance application designed to optimize asset value and improve manufacturing productivity."
    "@product.version@", version
    "@product.applicationfiles@", applicationDirectoryString
    "@product.servicefiles@", servivceDirectoryString
    "@product.applicationcomponents@", applicationComponentIds
    "@product.servicecomponents@", serviceComponentIds
    "@product.productcode@", "21654944-cf96-447f-890f-f7642e3128ec"
    "@product.sourcedir@", buildDir]

!! (buildDir @@ "*.wxs")
    |> processTemplates replacements  

// run the WiX tools
WiX (fun p -> {p with ToolDirectory = WiXPath; AdditionalLightArgs = ["-ext WiXNetFxExtension";"-ext WixUIExtension.dll";"-ext WixUtilExtension.dll";]}) 
    (buildDir @@ "Project-" + version + ".msi")
    (buildDir @@ "setup.template.wxs")

)
`

@DigitalFlow
Copy link
Contributor

@devfunkd: Found an issue in the WiXDir function, it sets the directory name as id for the components that it creates, but does not remove spaces in it. I changed it to use the hashcode of the name.
Please test with PR: #1164

@devfunkd
Copy link
Author

devfunkd commented Mar 3, 2016

Doesn't work, still getting error:

C:\Workspaces\Project\main.build.compile\setup.template.wxs(803) : error CNDL0014 : The ComponentRef/@id attribute's value, '37b7fd9538', is not a legal identifier. Identifiers may contain ASCII characters A-Z, a-z, digits, underscores (_), or periods (.). Every identifier must begin with either a letter or an underscore.

@devfunkd
Copy link
Author

devfunkd commented Mar 4, 2016

The latest version with this change seems to have broken the WixHelper, watched all my builds start breaking this morning on TeamCity :(

@forki
Copy link
Member

forki commented Mar 4, 2016

@DigitalFlow should I revert? To which version?
On Mar 4, 2016 3:04 AM, "Ross" notifications@github.com wrote:

The latest version with this change seems to have broken the WixHelper,
watched all my builds start breaking this morning on TeamCity :(


Reply to this email directly or view it on GitHub
#1129 (comment).

@devfunkd
Copy link
Author

devfunkd commented Mar 4, 2016

The issue appears to be the IDs don't start with a character. Looking at the code it seems some areas aren't appending a character in front of the hashcode.

On Mar 3, 2016, at 11:27 PM, Steffen Forkmann notifications@github.com wrote:

@DigitalFlow should I revert? To which version?
On Mar 4, 2016 3:04 AM, "Ross" notifications@github.com wrote:

The latest version with this change seems to have broken the WixHelper,
watched all my builds start breaking this morning on TeamCity :(


Reply to this email directly or view it on GitHub
#1129 (comment).


Reply to this email directly or view it on GitHub.

@DigitalFlow
Copy link
Contributor

@forki: I'll make sure, that a letter is prepended to each ID. No revert needed yet.
@devfunkd Please recheck with FAKE v 4.21.4

@devfunkd
Copy link
Author

devfunkd commented Mar 4, 2016

FAKE v 4.21.4 Works! Thanks guys, this developer gets to shed the QA on his back... I am free again! :)

@forki
Copy link
Member

forki commented Mar 4, 2016

;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants