问题描述
我想提出一个安装程序自定义操作。它必须读取存储在 CSIDL_COMMON_DOCUMENTS文件
确定安装目录。 (我希望它不会成为一个问题来更改自定义操作的安装目录,但是这是一个不同的问题。)
I am making a custom action for an installer. It must read a file stored in CSIDL_COMMON_DOCUMENTS
to determine the install directory. (I'm hoping it won't be an issue to change the install directory in a custom action, but that's a different question.)
我看到.NET 4中添加 CommonDocuments
到 Environment.SpecialFolder
。不幸的是,我坚持了.NET 3.5。什么是让这条道路的下一个最简单的方法是什么?
I see that .NET 4 added CommonDocuments
to Environment.SpecialFolder
. Unfortunately, I'm stuck with .NET 3.5. What's the next easiest way to get this path?
推荐答案
我所知道的最简单的方法是将P /调用的,这极有可能是.NET Framework使用何种内部检索 Environment.SpecialFolders
值。
The easiest way I know of is to P/Invoke the SHGetFolderPath
function, which is very likely what the .NET Framework uses internally to retrieve the Environment.SpecialFolders
values.
的定义是这样的:
[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头:
You'll also need the CSIDL_COMMON_DOCUMENTS
constant. Direct from the Windows headers:
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
如果你想的动力的,如果它不存在,创建文件夹,你需要通过 CSIDL_FLAG_CREATE
标志。被定义如下:
If you want to force the creation of the folder if it does not already exist, you'll need to pass the CSIDL_FLAG_CREATE
flag. That is defined as follows:
const int CSIDL_FLAG_CREATE = 0x8000;
这样称呼它:
Call it like this:
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
功能已经支持的(外壳队只是喜欢改变这些周围的事物)。这个新功能带来了一个新的组标识符;而不是 CSIDL
值,它现在使用 KNOWNFOLDERID
值。他们建议,所有新的应用程序使用新的功能。
Just for your information, the SHGetFolderPath
function has been deprecated as of Windows Vista in favor of SHGetKnownFolderPath
(the shell team just loves to change these things around). That new function brings with it a new set of identifiers; instead of CSIDL
values, it now uses KNOWNFOLDERID
values. They recommend that all new applications use the new function.
但考虑到你的目标是旧版本的.NET Framework,不想升级,这是一个不错的选择,你可能没有必要调用最新的API函数,无论是。 : - )
But considering that you're targeting an old version of the .NET Framework and don't want to upgrade, it's a good bet that you probably have no need to call the latest API function, either. :-)
老一继续工作就好在Windows Vista和7,即使它内部实施仅仅作为一种瘦包装过的新功能。如果它不能在Windows 8中,你必须隔离的code路径,终于还是硬着头皮升级到最新版本的.NET中,负责处理这一切给你。
The old one continues to work just fine in Windows Vista and 7, even if it's implemented internally merely as a thin wrapper over the new function. If it fails in Windows 8, you'll have to segregate your code paths, or finally bite the bullet and upgrade to the latest version of .NET, which handles it all for you.
这篇关于如何获得在.NET 3.5的路径CSIDL_COMMON_DOCUMENTS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!