【问题标题】:Get common desktop path in .NET获取 .NET 中的通用桌面路径
【发布时间】:2009-08-11 08:48:07
【问题描述】:

我需要将文件存储到 Windows 的公用桌面中。该应用程序是一个非常特殊的应用程序,只针对一台特殊的 PC(设备准备),因此非技术用户必须易于查找和修改配置文件。现在我们切换到一个域,因为不同的人(使用不同的帐户)应该使用该软件,所以它必须在一个共同的地方,每个用户都可以看到。所以请不要问为什么它在桌面上;)

之前,我只使用了Environment.GetFolderPath(Environment.SpecialFolder.Desktop)SpecialFolder 枚举中有几个常用文件夹,但常用桌面似乎不存在。我是否遗漏了什么,或者我必须使用CSIDL_COMMON_DESKTOPDIRECTORY p/invoke SHGetSpecialFolderPath

【问题讨论】:

  • 现在它变脏了。不幸的是,默认情况下我似乎没有写入公共桌面的权限,这使得这变得复杂。对更好的位置有什么建议吗?请记住,用户应该能够找到该文件,并且所有用户都需要读/写访问权限。该应用程序应由 XCOPY 部署。
  • 虽然原始问题仍然有效(特别是因为它似乎不在 SO 上的任何地方),但我认为我将不得不使用通用文档(或英文系统上的任何名称)。用户仍然可以找到它。现在让我们希望我有写权限。如果您认为这是一个好/坏主意,请随时发表评论。
  • 为什么不将它们存储在机器范围的隔离存储中?
  • @David Brunelle:我去看看,谢谢。
  • 该死的。我知道我应该把它放在答案中。本来可以投票的... :o

标签: .net windows windows-shell


【解决方案1】:

我认为您必须使用SHGetSpecialFolderPath API,因为“CommonDesktopDirectory”没有枚举值。您不能显式使用CSIDL_COMMON_DESKTOPDIRECTORY 的值并将其转换为Environment.SpecialFolder,因为GetFolderPath 方法会检查该值是否在枚举中定义。这是GetFolderPath 方法的代码(来自Reflector):

public static string GetFolderPath(SpecialFolder folder)
{
    if (!Enum.IsDefined(typeof(SpecialFolder), folder))
    {
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, GetResourceString("Arg_EnumIllegalVal"), new object[] { (int) folder }));
    }
    StringBuilder lpszPath = new StringBuilder(260);
    Win32Native.SHGetFolderPath(IntPtr.Zero, (int) folder, IntPtr.Zero, 0, lpszPath);
    string path = lpszPath.ToString();
    new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand();
    return path;
}

因此您可以轻松复制和调整您需要的部分...

【讨论】:

  • 好的,我只是想确定一下。现在我查看了 MSDN 文档,有一条说明在 Vista 及更高版本中,您应该使用 KNOWNFOLDERID 而不是 CLSID 值。如果我的应用必须在 XP 上运行,这是否也适用?
  • 不,我认为它仅适用于 Vista
  • 我可能会使用另一个文件夹(请参阅我的 cmets 问题),但这是该问题的最佳答案,因此我接受了它。感谢您的及时回复。
【解决方案2】:

澄清一下 - 通用桌面是指 C:\Documents and Settings\All Users\Desktop?

如果是,这是一个丑陋的 hack -

Dim c As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
Dim comDesktop As String = c.Substring(0, c.LastIndexOf("\")) + "\Desktop"

【讨论】:

  • 是的,我是这个意思。但这真的太丑了。
  • 一旦某些系统为桌面使用其他名称,它就会崩溃:p
【解决方案3】:

您可以使用 Windows 脚本宿主 - WshShell.SpecialFolders

http://msdn.microsoft.com/en-us/library/0ea7b5xe(VS.85).aspx

【讨论】:

  • 感谢你的想法,但我宁愿 p/invoke 也不愿引入这样的依赖:)
【解决方案4】:

首先,添加对“Windows 脚本宿主对象模型”的引用。您可以在“添加引用”对话框的 COM 选项卡中找到它。

using IWshRuntimeLibrary;

object commonUserDesktop = "AllUsersDesktop";
WshShell shell = new WshShellClass();
string commonPath = shell.SpecialFolders.Item(ref commonUserDesktop).ToString();

【讨论】:

  • 就像我在 Bogdan_Ch 的回答中所写的那样,我宁愿不使用 WSH 来完成这样的任务。 P/Invoke 对我来说很好。
【解决方案5】:

另一种方式(是的,它也很丑,可能只适用于 Windows XP,而不适用于 Vista) 是从注册表中读取一个值

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell 文件夹,通用桌面

【讨论】:

  • 这不仅丑陋,而且是兼容性的噩梦。如果我没记错的话,它甚至只存在于某些 CTP 版本的 Windows 中,但由于应用程序依赖它,它必须在 Windows 中存在几十年。
猜你喜欢
  • 2018-07-22
  • 1970-01-01
  • 2013-07-21
  • 2020-02-04
  • 2021-06-27
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 2016-05-03
相关资源
最近更新 更多