为所有用户和数据访问安装

本文关键字:数据 访问 安装 用户 | 更新日期: 2023-09-27 18:19:55

修改安装程序应用程序以将我的exe和几个数据文件安装到所有用户都可以访问的位置的最佳方法是什么?我希望任何XP/Vista/Win7用户在开始菜单和桌面上都有这个选项。一旦他们运行了这个应用程序,他们就需要能够对应用程序附带的一些数据文件进行写入更改。我目前正在使用"用户配置文件漫游"数据文件夹或类似的文件夹。

为所有用户和数据访问安装

首先,您需要将安装类型更改为每台机器:

  • 在解决方案资源管理器中选择您的安装项目
  • 在其"属性"窗格中将InstallAllUsers设置为True

之后,您可以配置默认安装文件夹:

  • 转到安装项目"文件系统编辑器"
  • 选择应用程序文件夹
  • 在其"属性"窗格中将DefaultLocation设置为:

    [CommonAppDataFolder][Manufacturer]'[ProductName]

  • 在应用程序文件夹中添加文件

您可以在此处阅读有关CommonAppDataFolder的更多信息:http://msdn.microsoft.com/en-us/library/windows/desktop/aa367992(v=vs.85).aspx

最后,在文件系统编辑器中,您可以在User's Desktop文件夹中添加快捷方式。它使用DesktopFolder属性,该属性会自动解析为每台机器安装的所有用户桌面。

如果用户应该能够修改自己的数据副本,我确实会使用漫游数据文件夹,除非文件很大,这不利于漫游:无论何时启动应用程序,都要检查用户的漫游文件夹中是否存在文件。如果没有,请从程序目录中的通用只读副本为该用户创建初始副本。

OTOH,如果用户需要修改通用副本,则在程序的目录中创建一个数据子目录,并修改其安全描述符,以授予对users组的Write访问权限。下面是一些本机代码。这些代码当然应该从安装程序中执行,因为它需要管理员权限。

编辑:哎呀!我刚刚意识到我从这个前SO问题中得到了代码

#include <aclapi.h>
BOOL CreateDirectoryWithUserFullControlACL(LPCTSTR lpPath) 
{
  // Create directory
  if (!CreateDirectory(lpPath,NULL))
    return FALSE;
  // Open directory object
  HANDLE hDir = CreateFile(lpPath,READ_CONTROL|WRITE_DAC,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
  if (hDir == INVALID_HANDLE_VALUE)
    return FALSE;
  // Get current security info for the directory
  ACL* pOldDACL;
  SECURITY_DESCRIPTOR* pSD = NULL;
  GetSecurityInfo(hDir, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, &pOldDACL, NULL, (void**)&pSD);
  // Create SID for Users
  PSID pSid = NULL;
  SID_IDENTIFIER_AUTHORITY authNt = SECURITY_NT_AUTHORITY;
  AllocateAndInitializeSid(&authNt,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_USERS,0,0,0,0,0,0,&pSid);
  // Create Full Access descriptor for Users
  EXPLICIT_ACCESS ea={0};
  ea.grfAccessMode = GRANT_ACCESS;
  ea.grfAccessPermissions = GENERIC_ALL;
  ea.grfInheritance = CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE;
  ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  ea.Trustee.ptstrName = (LPTSTR)pSid;
  // Add Users' full access descriptor to the current permissions list of the directory
  ACL* pNewDACL = 0;
  DWORD err = SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL);
  if (pNewDACL!=NULL)
    SetSecurityInfo(hDir,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL, pNewDACL, NULL);
  // Clean up resources
  FreeSid(pSid);
  LocalFree(pNewDACL);
  LocalFree(pSD);
  LocalFree(pOldDACL);
  CloseHandle(hDir);
  return TRUE;
}