我认为这CSIDL_COMMON_APPDATA\company\product
应该是放置应用程序的所有用户和应用程序可以修改的文件的地方,但是,在Vista上这是一个只读位置,除非安装程序修改(根据MSDN - http: //msdn.microsoft.com/en-us/library/ms995853.aspx),那么......什么是最好的?修改位置的安全设置以允许编写或使用CSIDL_COMMON_DOCUMENTS\company\product
?也许还有第三种选择?
此外,微软是否有某个"官方"推荐?
仅修改AppData目录的特定子目录上的安全性(这来自您提供的链接):
CSIDL_COMMON_APPDATA此文件夹应该用于非用户特定的应用程序数据.例如,应用程序可以在CSIDL_COMMON_APPDATA文件夹中存储拼写检查字典,剪贴画数据库或日志文件.此信息不会漫游,并且可供使用该计算机的任何人使用.默认情况下,此位置对于普通(非管理员,非电源)用户是只读的.如果应用程序要求普通用户具有对CSIDL_COMMON_APPDATA的特定于应用程序的子目录的写访问权限,则应用程序必须在应用程序设置期间显式修改该子目录的安全性.修改后的安全性必须记录在供应商调查问卷中.
下面是一个简单示例,说明如何为Common App Data文件夹(CSIDL_COMMON_APPDATA)中的所有用户创建具有读/写权限的文件和文件夹.任何用户都可以运行此代码,以授予所有其他用户写入文件和文件夹的权限:
#include#include #pragma comment(lib, "shell32.lib") // for PathAppend #include #pragma comment(lib, "Shlwapi.lib") #include #include #include #pragma comment(lib, "advapi32.lib") #include #include using namespace std; int _tmain(int argc, _TCHAR* argv[]) { DWORD dwRes, dwDisposition; PSID pEveryoneSID = NULL; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; SECURITY_ATTRIBUTES sa; // Create a well-known SID for the Everyone group. if (!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) { _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError()); goto Cleanup; } // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow Everyone access to files & folders you create. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = 0xFFFFFFFF; ea.grfAccessMode = SET_ACCESS; // both folders & files will inherit this ACE ea.grfInheritance= CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID; // Create a new ACL that contains the new ACEs. dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL); if (ERROR_SUCCESS != dwRes) { _tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError()); goto Cleanup; } // Initialize a security descriptor. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (NULL == pSD) { _tprintf(_T("LocalAlloc Error %u\n"), GetLastError()); goto Cleanup; } if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { _tprintf(_T("InitializeSecurityDescriptor Error %u\n"), GetLastError()); goto Cleanup; } // Add the ACL to the security descriptor. if (!SetSecurityDescriptorDacl(pSD, TRUE, // bDaclPresent flag pACL, FALSE)) // not a default DACL { _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"), GetLastError()); goto Cleanup; } // Initialize a security attributes structure. sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; TCHAR szPath[MAX_PATH]; if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, szPath))) { PathAppend(szPath, TEXT("Your Shared Folder")); if (!CreateDirectory(szPath, &sa) && GetLastError() != ERROR_ALREADY_EXISTS) { goto Cleanup; } PathAppend(szPath, TEXT("textitup.txt")); HANDLE hFile = CreateFile(szPath, GENERIC_READ | GENERIC_WRITE, 0, &sa, CREATE_ALWAYS, 0, 0); if (hFile == INVALID_HANDLE_VALUE) goto Cleanup; else CloseHandle(hFile); //TODO: do the writing ofstream fsOut; fsOut.exceptions(ios::eofbit | ios::failbit | ios::badbit); fsOut.open(szPath, ios::out | ios::binary | ios::trunc); fsOut << "Hello world!\n"; fsOut.close(); } Cleanup: if (pEveryoneSID) FreeSid(pEveryoneSID); if (pACL) LocalFree(pACL); if (pSD) LocalFree(pSD); return 0; }