如何在C++中获取到Windows资源管理器的完整路径

如何在C++中获取到Windows资源管理器的完整路径,c++,winapi,windows-explorer,C++,Winapi,Windows Explorer,我是否可以安全地假定Windows资源管理器始终从Windows系统目录启动?另外,其进程是否始终命名为explorer.exe 如果没有,如何获取其完整文件路径 编辑:忘了提及-我需要这个来稍后查找在给定用户会话中运行的Windows资源管理器的进程ID。因此,我寻找它的完整路径 编辑2:感谢所有做出贡献的人,尤其是sehe!在他的帖子之后,我发现这解释了如何设置自己的shell。我用自己的进程完全替换了explorer.exe,进行了一次疯狂的测试,结果如下: 如果你想重新调整尺寸,这里有一

我是否可以安全地假定Windows资源管理器始终从Windows系统目录启动?另外,其进程是否始终命名为explorer.exe

如果没有,如何获取其完整文件路径

编辑:忘了提及-我需要这个来稍后查找在给定用户会话中运行的Windows资源管理器的进程ID。因此,我寻找它的完整路径

编辑2:感谢所有做出贡献的人,尤其是sehe!在他的帖子之后,我发现这解释了如何设置自己的shell。我用自己的进程完全替换了explorer.exe,进行了一次疯狂的测试,结果如下: 如果你想重新调整尺寸,这里有一个建议

如您所见,我可以从技术上用我可能想到的任何进程替换explorer.exe。正如你也可以在我的截图窗口中看到的那样,我可以完全控制外壳,截图就是我的整个窗口

因此,底线是,获取explorer.exe文件路径或使用任何Shell进程的唯一方法是使用我上面引用的链接中的注册表项-非常接近sehe的建议,只需再做一些检查,但这是一个非常简单的东西


至于肖恩·克莱恩(Sean Cline)的建议,只有当我们运行带有特定类名的托盘窗口的stock Windows Explorer时,这才是一个非常优雅的解决方案。

两者都同意。Windows资源管理器始终位于%WINDIR%\Explorer.exe。

两者都是。Windows资源管理器始终位于%WINDIR%\Explorer.exe。

可以安全地假设Explorer.exe始终位于%WINDIR%或%SystemRoot%中,因为它已经多年没有移动了。但是,如果您试图通过资源管理器调用某个函数,那么您很可能希望改用该函数

如果确实需要路径,最简单的方法可能是调用使用FOLDERID_窗口作为第一个参数

编辑: 下面是我对一些代码的尝试,我知道您正在寻找shell进程的PID:

DWORD trayPID;
HWND trayWnd = FindWindow("Shell_TrayWnd", NULL);
GetWindowThreadProcessId(trayWnd, &trayPID);

它查找任务栏的hWnd并找到所属的PID。如果资源管理器未运行且该窗口不存在,则可能需要添加一些错误处理-不太可能,但可能存在。

可以安全地假设explorer.exe始终位于%windir%或%SystemRoot%中,因为它已多年未移动。但是,如果您试图通过资源管理器调用某个函数,那么您很可能希望改用该函数

如果确实需要路径,最简单的方法可能是调用使用FOLDERID_窗口作为第一个参数

编辑: 下面是我对一些代码的尝试,我知道您正在寻找shell进程的PID:

DWORD trayPID;
HWND trayWnd = FindWindow("Shell_TrayWnd", NULL);
GetWindowThreadProcessId(trayWnd, &trayPID);

它查找任务栏的hWnd并找到所属的PID。对于Explorer没有运行且窗口不存在的情况,您可能需要添加一些错误处理。不太可能,但可能。

< P>不,您不能安全地假定这一点与C++无关。p> 而且,您没有显示任何代码。下面是:

此注册表项为Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Shell请参阅


不,你不能安全地假定这一点与C++无关。p> 而且,您没有显示任何代码。下面是:

此注册表项为Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Shell请参阅


