D
D
Dmitry Makarov2015-03-26 14:47:48
visual studio
Dmitry Makarov, 2015-03-26 14:47:48

Shortcuts in the main menu are not deleted when the application is uninstalled. What's the matter?

Hello colleagues.
I recently started learning WiX.
So:...
I have several homogeneous projects, which both in ProgramFiles and in the main menu are combined into one folder, and already inside this folder, each project is installed in its own subfolder. For this, one common wxi-file has been created, which describes how to install everything. For each project, a wxs file has been created in which the nuances of a particular project are defined.
Everything works beautifully, but when uninstalling, a problem appears that I can’t overcome in any way: if one project was installed, then it is uninstalled successfully, and if there are two or more, then the shortcuts from the main menu and the keys written to the registry are not deleted. If there is one installed project left, then its shortcuts and registry keys are deleted normally.
As a result, after installing, say, five projects and then uninstalling them, I am left with garbage in the form of four shortcuts and four keys in the registry associated with installed projects, in addition to the one I deleted last.
Let, for example, one of my projects be called Pjt1.
In VS2013, the WiX Setup Project's SetupPjt1 includes References for the Pjt1 project and WixUIExtention, and adds Project1.wxs files and a shortcut to Common.wxi. In the SetupPjt1 properties on the "Build" tab, the "Cultures to build" property is set to "ru-ru".
Project1.wxs

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <?define SourcePath="$(var.Pjt1.TargetPath)"?>
  <?define SourceName="$(var.Pjt1.TargetName)"?>
  <?define SourceFileName="$(var.Pjt1.TargetFileName)"?>
  <?define SourceDir=$(var.Pjt1.TargetDir)?>
  <?define ApplicationTitle="Проект 1"?>
  <?define UpgradeCode="{BBE54FA8-53E6-44EB-ABA5-A364744E5D35}"?>
  <?define ProductCode="*"?>
  <?define ProductVersion=15.02.11.14?>
  <?define Manufacturer="Наша контора"?>
  <?define GroupApplicationName="PjojectGroup"?>
  <?define GroupApplicationTitle="Группа проектов"?>
  <?define DependencesFiles=dep1.dll;dep2.dll;dep3.dll;dep4.dll?>

  <?include ..\Common.wxi?>
</Wix>

