【问题标题】:How to get the path to CSIDL_COMMON_DOCUMENTS in .NET 3.5?如何在 .NET 3.5 中获取 CSIDL_COMMON_DOCUMENTS 的路径?
【发布时间】:2011-12-22 23:19:35
【问题描述】:

我正在为安装程序进行自定义操作。它必须读取存储在CSIDL_COMMON_DOCUMENTS 中的文件以确定安装目录。 (我希望在自定义操作中更改安装目录不会成为问题,但这是一个不同的问题。)

我看到 .NET 4 将 CommonDocuments 添加到 Environment.SpecialFolder。不幸的是,我坚持使用 .NET 3.5。获得这条路径的下一个最简单的方法是什么?

【问题讨论】:

标签: c# .net windows winapi special-folders


【解决方案1】:

我知道的最简单的方法是 P/Invoke SHGetFolderPath function,这很可能是 .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(shell 团队只是喜欢改变这些东西)。这个新功能带来了一组新的标识符;它现在使用 KNOWNFOLDERID 值,而不是 CSIDL 值。他们建议所有新应用程序都使用新功能。

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

旧版本在 Windows Vista 和 7 中仍然可以正常工作,即使它只是在内部实现为新功能的薄包装。如果它在 Windows 8 中失败,您将不得不隔离代码路径,或者最后硬着头皮升级到最新版本的 .NET,它会为您处理这一切。

【讨论】:

  • 您的代码损坏了垃圾收集堆。初始化字符串生成器,使其容量为 259 个字符。
  • 有趣的是System.Environment.GetFolderPath 调用Win32Native.SHGetFolderPath 却没有Win32Native.SHGetKnownFolderPath (.NET FW 4.0)。
猜你喜欢
  • 1970-01-01
  • 2012-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-11
  • 2020-10-16
  • 1970-01-01
相关资源
最近更新 更多