真正地我不相信。你能引用一个来源吗?是的,同意。虽然,由于我没有将Shell进程称为explorer.exe来正确表述我的原始问题,他可能特别正确地描述了Windows资源管理器。真的吗?!我不相信。你能引用一个来源吗?是的,同意。虽然,由于我没有通过将Shell进程称为explorer.exe来正确表述我的原始问题,他可能特别正确地描述了Windows资源管理器的股票。应该注意的是,Shell注册表项有几个警告。它不包括完整路径,只包括可执行文件名。此外,任何安装了常规shell替换项的用户都会使用不同的密钥值,尽管这种情况非常罕见。@sehe感谢您的输入。我不知道这样的注册表项。因此,由于没有完整路径,我可以假设该文件位于可以从GetWindowsDirectory调用获取的系统文件夹中吗?我根据您的建议更新了原始问题的解决方案。再次感谢。@SeanCline哦,这让我很惊讶。我没有windows机器来测试代码。我只是在一个文本编辑器里写的。另外,如果用户有不同的shell,您将获得不同的可执行文件,这完全是目的所在!为什么不使用“硬代码”%WINDIR%\explorer.exe,否则应该注意Shell注册表项有几个警告。它不包括完整路径,只包括可执行文件名。此外,任何安装了常规shell的替换项的用户都将对此密钥具有不同的值,尽管这是v

非常罕见。@sehe谢谢你的意见。我不知道这样的注册表项。因此,由于没有完整路径,我可以假设该文件位于可以从GetWindowsDirectory调用获取的系统文件夹中吗?我根据您的建议更新了原始问题的解决方案。再次感谢。@SeanCline哦,这让我很惊讶。我没有windows机器来测试代码。我只是在一个文本编辑器里写的。另外,如果用户有不同的shell,您将获得不同的可执行文件,这完全是目的所在!为什么不使用“硬代码”%WINDIR%\explorer.exe,否则您可能需要更具体地说明您要实现的目标。根据您的意愿,可能没有必要对外壳的名称或位置进行任何假设。是的,我道歉。我需要知道在给定用户会话中运行的Windows资源管理器的进程ID。我自己想不出有什么理由知道shell进程的PID,但我已经更新了我的答案。希望它能为你指明正确的方向。如果你解释为什么需要pid,也许有人能解决你的实际问题。你不能用explorer的pid做很多事情。您应该使用适当的shell API。有些终端服务场景中,资源管理器不是外壳,当然也有些场景中有多个资源管理器副本正在运行。@RaymondChen:我需要Windows资源管理器的PID来确定特定进程是由用户还是由系统启动的。这是一个完全不同的讨论,但简而言之,我使用子-父进程树来确定这种继承。您可能需要更具体地说明您试图实现的目标。根据您的意愿,可能没有必要对外壳的名称或位置进行任何假设。是的,我道歉。我需要知道在给定用户会话中运行的Windows资源管理器的进程ID。我自己想不出有什么理由知道shell进程的PID,但我已经更新了我的答案。希望它能为你指明正确的方向。如果你解释为什么需要pid,也许有人能解决你的实际问题。你不能用explorer的pid做很多事情。您应该使用适当的shell API。有些终端服务场景中,资源管理器不是外壳,当然也有些场景中有多个资源管理器副本正在运行。@RaymondChen:我需要Windows资源管理器的PID来确定特定进程是由用户还是由系统启动的。这是一个完全不同的讨论,但简而言之,我使用子-父进程树来确定此继承。我实际上是使用GetWindowsDirectory来获取系统文件夹。但是现在在阅读了@sehe的评论之后,我倾向于认为我需要从注册中心的shell中获取资源管理器的名称。虽然仍然不是最终答案,因为正如您指出的,托盘窗口可能不存在。更新:在我的原始答案中发布了一个解决方案。我实际上是使用GetWindowsDirectory获取系统文件夹。但是现在在阅读了@sehe的评论之后,我倾向于认为我需要从注册中心的shell中获取资源管理器的名称。虽然仍然不是最终答案,因为正如您指出的,托盘窗口可能不存在。更新:在我的原始答案中发布了一个解决方案。