安装所有用户和数据访问

时间:2012-01-09 22:52:10

标签: c# installer

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

2 个答案:

答案 0 :(得分:1)

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

  • 在解决方案资源管理器中选择您的安装项目
  • 在其“属性”窗格中将 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属性,该属性会自动解析为每台计算机安装的所有用户桌面。

答案 1 :(得分:0)

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

OTOH,如果用户需要修改公共副本,则在程序目录中创建一个数据子目录,并修改其安全描述符,以便为Users组提供Write访问权限。这是一些本地代码。当然,这段代码应该从安装程序执行,因为它需要管理员权限。

编辑:哎呀!我只是意识到我从前SO question获得了代码。

#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;
}