安装所有用户和数据访问

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

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

  • 在Solution Explorer中选择您的安装项目
  • 在其“属性”窗格中,将InstallAllUsers设置为True

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

  • 转到您的安装项目文件系统编辑器
  • 选择Application Folder
  • 在其“属性”窗格中将DefaultLocation设置为:

    [CommonAppDataFolder][Manufacturer]\[ProductName]

  • 在Application Folder中添加文件

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

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

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

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

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

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