如何从服务中获取用户桌面路径?

3
我需要从一个服务应用程序中枚举本地Windows系统上所有用户桌面文件夹的路径。但是,有些用户可能在此时未登录。那么是否有任何API或其他方法可以实现呢?
编辑1:对于那些没有阅读第一段的人,请允许我重申——我没有用户账户的令牌,用户可能在此时未登录。
编辑2:我需要在支持我的应用程序的功能被关闭或卸载应用程序之前,从用户桌面中删除快捷方式。

@ConnorHollis,我认为你不能轻易地做出这种假设——根据环境和操作系统版本,文件夹的名称可能会有所不同,或者可能在网络共享、不同的驱动器等位置。 - Timo Geusch
2
请查看https://dev59.com/OknSa4cB1Zd3GeqPLzN5以获取所有用户的列表。但是,我找不到在未登录用户的情况下获取用户配置文件路径的方法。 - HerrJoebob
1
不,它可以是任何本地化的名称,例如%UserProfile%\桌面。 - Sheng Jiang 蒋晟
1
尝试使用通过 GetUserProfileDirectory 文档中的方法获得的令牌来调用 SHGetFolderPath。 - Sheng Jiang 蒋晟
共享桌面(以及文件、应用程序数据等)在您与其他人分享一组计算机而不是始终使用特定计算机时是必不可少的。 - Harry Johnston
显示剩余12条评论
2个回答

0

这是我目前能想到的最佳方法。所以我希望有人能用非英语安装的Windows检查一下这个方法是否可行?

(为了简洁起见,我只发布伪代码。)

1 - 所有以下步骤都是从本地服务应用程序中完成的。

2 - 要获取所有用户配置文件的路径,请枚举HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList键中的子文件夹,并从中读取ProfileImagePath值。它将为每个用户帐户提供配置文件路径。

3 - 要获取桌面文件夹的名称,请从服务应用程序中读取HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders键中的Desktop值(是的,我知道HKCU听起来很奇怪,但对我有效)。之后,使用环境变量API获取%USERPROFILE%环境变量的路径。因此,您将获得两个路径,类似于:

C:\Windows\system32\config\systemprofile\Desktop

并且

C:\Windows\system32\config\systemprofile

然后,只需使用不区分大小写的比较方法从第一个字符串中隔离出第二个字符串,您将获得桌面文件夹的名称(在本例中为"\Desktop")。

4- 将步骤2中获取的路径添加到桌面文件夹中,以生成该用户桌面文件夹的完整路径。


注册表的问题在于它可能无法为干净的安装创建,并且当注册表在不同机器之间漫游时,可能会从一台机器更改到另一台机器。http://blogs.msdn.com/b/oldnewthing/archive/2003/11/03/55532.aspx - Sheng Jiang 蒋晟
@ShengJiang蒋晟:我很感激陈先生对于垂死的Win32社区所做出的贡献,他也经常浏览这个论坛,或许他会对我的问题提出自己的看法。但是说实话,他的“旧新事物”大多数都是提出问题而非回答问题。我们知道Windows现在并没有像“昨天”承诺的那样运行,这并不是什么新鲜事...你挑选了User Shell Folders键的Desktop,所以如果我们按照陈先生的逻辑来看,它应该至少在Windows安装后被打开过一次,对吧? - ahmd0
有没有使用英语以外的操作系统的人可以确认一下,HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders 键中 Desktop 值是否包含除 "%USERPROFILE%\Desktop" 以外的内容或者不存在? - ahmd0
这不是可靠的。你假设系统上的所有用户相对于其个人文件夹具有相同的桌面路径,但这并不一定正确。 - Harry Johnston

0

从 userenv.h 中:GetProfilesDirectory(win2k+,如果我没记错)

msdn.microsoft.com/en-us/library/windows/desktop/bb762278(v=vs.85).aspx

使用此方法查找包含所有本地用户帐户配置文件目录的目录。
要查找桌面文件夹:
Shlobj.h:SHGetKnownFolderPath(vista+)

msdn.microsoft.com/en-us/library/windows/desktop/bb762188(v=vs.85).aspx

你需要使用FOLDERID_Desktop作为已知文件夹的ID。这个符号在Knownfolders.h中声明。

msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx

使用这些方法,您可以更接近您想要的结果,而无需直接读取注册表。当然,这违背了任何优雅的枚举用户的方式,除非从GetProfilesDirectory中的文件夹列表推断出来。也许有一种更适合API的方式来枚举本地用户。

其次,这取决于您服务的目的,但也许通过使用“allusers”配置文件而不是每个配置文件,您就不需要知道当前本地用户的列表。


谢谢您的回复,但是再次强调,所有这些东西只有在我拥有用户令牌的情况下才能起作用,而我可能没有... - ahmd0
不允许或者不确定如何实现这种方法?如果这是必须的,有一些不太常见的方式可以获取令牌,我只有模糊的了解(我相信NtCreateToken是其中之一),否则,重新思考问题和方法可能会给您一个很好的替代方案。 - JustinC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接