对于我已排序的一些应用程序,App-V 似乎正好能使应用程序正常运行。然而,在其他情况下,我发现一些本应驻留在本地文件系统上的文件被虚拟化了。这是一个问题,因为这些文件无法在虚拟化应用程序的“修复”中幸存下来。
我以为将 VFS 文件夹设置为合并模式将允许应用程序写入本地文件系统。然而,简单的测试表明情况似乎并非如此。显然,必须有规则规定从本地文件系统(而不是 VFS)读取和写入哪些文件。
在什么条件下 App-V 应用程序会读取或写入本地文件系统?
答案1
总结
本地文件系统上存在的文件能当相应的 VFS 文件夹处于“合并”模式时可被虚拟化应用程序看到或者VFS 中没有提到相应的文件夹。但是,相同的文件不能当相应的 VFS 文件夹处于“覆盖”模式时可以看到。
仅当以下两个条件都满足时,虚拟化应用程序才会写入本地文件系统:
- VFS 中未提及写入文件的文件夹,并且
- 本地文件系统中存在写入文件的文件夹
我找不到权威文献来回答这个问题。我找到的最接近的信息是Kalle Saunamäki 的 2011 年博客文章关于 App-V 4.6。事实证明,那篇文章不仅只是从表面来看是正确的,而且 App-V 5.x 的行为似乎也至少在一种情况下发生了变化(即 App-V 5.x 似乎不再在本地文件系统上创建丢失的合并模式 VFS 文件夹,而 Kalle 似乎发现 4.6 会这样做)。
实证检验
我的粗略实验只是导致了令人困惑的结果,所以我决定进行一些更正式的测试来彻底解决这个问题。
设置
测试涉及在以下每个阶段创建文件:
- A:测序之前
- B:在测序仪内部测序期间
- C:出版前
- D:从应用程序内的虚拟进程发布后
在排序结束时,VFS 如何应用于文件夹有三种可能的情况:
- 覆盖模式
- 合并模式
- 未提及
在发布阶段,每个本地和虚拟文件系统中都可以创建或不创建任何给定的文件夹。一共有四种可能性。
VFS 的三种应用方式与四种发布可能性相结合,产生了我测试的 12 种情况。我使用了一些脚本来自动执行此操作并(希望)避免错误。这些脚本位于本文末尾。
结果
从序列器 UI 看到的 VFS 如下:
我检查了已发布应用程序气泡内部和外部的脚本编写的每个文件是否存在。结果如下表所示:
分析
根据该表,以下陈述似乎成立:
- 正在运行的虚拟化应用程序可以查看由该应用程序创建的所有文件。这并不奇怪,因为这是应用程序正常运行所必需的。
- 当相应的 VFS 文件夹处于“覆盖”模式时,虚拟化应用程序无法看到本地文件系统上存在的文件。
- 本地文件系统上存在的文件能当相应的 VFS 文件夹处于“合并”模式时可被虚拟化应用程序看到或者VFS 中没有提到相应的文件夹。
- 虚拟化应用程序写入本地文件系统的唯一情况是以下两个条件都成立时:
- VFS 中未提及写入文件的文件夹,并且
- 本地文件系统中存在写入文件的文件夹
脚本
测序前.ps1
$splat = @{
Cases = 4..11
FolderName = 'ExistsBeforeSequencing'
FileName = 'ExistsBeforeSequencing'
Mode = 'Create'
}
.\Alter-Folders.ps1 @splat
B-测序过程中.ps1
$splats = @(
@{
Cases = 0..3
FolderName = 'CreatedDuringSequencing'
FileName = 'CreatedDuringSequencing'
Mode = 'Create'
},
@{
Cases = 4..7
FolderName = 'ExistsBeforeSequencing'
FileName = 'CreatedDuringSequencing'
Mode = 'Create'
}
)
$splats |
% { .\Alter-Folders.ps1 @_ }
C-发布前.ps1
$splats = @(
@{
Cases = 0..3
FolderName = 'CreatedDuringSequencing'
Mode = 'Remove'
}
@{
Cases = 4..11
FolderName = 'ExistsBeforeSequencing'
Mode = 'Remove'
}
@{
Cases = 1,3
FolderName = 'CreatedDuringSequencing'
FileName = 'CreatedBeforePublishing'
Mode = 'Create'
}
@{
Cases = 5,7,9,11
FolderName = 'ExistsBeforeSequencing'
FileName = 'CreatedBeforePublishing'
Mode = 'Create'
}
)
$splats |
% { .\Alter-Folders.ps1 @_ }
D-应用程序-正在运行.ps1
$splats = @(
@{
Cases = 2,3
FolderName = 'CreatedDuringSequencing'
FileName = 'CreatedByRunningApp'
Mode = 'Create'
}
@{
Cases = 6,7,10,11
FolderName = 'ExistsBeforeSequencing'
FileName = 'CreatedByRunningApp'
Mode = 'Create'
}
)
$splats |
% { .\Alter-Folders.ps1 @_ }
更改文件夹.ps1
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)]
[int32[]]
$cases,
[parameter(Mandatory=$true)]
[string]
$FolderName,
[string]
$FileName,
[parameter(Mandatory=$true)]
[string]
[ValidateSet('create','remove')]
$mode
)
$path = $env:ProgramData
if ( 'create' -eq $mode )
{
$cases |
% {
New-Item "$path\$FolderName$_" -ItemType Directory | Out-Null
New-Item "$path\$FolderName$_\$FolderName$_-1" -ItemType Directory | Out-Null
$filePath = "$path\$FolderName$_\$FolderName$_-1\$FileName$_-1.txt"
$filePath | Out-File $filePath
}
}
if ( 'remove' -eq $mode )
{
$cases |
% {
Remove-Item "$path\$FolderName$_" -Recurse -Force
}
}