Самый простой способ, который я знаю, - это P / Invoke SHGetFolderPath
функция , что весьма вероятно для внутреннего использования .NET Framework для получения значений Environment.SpecialFolders
.
Определение будет выглядеть так:
[DllImport("shell32.dll"), CharSet = CharSet.Auto]
static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken,
uint dwFlags, [Out] StringBuilder pszPath);
Вам также понадобится константа CSIDL_COMMON_DOCUMENTS
. Напрямую из заголовков Windows:
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
Если вы хотите принудительно создать папку, если она еще не существует, вам нужно будет пропустить флаг CSIDL_FLAG_CREATE
. Это определяется следующим образом:
const int CSIDL_FLAG_CREATE = 0x8000;
Назовите это так:
public static string GetCommonDocumentsFolder()
{
StringBuilder sb = new StringBuilder();
int retVal = SHGetFolderPath(IntPtr.Zero,
CSIDL_COMMON_DOCUMENTS | CSIDL_FLAG_CREATE,
IntPtr.Zero,
0,
sb);
Debug.Assert(retVal >= 0); // assert that the function call succeeded
return sb.ToString();
}
Только для вашей информации, функция SHGetFolderPath
устарела с Windows Vista в пользу SHGetKnownFolderPath
(команда разработчиков оболочки просто любит все это менять). Эта новая функция приносит новый набор идентификаторов; вместо значений CSIDL
теперь используются значения KNOWNFOLDERID
. Они рекомендуют, чтобы все новые приложения использовали новую функцию.
Но, учитывая, что вы ориентируетесь на старую версию .NET Framework и не хотите обновляться, стоит поспорить, что вам, вероятно, нет необходимости вызывать последнюю функцию API. : -)
Старый продолжает отлично работать в Windows Vista и 7, даже если он реализован внутри просто как тонкая оболочка для новой функции. Если это не удастся в Windows 8, вам придется разделить пути кода или, наконец, откусить маркер и перейти на последнюю версию .NET, которая обрабатывает все это за вас.