如何将所有快捷方式重定向到给定的可执行文件? Windows 上是否有相当于符号链接的东西?

发布于 2024-08-07 12:50:31 字数 1519 浏览 9 评论 0原文

我正在开发一个程序,其中包括通用引擎、一些特定于程序的内容和自定义自动更新程序,以尽可能高效地处理更新内容中的数千兆字节媒体。在引擎的最新版本中,我们重新组织了目录结构,这样可执行文件不再安装到(例如)c:\Program Files\Program\Engine.exe,而是现在位于c:\Program Files\Program\engine\win32\NewEngine.exe(请注意,在此过程中引擎的名称也发生了变化)。

问题是,为了启动该程序,用户需要使用快捷方式,我们将其安装在他们的开始菜单中和(可选)桌面上。不过,更新后引擎的移动打破了这些快捷方式。所以现在我需要找到一种方法来修复用户启动程序所拥有的所有快捷方式。

来自 Unix/Mac OS X 背景的我倾向于创建一个从旧可执行文件名称到新可执行文件名称的符号链接。据我所知,Windows 上并没有真正相当于符号链接的东西(通过谷歌搜索,我看到有 Vista 及更高版本上的符号链接,但这需要在 XP 上工作)。我的假设有错吗? Windows 上是否有与可执行文件的符号链接等效的东西?

我想到的其他一些可能的解决方案是:

  1. 在旧位置创建一个小型可执行文件,在新位置启动真正的可执行文件。 是否有任何快速简便的方法来创建一个简单的无头可执行文件,只需启动另一个程序?同样,在 Unix 上,我只需创建一个 shell 脚本,但据我所知我可以无法将 .bat 文件命名为 .exe 并运行它,因此这需要成为实际生成 .exe 的方法。
  2. 更新后,搜索指向可执行文件的所有快捷方式并编辑它们。 是否有任何(有效且可靠的)方法来查找系统上指向给定位置的所有快捷方式并更新它们?
  3. 上述组合,以及一个小型可执行文件,可以检测到它正在从以下位置启动快捷方式,并在启动实际程序之前编辑该快捷方式。 有什么方法可以检测到程序正在从快捷方式启动,从而能够编辑该快捷方式?

这些选项是否有效?如果可以,如何?在 Windows 上执行此类操作的最佳方法是什么? 我是否缺少将快捷方式从一个位置重定向到另一个位置的任何其他方法?

