Windows 安装程序将 ROOTDRIVE 评估为可用内存较少的本地驱动器 space => 为什么?
Windows Installer evaluates ROOTDRIVE to local drive with less free memory space => why?
互联网上的许多页面和有关 Windows 安装程序的书籍都引用了以下 Microsoft 页面 ROOTDRIVE:
If ROOTDRIVE is not set at a command line or authored into the Property table, the installer sets this property. During an administrative installation the installer sets ROOTDRIVE to the first connected network drive it finds that can be written to. If it is not an administrative installation, or if the installer can find no network drives, the installer sets ROOTDRIVE to the local drive that can be written to having the most free space.
好吧,在我客户的机器上 C:
比 Y:
有更多的免费 space,但是应用程序安装到 Y:\MyApp
而不是 C:\Program Files (x86)\MyApp
].当然,WiX 和 Directory 结构是标准样式的:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="$(var.CompanyName)">
<Directory Id="MyAppFolder" Name="MyApp" />
</Directory>
</Directory>
</Directory>
所以没什么特别的。在其他机器上,它按预期安装到 Program Files
文件夹。
根据我的日常经验,"most free space" 的规则不可能是真的,因为在我处理的许多机器上都有一个相当小的 SSD,如 C:
本地驱动器和一个大得多的数据驱动器 D:
,可用的 TB 数 space 比 C:
。如果该规则适用,那么如今大多数计算机会将(所有)应用程序安装到其数据驱动器根目录(例如 D:\
),而不是在受特别保护的 %ProgramFiles%
/%ProgramFiles (x86)%
文件夹。在我所有配置小型 SSD 和配置更多 space 的大数据 HDD 的机器上,所有东西都安装到我预期的 Program Files
文件夹中 C:
。所以 "most free space" 的规则肯定是 NOT TRUE!!!并且 MSI 并没有特别在命令行上定义任何 TARGETDIR
或 ROOTDIR
属性 到 C:\
,在任何情况下 MSI table 都没有!
所以必须有另一个评估规则。哪一个?谁能解释这种奇怪的行为?
编辑
感谢 Stein,我仔细查看了日志,发现 ROOTDRIVE
实际上确实指向较大的本地磁盘,但由于 系统文件夹属性 它总是安装在 系统驱动器 上的正确位置。我在问这个问题时也查看了日志文件是来自戴尔数据保护的日志文件,它明确必须将 ROOTDRIVE
设置为 C:\
或系统驱动器。因此,来自 MSDN 的 ROOTDRIVE
规则似乎是正确的,但在大多数情况下它没有任何效果。
当我自己查看有问题的计算机时,我看到 Y: 是一个网络驱动器,然后我搜索了 ADMIN et voilà 这个词:这是一个管理安装,尽管我的客户告诉我他只是双击了 MSI 和 Y:是一个本地驱动器 => 今年我对节日的不满是,一个人不应该永远相信顾客说的话和誓言 ;-)
System Folder Properties:我想答案可以在这个找到Symantec Article. Essentially: System Folder Properties不受ROOTDRIVE影响属性.
顺便说一下,我的 D:\
驱动器比我的 C:\
驱动器有更多 space,并且 ROOTDRIVE
在 MSI 日志文件中设置为 D:\
。尽管安装不会将文件写入 D:\
。我认为这是由于 C:\
?
上的充足 space
更新:同时检查the documentation on TARGETDIR,重点关注此部分:
"...if the TARGETDIR property is defined, the destination directory
is resolved to the property's value. If the TARGETDIR property is
undefined, the ROOTDRIVE property is used to resolve the path."
问题计算机:以上内容并没有真正解释您的问题计算机上发生的情况,对吗?你有没有手动安装到这个自定义位置?您是否使用了 "Remember Property" pattern to persist the installation folder? It must be reading back that old path? Or maybe the disk is very low on space? Or are you installing using an admin image? AdminProperties. No Set Property custom actions in there? Could there be constructs in the GUI that could affect this? I know set property is used in some of WiX's default GUI sets. And you can make directories modifiable as "feature directories". See the screenshot down the page here.
Verbose Log:我建议你在安装到辅助驱动器的系统上创建一个日志文件,并检查什么一般情况下,有关 ROOTDRIVE 和目录解析的日志已写入日志。在目标计算机统一的企业环境中,许多实际上是硬编码 ROOTDRIVE
到 C:\
- 不是很好,但它们确实如此。他们不会那样做,除非他们试图按照您描述的方式避免一些随机的副作用。
Festivus Grievance:我一直不喜欢ROOTDRIVE这个问题,老实说从来没有完全理解它。我听到你换句话说。这实际上是我对 MSI 的 Festivus 不满之一。我回答了吗?并不真地 :-)。你至少有一些指示。也许 WiX 家伙、Chris Painter 或 PhilDW 可以提供完整的答案。
Do Not Use the below construct:
<!--ROOTDRIVE explicitly set to prevent it from defaulting to drive with most space-->
<Property Id="ROOTDRIVE" Value="$(env.SystemDrive)" />
<!-- NO SOLUTION -->
以上将是编译时解析,而不是文件夹的运行时解析。换句话说,它根本不是解决方案。 ROOTDRIVE 将设置为构建计算机的系统盘符,而不是您安装到的计算机的盘符。
Construct you can try to force ROOTDRIVE to be set to the system drive:
<CustomAction Id='SetRootDrive' Property='ROOTDRIVE' Value='[%SystemDrive]\' />
<InstallUISequence>
<Custom Action="SetRootDrive" Before="CostInitialize"></Custom>
</InstallUISequence>
部分链接:
- In WiX files, what does Name="SourceDir" refer to?
互联网上的许多页面和有关 Windows 安装程序的书籍都引用了以下 Microsoft 页面 ROOTDRIVE:
If ROOTDRIVE is not set at a command line or authored into the Property table, the installer sets this property. During an administrative installation the installer sets ROOTDRIVE to the first connected network drive it finds that can be written to. If it is not an administrative installation, or if the installer can find no network drives, the installer sets ROOTDRIVE to the local drive that can be written to having the most free space.
好吧,在我客户的机器上 C:
比 Y:
有更多的免费 space,但是应用程序安装到 Y:\MyApp
而不是 C:\Program Files (x86)\MyApp
].当然,WiX 和 Directory 结构是标准样式的:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="$(var.CompanyName)">
<Directory Id="MyAppFolder" Name="MyApp" />
</Directory>
</Directory>
</Directory>
所以没什么特别的。在其他机器上,它按预期安装到 Program Files
文件夹。
根据我的日常经验,"most free space" 的规则不可能是真的,因为在我处理的许多机器上都有一个相当小的 SSD,如 C:
本地驱动器和一个大得多的数据驱动器 D:
,可用的 TB 数 space 比 C:
。如果该规则适用,那么如今大多数计算机会将(所有)应用程序安装到其数据驱动器根目录(例如 D:\
),而不是在受特别保护的 %ProgramFiles%
/%ProgramFiles (x86)%
文件夹。在我所有配置小型 SSD 和配置更多 space 的大数据 HDD 的机器上,所有东西都安装到我预期的 Program Files
文件夹中 C:
。所以 "most free space" 的规则肯定是 NOT TRUE!!!并且 MSI 并没有特别在命令行上定义任何 TARGETDIR
或 ROOTDIR
属性 到 C:\
,在任何情况下 MSI table 都没有!
所以必须有另一个评估规则。哪一个?谁能解释这种奇怪的行为?
编辑
感谢 Stein,我仔细查看了日志,发现 ROOTDRIVE
实际上确实指向较大的本地磁盘,但由于 系统文件夹属性 它总是安装在 系统驱动器 上的正确位置。我在问这个问题时也查看了日志文件是来自戴尔数据保护的日志文件,它明确必须将 ROOTDRIVE
设置为 C:\
或系统驱动器。因此,来自 MSDN 的 ROOTDRIVE
规则似乎是正确的,但在大多数情况下它没有任何效果。
当我自己查看有问题的计算机时,我看到 Y: 是一个网络驱动器,然后我搜索了 ADMIN et voilà 这个词:这是一个管理安装,尽管我的客户告诉我他只是双击了 MSI 和 Y:是一个本地驱动器 => 今年我对节日的不满是,一个人不应该永远相信顾客说的话和誓言 ;-)
System Folder Properties:我想答案可以在这个找到Symantec Article. Essentially: System Folder Properties不受ROOTDRIVE影响属性.
顺便说一下,我的 D:\
驱动器比我的 C:\
驱动器有更多 space,并且 ROOTDRIVE
在 MSI 日志文件中设置为 D:\
。尽管安装不会将文件写入 D:\
。我认为这是由于 C:\
?
更新:同时检查the documentation on TARGETDIR,重点关注此部分:
"...if the TARGETDIR property is defined, the destination directory is resolved to the property's value. If the TARGETDIR property is undefined, the ROOTDRIVE property is used to resolve the path."
问题计算机:以上内容并没有真正解释您的问题计算机上发生的情况,对吗?你有没有手动安装到这个自定义位置?您是否使用了 "Remember Property" pattern to persist the installation folder? It must be reading back that old path? Or maybe the disk is very low on space? Or are you installing using an admin image? AdminProperties. No Set Property custom actions in there? Could there be constructs in the GUI that could affect this? I know set property is used in some of WiX's default GUI sets. And you can make directories modifiable as "feature directories". See the screenshot down the page here.
Verbose Log:我建议你在安装到辅助驱动器的系统上创建一个日志文件,并检查什么一般情况下,有关 ROOTDRIVE 和目录解析的日志已写入日志。在目标计算机统一的企业环境中,许多实际上是硬编码 ROOTDRIVE
到 C:\
- 不是很好,但它们确实如此。他们不会那样做,除非他们试图按照您描述的方式避免一些随机的副作用。
Festivus Grievance:我一直不喜欢ROOTDRIVE这个问题,老实说从来没有完全理解它。我听到你换句话说。这实际上是我对 MSI 的 Festivus 不满之一。我回答了吗?并不真地 :-)。你至少有一些指示。也许 WiX 家伙、Chris Painter 或 PhilDW 可以提供完整的答案。
Do Not Use the below construct:
<!--ROOTDRIVE explicitly set to prevent it from defaulting to drive with most space-->
<Property Id="ROOTDRIVE" Value="$(env.SystemDrive)" />
<!-- NO SOLUTION -->
以上将是编译时解析,而不是文件夹的运行时解析。换句话说,它根本不是解决方案。 ROOTDRIVE 将设置为构建计算机的系统盘符,而不是您安装到的计算机的盘符。
Construct you can try to force ROOTDRIVE to be set to the system drive:
<CustomAction Id='SetRootDrive' Property='ROOTDRIVE' Value='[%SystemDrive]\' />
<InstallUISequence>
<Custom Action="SetRootDrive" Before="CostInitialize"></Custom>
</InstallUISequence>
部分链接:
- In WiX files, what does Name="SourceDir" refer to?