我见过几个与此相反的问题; “我如何禁用虚拟化?”那不是我的问题。我想强制应用程序在虚拟化启用的情况下运行。
我有一个在Windows XP下运行得很好的应用程序,但是,因为它将其配置写入其工作目录(“C:\ Program Files(x86)”的子文件夹),它在Windows 7下无法正常运行如果我使用任务管理器打开UAC虚拟化,它会保存其配置就好了,但当然它无法加载该配置。
我不想将其设置为以管理员身份运行,因为它不需要这些权限。我想将其设置为在启用UAC虚拟化的情况下运行。
我found a suggestion我在HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags
的注册表中添加了一些魔法。为了完整起见,我也把它放在Wow6432Node
中,但都没有任何效果。
答案 0 :(得分:5)
在某些情况下,文件系统是虚拟化的,那么当您的应用程序不符合条件时,您的问题是如何仍然打开它?这不太可能,MSDN:
在以下情况下,虚拟化不可用:
虚拟化不适用于已升级并使用完整管理访问令牌运行的应用程序。
虚拟化仅支持32位应用程序。非提升的64位应用程序只会在它们收到拒绝访问的消息时收到 尝试获取Windows对象的句柄(唯一标识符)。 本机Windows 64位应用程序需要兼容 UAC并将数据写入正确的位置。
如果应用程序包含具有请求的执行级别的应用程序清单,则会禁用应用程序的虚拟化 属性。
答案 1 :(得分:4)
这可能为时已晚,但我是您发现激活UAC虚拟化的建议的作者,我的帖子中有一个错误。要修改的注册表项如下:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\
(注意"图层" 附加)
所以一个完整的例子是:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="RUNASINVOKER"
请注意,必须使用空格字符分隔多个参数。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="WINXPSP3 RUNASINVOKER"
-
我真诚地感到遗憾,因为我的错误,你失去了相当多的时间。
顺便说一句,让我表达我对Ian Boyd的帖子的不同意见。有些地方不应该向所有人授予写权限,例如这一权限,因为它违反了&#34的基本安全规则;系统范围的写入应仅授权给特权主体"。 Program Files是一个系统范围的地方,而不是每个用户。
当然,所有规则都有例外,但在目前的情况下,可以想象一个恶意制作的配置文件,使程序在运行它时执行任意命令。在较轻的一面,人们可以想象一个"错误删除"由另一个用户,这将使应用程序失败。回到更重要的一面,程序文件中的应用程序可执行文件通常由管理员运行,迟早。即使您不想,卸载程序也经常运行程序文件中的卸载可执行文件。也许卸载程序将使用该配置文件,如果它被恶意制作可能会产生后果。
当然你可能会说,这听起来有些偏执,同意了。在Win XP时我确实修改了程序文件中的一些NTFS ACL,之后能够睡觉,但为什么工具可用时会有最轻微的风险?
答案 2 :(得分:2)
我找到了一个不太引用的条件,其中UAC虚拟化不起作用:Program Files
中的文件被设为只读。
也就是说,假设文件C:\Program Files\<whatever>\config.ini
被标记为只读。当应用程序尝试更改它时,UAC虚拟化将返回拒绝访问权限错误,而不是将其重新分析为%LOCALAPPDATA%\VirtualStore\<whatever>\config.ini
。
虽然我没有发现这个记录,但这种行为可能是由设计完成的,因为它有一定意义。
解决方案很简单:确保应用程序应该修改的所有文件都不是只读的(或者只是取消标记所有文件,因为用户无论如何都无法更改它们。)
答案 3 :(得分:0)
您有一个应用程序,并且想要用户能够修改默认 的位置中的注册表项或文件,只有管理员可以修改。
如果您运行的是Windows 2000,Windows XP,Windows Vista,Windows 7或Windows 8,则解决方案是相同的:
例如,如果您的程序需要修改以下文件:
C:\Program Files\Blizzard\World of Warcraft
然后更正操作 以更改World of Warcraft
文件夹的权限。事实上,这是微软应用于魔兽世界的垫片。 (在下一次运行时,它将Everyone完全控制权授予该文件夹 - 无论用户登录什么,WoW如何自行更新。)
如果您希望用户能够修改某个位置的文件:您必须授予他们权限。如果您是标准用户试图在 Windows XP 上运行WoW,您将遇到同样的问题 - 并且需要应用相同的解决方案。
您的应用程序正在将其配置写入:
C:\Program Files (x86)\Hyperion Pro\preferences.ini
然后您实际上执行想要将用户 完全控制授予该文件:
所以你的:
Configuration.ini
授予权限并不是件坏事;这就是你管理服务器的方式。
有两种解决方案:
C:\ProgramData\Contoso\Preferences.ini
并在安装时对其进行ACL C:\Program Files\Contoso\Preferences.ini
并在安装时对其进行ACL 如果你看看微软的AppCompat人员的指导:
Where Should I Write Program Data Instead of Program Files?
常见的应用程序代码更新是:“我的应用程序用于将文件写入程序文件。感觉就像把它放在任何其他地方一样好。它已经有我的应用程序名称,因为我的用户是管理员,它工作正常。但是现在我发现这可能不像我曾经想过的那样强大,因为UAC甚至管理员大多数时候都使用标准的类似用户的权限。那么,我应该在哪里放置我的文件呢?“
<强> FOLDERID_ProgramData 强>
用户永远不想在资源管理器中浏览此处,此处更改的设置应该影响计算机上的每个用户。默认位置是%systemdrive%ProgramData,它是Windows Vista安装中的隐藏文件夹。 您需要创建目录并在安装时设置所需的ACL。
所以你有两个解决方案:
唯一的区别是语义。 程序文件文件夹是程序文件的意思。您不想在此处存储数据。
有时机器会反复使用相同的程序文件进行成像。您不希望图像中的每台机器数据。该数据属于 ProgramData 。
这不是安全问题。
有些人必须了解安全边界的位置。
答案 4 :(得分:0)
在其他答案中有很多优点。
其实我都赞成。
因此,让我们将所有 combine 组合在一起,并 add 还有更多方面...
OP提到了一些“过去的遗留应用程序”。
因此我们可以假设它是x86(32位),并且不也没有包含任何清单(尤其是未指定任何“ requestedExecutionLevel”)。
-
Roman R.对于x64
和manifest
文件有很好的回答:
https://stackoverflow.com/a/8853363/1468842
但所有这些条件似乎都不适用于这种情况。
NovHak在他的答案中概述了一些AppCompatFlags
和RUNASIVOKER
:
https://stackoverflow.com/a/25903006/1468842
迭戈·奎罗斯(Diego Queiroz)在他的回答中添加了有关read-only
标志的有趣方面:
https://stackoverflow.com/a/42934048/1468842
伊恩·博伊德(Ian Boyd)指出,您甚至不应该进行这种“虚拟化”,而应根据ACL
在那些感兴趣的文件(例如“ config.ini”)上进行设置:
https://stackoverflow.com/a/12940213/1468842
这是附加/新方面:
可以将policy
设置为禁用所有虚拟化-系统范围内:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
"EnableVirtualization"=dword:00000000
实际上,我在我拥有的每个系统上都执行此策略。
因为否则会导致在multi-user
环境中产生混乱的行为。
UserA在其中进行了一些更改,一切正常。
但随后UnserB不会不获取UserA完成的更改。
万一某些老套的软件失败了,那就应该“失败”!
而不是说一切都很好。
恕我直言,“虚拟化”是微软有史以来最糟糕的设计决定。
那么也许系统启用了此策略,这就是为什么虚拟化对您不起作用的原因?
-
,所以最终的检查清单可能是:
requestedExecutionLevel
)?EnableVirtualization
强制设为0
?RUNASIVOKER
尝试了 AppCompatFlags ?-
最后,我们将讨论如何运行旧的旧版应用程序。
通过使用我们可以想到的任何变通方法和技巧。
可能应该在superuser
或serverfault
上对此进行更好的讨论。
在stackoverflow
(针对programmers
的目标)中我们都知道:现在是时候让我们自己的所有程序都与UAC概念兼容,以及如何以“正确”的方式实现事物了- “方式:)