有没有办法防止Delphi应用程序在不启用运行时主题的情况下在Vista/Win 7上使用虚拟存储?
这个问题几乎说明了一切 如果启用了运行时主题,我有一个带有旧组件的应用程序无法正常工作。但如果我不启用它们,应用程序最终总是会弄乱虚拟商店 谢谢 更新:有没有办法防止Delphi应用程序在不启用运行时主题的情况下在Vista/Win 7上使用虚拟存储?,delphi,Delphi,这个问题几乎说明了一切 如果启用了运行时主题,我有一个带有旧组件的应用程序无法正常工作。但如果我不启用它们,应用程序最终总是会弄乱虚拟商店 谢谢 更新: 使用下面Mark的解决方案,应用程序不再写入虚拟存储。但是,现在它无法访问它所需要的tdb文件(微小的数据库文件)。此tdb文件与写入虚拟存储的文件相同。关于如何让它访问tdb文件,并且仍然阻止写入虚拟存储,有什么想法吗 您需要向exe添加清单(资源) 清单中有一个XML资源,其内容类似于下面的内容。TrustInfo是导致不使用Virtual
使用下面Mark的解决方案,应用程序不再写入虚拟存储。但是,现在它无法访问它所需要的tdb文件(微小的数据库文件)。此tdb文件与写入虚拟存储的文件相同。关于如何让它访问tdb文件,并且仍然阻止写入虚拟存储,有什么想法吗 您需要向exe添加清单(资源) 清单中有一个XML资源,其内容类似于下面的内容。TrustInfo是导致不使用VirtualStore的关键部分 此示例引用了Microsoft.Windows.Common-Controls程序集,该程序集启用运行时主题。如果您从清单中删除它,您仍然可以保留TrustInfo部分 Vista使用TrustInfo确定应用程序“知道”UAC限制,而不将VirtualStore用于该应用程序
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="Delphi 7"
version="7.1.0.0"
processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
以及应用程序清单架构上的Microsoft页面:
当然,一旦执行此操作,在UAC打开的情况下,您将无法再将数据写入c:\program files\或其他受保护的位置。这就是微软最初创建虚拟商店的原因。它旨在使旧应用程序保持运行,以便能够写入这些(现在受保护的)位置
您有几个不同的选择:
1:更改文件位置
将tdb文件移动到其他位置。这是一种理想的情况,但可能需要更改最多的代码。有关一些建议,请参见问题“”。Microsoft建议将用户未命名的数据存储在“应用程序数据”文件夹下。我尝试过这个方法,但这让用户很难找到数据并将其移动到另一台计算机。我已将所有用户数据(即使用户未专门保存该文件)移动到“我的文档”文件夹中。这样一来,当他们得到一台新电脑时,他们就可以移动“我的文档”(大多数都可以),我的所有应用程序数据也会移动
2:更改文件的权限,以允许标准用户读取/写入文件。您的安装程序可以这样做,或者您可以在事后对其进行更新,但您需要以管理员身份运行才能进行更改
3:强制应用程序以管理员身份运行。如果按照Sertac的说明将执行级别设置为“requireAdministrator”,则可以写入文件,但用户每次运行应用程序时都会收到UAC提升提示
还请注意,如果您正在升级一直在运行并将数据保存到虚拟存储的用户,则不会自动将数据移动到新位置。将清单添加到应用程序后,它将开始看到实际位于c:\program files*下的文件。您可能需要在虚拟存储中查找文件,并将其复制到用户的新位置。下面是一个例子。在我的例子中,许可证文件存储在安装目录下。升级应用程序后,我需要查找旧许可证文件并将其移动到新位置:
procedure TResetMain.CopyVirtFiles();
var
VirtLicDir: string;
NewLicDir: string;
FileOp: TSHFileOp;
TempPath : array[0..MAX_PATH] of Char;
begin
SHGetFolderPath(Application.Handle, CSIDL_LOCAL_APPDATA, 0, 0, TempPath);
VirtLicDir := TempPath + '\VirtualStore\Program Files\My Company\Licenses';
NewLicDir := GetMyConfigDir();
if NewLicDir <> '' then
begin
NewLicDir := IncludeTrailingPathDelimiter(NewLicDir) + 'User Licenses';
end;
// If the Virtual license directory exists but not the new directory we
// know this is the first time the updated application has been run
// and we need to move the files to the correct location.
if DirectoryExists(VirtLicDir) and Not DirectoryExists(NewLicDir) then
begin
ForceDirectories(NewLicDir);
FileOp := TSHFileOp.Create(nil);
FileOp.FileList.Add(VirtLicDir + '\*.*');
FileOp.Destination := NewLicDir;
FileOp.Action := faMove;
FileOp.SHOptions := [ofFilesOnly, ofNoConfirmation, ofNoConfirmMKDir, ofRenameOnCollision, ofSilent];
FileOp.Execute;
FreeAndNil(FileOp);
end;
end;
过程TResetMain.CopyVirtFiles();
变量
VirtLicDir:字符串;
NewLicDir:字符串;
FileOp:TSHFileOp;
TempPath:字符的数组[0..MAX_PATH];
开始
SHGetFolderPath(Application.Handle,CSIDL_LOCAL_APPDATA,0,0,TempPath);
VirtLicDir:=TempPath+'\VirtualStore\Program Files\My Company\Licenses';
NewLicDir:=GetMyConfigDir();
如果NewLicDir为“”,则
开始
NewLicDir:=IncludeTrailingPathDelimiter(NewLicDir)+“用户许可证”;
结束;
//如果虚拟许可证目录存在,但新目录不存在,则
//知道这是第一次运行更新的应用程序
//我们需要将文件移动到正确的位置。
如果存在目录(VirtLicDir)而不存在目录(NewLicDir),则
开始
ForceDirectories(NewLicDir);
FileOp:=TSHFileOp.Create(nil);
FileOp.FileList.Add(VirtLicDir+'\*.*');
FileOp.Destination:=NewLicDir;
FileOp.Action:=faMove;
FileOp.SHOptions:=[OfficeOnly、OfNoconfirm、OfNoconfirmkDir、OfNameOnCollision、ofSilent];
FileOp.Execute;
FreeAndNil(FileOp);
结束;
结束;
马克的一些替代方案
- 右键单击并选择“以管理员身份运行”
- 修改应用程序的兼容性属性,以包括“以管理员身份运行此程序”
- 重命名可执行文件,使其包含“安装”、“更新”、“安装”、“修补程序”等词语之一
- 在版本信息中包含上述词语之一,例如将“Internal Name”设置为“MyApplication install”。细节
- 如果UAC对话框或运行提升版不可接受,请修改应用程序需要写入的文件夹或文件的权限。例如,如果组件正在“MyApplication\Logs”上删除日志文件,请在“Logs”上设置安全性,以便“Everyone”可以“完全控制”文件夹。不要忘记删除“.\AppData\VirtualStore\Program Files\MyApplication\Logs”以使其生效
不确定您称之为虚拟存储。你是说虚拟存储以及访问注册表和文件夹时出现问题吗?是的,我的意思是虚拟存储……我不明白视觉主题和虚拟存储是以何种方式关联的……不确定这种关系,但是启用了运行时主题的delphi应用程序将不会使用虚拟存储。@croceldon:不,这不是真的。任何试图将文件保存到C:\Program Files\目录(例如)的应用程序都会在不知不觉中写入C:\Users\\AppData\VirtualSt