Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在.NET3.5中获取CSIDL_公共_文档的路径?_C#_.net_Windows_Winapi_Special Folders - Fatal编程技术网

C# 如何在.NET3.5中获取CSIDL_公共_文档的路径?

C# 如何在.NET3.5中获取CSIDL_公共_文档的路径?,c#,.net,windows,winapi,special-folders,C#,.net,Windows,Winapi,Special Folders,我正在为安装程序执行自定义操作。它必须读取存储在CSIDL\u COMMON\u文档中的文件来确定安装目录。(我希望在自定义操作中更改安装目录不会成为问题,但这是另一个问题。) 我看到.NET4在Environment.SpecialFolder中添加了CommonDocuments。不幸的是,我一直使用.NET3.5。获取此路径的下一个最简单的方法是什么?我知道的最简单的方法是p/调用,这很可能是.NET Framework内部用于检索环境.SpecialFolders值的方法 定义如下: [

我正在为安装程序执行自定义操作。它必须读取存储在
CSIDL\u COMMON\u文档中的文件来确定安装目录。(我希望在自定义操作中更改安装目录不会成为问题,但这是另一个问题。)


我看到.NET4在
Environment.SpecialFolder
中添加了
CommonDocuments
。不幸的是,我一直使用.NET3.5。获取此路径的下一个最简单的方法是什么?

我知道的最简单的方法是p/调用,这很可能是.NET Framework内部用于检索
环境.SpecialFolders
值的方法

定义如下:

[DllImport("shell32.dll"), CharSet = CharSet.Auto]
static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken,
                                  uint dwFlags, [Out] StringBuilder pszPath);
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();
}
您还需要
CSIDL\u COMMON\u文档
常量。直接从Windows标题:

const int CSIDL_COMMON_DOCUMENTS = 0x002e;
如果要在文件夹不存在时强制创建该文件夹,则需要传递
CSIDL\u标志\u CREATE
标志。其定义如下:

const int CSIDL_FLAG_CREATE = 0x8000;
可以这样称呼:

[DllImport("shell32.dll"), CharSet = CharSet.Auto]
static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken,
                                  uint dwFlags, [Out] StringBuilder pszPath);
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中已被弃用,取而代之的是(shell团队喜欢改变这些东西)。这个新函数带来了一组新的标识符;它现在使用的不是
CSIDL
值,而是
KNOWNFOLDERID
值。他们建议所有新应用程序都使用新功能

但是考虑到您的目标是.NET Framework的旧版本,并且不想升级,您可能也不需要调用最新的API函数。:-)


旧函数在WindowsVista和Windows7中仍然可以正常工作,即使它只是作为新函数的薄包装在内部实现的。如果在Windows 8中失败,您将不得不隔离代码路径,或者最终咬紧牙关升级到最新版本的.NET,该版本将为您处理所有问题。

可能的代码重复会损坏垃圾收集堆。将字符串生成器初始化为259个字符的容量。有趣的是,
System.Environment.GetFolderPath
调用
Win32Native.SHGetFolderPath
,并且没有
Win32Native.shgetKnowlderPath
(.NET FW 4.0)。