Common.wxi
<?xml version="1.0" encoding="utf-8"?>
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product  Id="$(var.ProductCode)"
              UpgradeCode="$(var.UpgradeCode)"
              Name="$(var.ApplicationTitle)"
              Language="1049"
              Codepage="1251"
              Version="$(var.ProductVersion)"
              Manufacturer="$(var.Manufacturer)">

    <Package  InstallerVersion="200"
              Compressed="yes"
              InstallScope="perMachine"/>
    
    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <Media Id="1" Cabinet="$(var.SourceName).cab" EmbedCab="yes"/>
    <Property Id="WIXUI_INSTALLDIR" Value="ApplicationFolder" />
    <Property Id ="MSIUSEREALADMINDETECTION" Value="1"/>
    <UIRef Id="WixUI_Common" />
    <UI Id="WixUI_ConfigUPAE">
      <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
      <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
      <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />

      <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
      <Property Id="WixUI_Mode" Value="InstallDir" />

      <DialogRef Id="BrowseDlg" />
      <DialogRef Id="DiskCostDlg" />
      <DialogRef Id="ErrorDlg" />
      <DialogRef Id="FatalError" />
      <DialogRef Id="FilesInUse" />
      <DialogRef Id="MsiRMFilesInUse" />
      <DialogRef Id="PrepareDlg" />
      <DialogRef Id="ProgressDlg" />
      <DialogRef Id="ResumeDlg" />
      <DialogRef Id="UserExit" />

      <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
      <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>

      <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>

      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">NOT Installed</Publish>
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>

      <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
      <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
      <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
      <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
      <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
      <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
      <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>

      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>

      <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>

      <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
      <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
      <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>

      <Property Id="ARPNOMODIFY" Value="1" />
    </UI>

    <Directory Id="TARGETDIR" Name="SourceDir">
      <!-- Директории, помещаемые в ProgramFiles -->
      <Directory Id="ProgramFilesFolder">
        <Directory Id="ManufacturerFolder" Name="$(var.Manufacturer)">
          <Directory Id="GroupFolder" Name="$(var.GroupApplicationName)">
            <Directory Id="ApplicationFolder" Name="$(var.SourceName)" />
          </Directory>
        </Directory>
      </Directory>

      <!-- Директории, помещаемые в главное меню -->
      <Directory Id="ProgramMenuFolder">
        <Directory Id ="MenuManufacturerFolder" Name="$(var.Manufacturer)">
          <Directory Id="MenuGroupFolder" Name="$(var.GroupApplicationTitle)">
            <Directory Id="MenuApplicationFolder" Name="$(var.ApplicationTitle)" />
          </Directory>
        </Directory>
      </Directory>
    </Directory>

    <!--Файлы, помещаемые в ProgramFiles-->
    <DirectoryRef Id="ApplicationFolder">
      <Component Id="ApplicationComponent" Guid="{C3BB7C3D-1D04-4B6F-ABCE-F6B36B24E488}" DiskId="1">
        <File Id="$(var.SourceFileName)" Name="$(var.SourceFileName)" Vital="yes" Source="$(var.SourceDir)"/>
        <?foreach dependenceFile in $(var.DependencesFiles)?>
        <File Id="$(var.dependenceFile)" Name="$(var.dependenceFile)" Vital="yes" Source="$(var.SourceDir)"/>
        <?endforeach?>
      </Component>
    </DirectoryRef>

    <!--Ярлыки, помещаемые в главное меню и регистрация их в реестре-->
    <DirectoryRef Id="MenuApplicationFolder">
      <Component Id="ApplicationShortcut" Guid="{CCCD7917-E585-4D59-89C6-503231F4EFEF}">
        <CreateFolder Directory="MenuManufacturerFolder"/>
        <CreateFolder Directory="MenuGroupFolder"/>        
        <CreateFolder Directory="MenuApplicationFolder" />
        
        <RemoveFolder Id="RemoveMenuManufacturerFolder" Directory="MenuManufacturerFolder" On="uninstall"/>
        <RemoveFolder Id="RemoveMenuGroupFolder" Directory="MenuGroupFolder" On="uninstall"/>
        <RemoveFolder Id="RemoveMenuApplicationFolder" Directory="MenuApplicationFolder" On="uninstall"/>

        <Shortcut Id="ApplicationStartMenuShortcut"
                  Name="$(var.ApplicationTitle)"
                  Target="[ApplicationFolder]$(var.SourceFileName)"
                  WorkingDirectory="ApplicationFolder"
                  Directory="MenuApplicationFolder"/>
        
        <RegistryValue Root="HKCU"
                       Key="Software\$(var.Manufacturer)\$(var.GroupApplicationTitle)\$(var.ApplicationTitle)"
                       Name="InstalledStartMenuShortcuts"
                       Type="integer"
                       Value="1"/>
      </Component>
    </DirectoryRef>

    <!-- Установка всех элементов -->
    <Feature Id="Pjt1" Title="$(var.ApplicationTitle)" Level="1">
      <ComponentRef Id="ApplicationComponent"/>
      <ComponentRef Id="ApplicationShortcut"/>
    </Feature>
  </Product>
</Include>

What exactly is the problem? How to cleanly uninstall apps?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Makarov, 2015-04-07
@DmitryITWorksMakarov

Managed to resolve the issue myself.
In the ApplicationShortcut component, the Guid must be unique, which means it must be recreated with each Build.

....
<Component Id="ApplicationShortcut" Guid="*">
....

Oh, and this little star drank my blood!!!

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question