在哪里放普通的可写应用程序文件?

我认为CSIDL_COMMON_APPDATA\company\product应该是放置应用程序的所有用户共同的文件的地方,应用程序可以修改,但是,在Vista上这是一个只读的位置,除非安装程序修改(如每MSDN – http://msdn.microsoft.com/en-us/library/ms995853.aspx ),所以…什么是最好的? 修改位置的安全设置,以允许编写或使用CSIDL_COMMON_DOCUMENTS\company\product ? 也许还有第三个select?

另外,在这个地方有没有“官方”的微软推荐?

只修改AppData目录的特定子目录的安全性(这是来自您提供的链接 ):

CSIDL_COMMON_APPDATA此文件夹应该用于不是用户特定的应用程序数据。 例如,应用程序可能会将拼写检查字典,剪贴画数据库或日志文件存储在CSIDL_COMMON_APPDATA文件夹中。 这些信息不会漫游,任何人都可以使用电脑。 默认情况下,对于普通(非管理员,非权力)用户,此位置是只读的。 如果应用程序要求普通用户具有对CSIDL_COMMON_APPDATA的特定于应用程序的子目录的写入权限,则应用程序必须在应用程序安装期间显式修改该子目录上的安全性。 修改后的安全性必须记录在供应商问卷中。

下面是一个简单的示例,显示如何为Common App Data文件夹(CSIDL_COMMON_APPDATA)中的所有用户创建具有读/写权限的文件和文件夹。 任何用户都可以运行此代码,以使所有其他用户都可以写入文件和文件夹:

 #include <windows.h> #include <shlobj.h> #pragma comment(lib, "shell32.lib") // for PathAppend #include <Shlwapi.h> #pragma comment(lib, "Shlwapi.lib") #include <stdio.h> #include <aclapi.h> #include <tchar.h> #pragma comment(lib, "advapi32.lib") #include <iostream> #include <fstream> 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; } 

我觉得这个帖子可能会回答一些问题,但是对于很多人来说这似乎是个难题。

显然,CSIDL_COMMON_DOCUMENTS提供了一个通用的解决方法

Vista / UAC指南可以在这里找到。 搜索该页面的“ CSIDL ”,你会发现一些“官方”的答案。