编辑添加:我们有一些额外的要求:

  1. 我们的许多用户都是非技术人员。任何需要用户干预的解决方案都是不可能的。
  2. 这应该尽可能无缝。每次用户单击快捷方式时弹出任何额外的窗口是不可接受的。
  3. 面对用户可以做的大多数事情,例如重新排列开始菜单或将快捷方式移动到快速启动栏,这应该是稳健的。
  4. ,这不太理想;我更愿意修复这个问题,但目前还不能)
  5. 我们的快捷方式对于程序的运行是绝对必要的,因为它们传递引擎加载内容所需的参数(是的 寻找相对快速、易于实施且极其可靠的东西。

I am working on a program which includes a general purpose engine, some program specific content, and a custom automatic updater to handle updating the many gigabytes worth of media in our content as efficiently as possible. In a recent release of the engine, we have reorganized our directory structure, such that instead of the executable installing to (for example) c:\Program Files\Program\Engine.exe, it is now in c:\Program Files\Program\engine\win32\NewEngine.exe (note that the name of the engine changed as well in this process).

The problem is that in order to launch the program, the user needs to use a shortcut, which we install in their start menu and (optionally) on their desktop. The move of the engine after an update breaks those shortcuts, though. So now I need to figure out a way to fix all of the shortcuts that the user has in order to launch the program.

Coming from a Unix/Mac OS X background, my inclination would be to just create a symlink from the old executable name to the new one. As far as I know though, there isn't really an equivalent of a symlink on Windows (from Googling, I see that there are symlinks on Vista and later, but this needs to work on XP). Am I wrong in my assumption? Is there any equivalent on Windows to a symlink to an executable?

Some other possible solutions that come to mind are:

  1. Creating a small executable at the old location that launches the real one in the new location. Is there any quick and easy way to create a simple, headless executable, that just launches another program? Again, on Unix, I'd simply create a shell script, but as far as I know I can't name a .bat file .exe and have it run, so this needs to be a way to actually generate an .exe.
  2. Upon the update, search for all shortcuts that point to the executable and edit them. Is there any (efficient and reliable) way to find all shortcuts on the system that point to a given location and update them?
  3. A combination of the above, with a small executable that detects that it's being launched from a shortcut, and edits that shortcut before launching the real program. Is there any way to detect that a program is being launched from a shortcut, and thus be able to edit that shortcut?

Would any of these options work, and if so how? What is the best way to do this sort of thing on Windows? Am I missing any other ways of redirecting a shortcut from one location to another?

edit to add: Some additional requirements we have:

  1. Many of our users are non-technical. Any solution requiring user intervention is out of the question.
  2. This should be as seamless as possible. Having any extra windows pop up every time the user clicks the shortcut is unacceptable.
  3. This should be robust in the face of most things the user could have done, such as rearranging their start menu or moving a shortcut to the quick launch bar.
  4. Our shortcuts are absolutely necessary to the functioning of the program, as they pass in arguments necessary for the engine to load the content (yes, this is less than ideal; I would prefer to fix this, but cannot at this point)
  5. I'm looking for something that is relatively quick and easy to implement and extremely reliable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

寻梦旅人 2024-08-14 12:50:31

奇怪的是,没有人提到NTFS 硬链接

一些参考:

Strangely enough, no one mentioned NTFS Hard Links.

Some references:

你与清晨阳光 2024-08-14 12:50:31

为什么在安装更新期间无法覆盖快捷方式?

您应该只覆盖默认快捷方式,而不是用户可能创建的每个快捷方式。不过,对于第二种情况,您可以使用选项 1,但是,它必须是真正的可执行文件。

(我认为您可以放心地假设,如果用户在非标准位置创建了第三个快捷方式,他知道这意味着什么,或者当复制的快捷方式不起作用时在哪里查找信息。哎呀,您甚至可以发出警告更新程序中的某个地方记录了更改。)

如果您确实想要执行您所说的操作(更新每个快捷方式),您可以使用已接受答案的方法的扩展来实现 此处。只需搜索任何.lnk文件,看看TargetPath是否是旧的引擎位置,如果有则更新。

Why can't you overwrite the shortcuts during installation of updates?

You should overwrite only the default shortcuts, not every shortcut the user might have created. Still, for this second case you can use option 1, but yes, it should have to be a real executable.

(I think you can safely assume that if the user has created a third shortcut in a non standard location, he knows what it means or where to look for information when the copied shortcut doesn't work. Heck, you could even put a warning somewhere in the updater noting the changes.)

If you really truly want to do what you've stated (updating every shortcut), you can do it with an extension of the method of the accepted answer here. Just search for any .lnk file, see if TargetPath is the old engine location, and update it if it is.

写下不归期 2024-08-14 12:50:31

好吧,我们决定的解决方案只是执行一个小的可执行文件来启动我们真正的引擎。使用 Visual Studio 花了比我希望的更多的时间来设置项目,但它似乎正在解决。

#include "stdafx.h"
#include <shellapi.h>

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
  HINSTANCE result = ShellExecute(NULL, _T("open"), 
                                  _T("engine\\win32\\NewEngine.exe"),
                                  lpCmdLine, NULL, 1);
  // ... handle errors ...
  return 0;
}

编辑:不。这似乎适用于 XP,但不适用于 Windows 7 或 Vista。任何关于为什么这会在 Windows 7 或 Vista 上失败的想法将不胜感激。如果我不能很快解决这个问题,我可能会将其分解为一个单独的问题。

编辑2:啊。在 XP 上,路径名中的正斜杠可以正常工作。在 Vista 或更新版本中,您需要反斜杠。

Well, the solution we've decided on is just doing the small little executable that launches our real engine. It took a bit more futzing with Visual Studio to get the project set up than I would have preferred, but it seems to be working out.

#include "stdafx.h"
#include <shellapi.h>

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
  HINSTANCE result = ShellExecute(NULL, _T("open"), 
                                  _T("engine\\win32\\NewEngine.exe"),
                                  lpCmdLine, NULL, 1);
  // ... handle errors ...
  return 0;
}

edit: Nope. This seems to work on XP, but not Windows 7 or Vista. Any ideas for why this would fail on Windows 7 or Vista would be much appreciated. If I can't figure this out soon, I may break this out into a separate question.

edit 2: Ah. On XP, forward slashes in the pathname work just fine. On Vista or newer, you need backslashes.

作死小能手 2024-08-14 12:50:31

ShellExecute() 的 MSDN 文档,我注意到您可能需要初始化 COM。此外,您需要提供可执行文件的完整路径(不是相对路径)。或者,您可以在快捷方式中使用环境变量而不是完整路径。您可以在新安装期间修改环境变量以反映新路径。

From the MSDN documentation for ShellExecute(), I notice you might need to initialize COM. Also, you need to provide full path to the executable (not relative). Alternatively, you could use ENVIRONMENT variables in the shortcuts instead of full paths. You can modify the ENVIRONMENT variables during new installations to reflect the new paths.

吻安 2024-08-14 12:50:31

对我来说这听起来像是安装程序问题。在升级过程中,为什么不直接卸载旧版本并安装新版本呢?我不熟悉 Inno Setup,但这就是我们进行 InstallShield 安装程序升级的方式。当然,这不能处理用户手动创建快捷方式的情况;但是,用户可以重新创建它。至于简单的搜索和替换,我认为不值得付出努力。

This sounds like an installer issue to me. During an upgrade, why not just uninstall the old version and install the new version? I am not familiar with Inno Setup, but this is how we do our InstallShield installer for an upgrade. Granted this doesn't handle the case when the user manually creates a shortcut; however, the user could just recreate it. As for a simple search and replace, I don't think it's worth the effort.

_蜘蛛 2024-08-14 12:50:31

尝试使用 CreateProcess 或spawn 等效项来代替 ShellExecute。我敢打赌CreateProcess。

Instead of ShellExecute, try CreateProcess or spawn equivalents. I would bet on CreateProcess.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文