我正在为安装程序制作自定义操作。必须读取存储在CSIDL_COMMON_DOCUMENTS
中的文件以确定安装目录。(我希望在自定义操作中更改安装目录不会成为问题,但这是另一个问题。)
我发现.NET 4将CommonDocuments
添加到Environment.SpecialFolder
中。不幸的是,我被困在.NET 3.5中。有什么下一个最简单的方法来获取此路径吗?
我正在为安装程序制作自定义操作。必须读取存储在CSIDL_COMMON_DOCUMENTS
中的文件以确定安装目录。(我希望在自定义操作中更改安装目录不会成为问题,但这是另一个问题。)
我发现.NET 4将CommonDocuments
添加到Environment.SpecialFolder
中。不幸的是,我被困在.NET 3.5中。有什么下一个最简单的方法来获取此路径吗?
我知道的最简单的方法是使用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();
}
仅供参考,自Windows Vista起,SHGetFolderPath
函数已被弃用,取而代之的是SHGetKnownFolderPath
(外壳团队喜欢改变这些东西)。新函数带来了一组新的标识符;现在它使用KNOWNFOLDERID
值,而不是CSIDL
值。他们建议所有新应用程序使用新函数。
但考虑到您正在针对旧版本的.NET Framework并且不想升级,您可能根本没有必要调用最新的API函数。 :-)
旧函数在Windows Vista和7中仍然可以正常工作,即使它在内部实现只是新函数的薄包装器。如果在Windows 8中失败,则必须隔离代码路径,或最终咬紧牙关升级到最新版本的.NET,它会为您处理所有内容。
System.Environment.GetFolderPath
调用了 Win32Native.SHGetFolderPath
,但在 .NET FW 4.0 中没有 Win32Native.SHGetKnownFolderPath
。 - Jeroen Wiert Pluimers