Как я могу перенаправить все ярлыки на данный исполняемый файл? Есть ли эквивалент символической ссылки в Windows?

Я работаю над программой, которая включает в себя движок общего назначения, некоторый контент для конкретной программы и настраиваемое автоматическое средство обновления для максимально эффективного обновления мультимедиа на многие гигабайты в нашем контенте. В последнем выпуске движка мы реорганизовали нашу структуру каталогов, так что вместо установки исполняемого файла (например) в c:\Program Files\Program\Engine.exe он теперь находится в c:\Program Files\Program\engine\win32\NewEngine.exe (обратите внимание, что имя движка также изменилось в этом процессе).

Проблема в том, что для запуска программы пользователю необходимо использовать ярлык, который мы устанавливаем у него в стартовом меню и (опционально) на рабочий стол. Однако перемещение движка после обновления ломает эти ярлыки. Итак, теперь мне нужно найти способ исправить все ярлыки, которые есть у пользователя для запуска программы.

Исходя из фона Unix / Mac OS X, я хотел бы просто создать символическую ссылку из старого имени исполняемого файла в новое. Однако, насколько я знаю, эквивалента символической ссылки в Windows на самом деле нет (погуглив я вижу, что есть символические ссылки в Vista и более поздних версиях, но это должно работать в XP). Я ошибаюсь в своем предположении? Есть ли в Windows эквивалент символической ссылки на исполняемый файл?

Некоторые другие возможные решения, которые приходят на ум:

  1. Создание небольшого исполняемого файла в старом месте, который запускает настоящий в новом месте. Есть ли какой-нибудь быстрый и простой способ создать простой исполняемый файл без заголовка, который просто запускает другую программу? Опять же, в Unix я бы просто создал сценарий оболочки, но, насколько я знаю, я могу не назвать .bat файл .exe и запустить его, так что это должен быть способ фактически сгенерировать файл .exe.
  2. После обновления найдите все ярлыки, указывающие на исполняемый файл, и отредактируйте их. Есть ли какой-либо (эффективный и надежный) способ найти в системе все ярлыки, указывающие на заданное место, и обновить их?
  3. Комбинация вышеперечисленного с небольшим исполняемым файлом, который обнаруживает, что он запускается с ярлыка, и редактирует этот ярлык перед запуском реальной программы. Есть ли способ определить, что программа запускается с ярлыка, и таким образом иметь возможность редактировать этот ярлык?

Будет ли работать любой из этих вариантов, и если да, то как? Каков наилучший способ сделать это в Windows? Могу ли я пропустить какие-либо другие способы перенаправления ярлыка из одного места в другое?

изменить, чтобы добавить: у нас есть некоторые дополнительные требования:

  1. Многие из наших пользователей не являются техническими специалистами. О любом решении, требующем вмешательства пользователя, не может быть и речи.
  2. Это должно быть максимально бесшовно. Появление каких-либо дополнительных окон каждый раз, когда пользователь щелкает ярлык, недопустимо.
  3. Это должно быть устойчивым к большинству вещей, которые пользователь мог бы сделать, например, переупорядочить меню «Пуск» или переместить ярлык на панель быстрого запуска.
  4. Наши ярлыки абсолютно необходимы для работы программы, так как они передают аргументы, необходимые движку для загрузки контента (да, это далеко не идеально; я бы предпочел это исправить, но пока не могу)
  5. Я ищу что-то относительно быстрое и простое в реализации и чрезвычайно надежное.

person Brian Campbell    schedule 10.10.2009    source источник
comment
Возможно, вам удастся задать этот вопрос на дочернем сайте (сайтах?).   -  person dreadwail    schedule 10.10.2009
comment
Который из? Это действительно больше вопрос программирования, чем вопрос администрирования сервера или вопрос опытного пользователя.   -  person Brian Campbell    schedule 10.10.2009


Ответы (6)


Как ни странно, никто не упомянул жесткие ссылки NTFS.

Некоторые ссылки:

person MaD70    schedule 13.01.2010
comment
Хм, интересная идея. Это могло бы сработать, но я уже развернул ситуацию с исполняемым файлом-заглушкой. Спасибо! - person Brian Campbell; 13.01.2010
comment
Пожалуйста. Это для справки в будущем, я знаю, что вы решили проблему несколько месяцев назад. Я прочитал всю ветку. ;-) - person MaD70; 13.01.2010

Почему нельзя перезаписывать ярлыки при установке обновлений?

Вы должны перезаписывать только ярлыки по умолчанию, а не каждый ярлык, который мог создать пользователь. Тем не менее, для этого второго случая вы можете использовать вариант 1, но да, это должен быть настоящий исполняемый файл.

(Я думаю, вы можете смело предположить, что если пользователь создал третий ярлык в нестандартном месте, он знает, что это значит или где искать информацию, когда скопированный ярлык не работает. Черт, вы могли бы даже поставить предупреждение где-то в программе обновления отмечают изменения.)

Если вы действительно действительно хотите делать то, что вы сказали (обновление каждого ярлыка), вы можете сделать это с расширением метода принятого ответа здесь. Просто найдите любой файл .lnk и посмотрите, является ли TargetPath старым расположением движка. , и обновите его, если это так.

person Vinko Vrsalovic    schedule 10.10.2009
comment
Есть две проблемы. Во-первых, как найти ярлыки даже для установки по умолчанию; установщик (Inno Setup) позволяет пользователю выбрать имя каталога в меню «Пуск» для установки. Нам нужно выяснить, как извлечь информацию о том, куда Inno Setup поместил свои ярлыки, возможно, из журнала удаления, и это может быть хрупким. Во-вторых, пользователи могут копировать или перемещать ярлыки, не имея ни малейшего представления о том, как решить проблему, если она возникнет (и давно забыв о любых диалоговых окнах, которые они могли видеть). Я хотел бы сделать этот процесс как можно более плавным. - person Brian Campbell; 10.10.2009
comment
См. последний абзац... он ссылается на способ WSH для поиска и обновления ярлыков. - person Vinko Vrsalovic; 10.10.2009
comment
Ну, неправда, это ссылка на метод для обновления ярлыка и на другой метод для поиска файлов, вам нужно сделать микс :) - person Vinko Vrsalovic; 10.10.2009
comment
Ага. На самом деле поиск по всему диску всех ярлыков и обновление соответствующих кажется довольно проигрышным предложением; довольно чертовски медленно, и слишком много возможностей для ужасного провала какого-то углового случая. Я надеялся, что может быть какой-то встроенный индекс, чтобы упростить этот процесс. - person Brian Campbell; 10.10.2009
comment
Я бы сделал, как я сказал, обновил только установленные ярлыки и запустил исполняемый файл в старом месте, запускающий новый движок. - person Vinko Vrsalovic; 10.10.2009
comment
(потому что, насколько я знаю, такого индекса нет) - person Vinko Vrsalovic; 10.10.2009

Ну, решение, которое мы выбрали, это просто сделать небольшой исполняемый файл, который запускает наш настоящий движок. С 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 или новее вам понадобится обратная косая черта.

person Brian Campbell    schedule 13.10.2009

Из документации MSDN для ShellExecute(), Я заметил, что вам может понадобиться инициализировать COM. Кроме того, вам необходимо указать полный путь к исполняемому файлу (не относительный). В качестве альтернативы вы можете использовать переменные ОКРУЖАЮЩЕЙ СРЕДЫ в ярлыках вместо полных путей. Вы можете изменить переменные ОКРУЖАЮЩЕЙ СРЕДЫ во время новых установок, чтобы отразить новые пути.

person hackworks    schedule 19.10.2009

Это звучит как проблема с установщиком для меня. Почему бы во время обновления просто не удалить старую версию и не установить новую? Я не знаком с Inno Setup, но именно так мы делаем наш установщик InstallShield для обновления. Конечно, это не относится к случаю, когда пользователь вручную создает ярлык; однако пользователь может просто воссоздать его. Что касается простого поиска и замены, я не думаю, что это стоит усилий.

person Luke    schedule 11.10.2009
comment
Наша программа включает в себя несколько гигабайт медиафайлов, которые также переместились по другому пути. Насколько я знаю, Inno Setup не имеет функций для создания добавочного обновления для такого типа ситуаций, которые не потребовали бы повторной загрузки всех носителей. Требовать, чтобы пользователь обновлял свои ярлыки вручную, — это больше проблем, чем вы думаете. Нам пришлось бы либо заново создавать ярлыки, которые пользователь переместил в сторону, либо пользователю пришлось бы копаться глубоко в нашей иерархии программных файлов, чтобы найти движок, имя которого не связано с названием программы. - person Brian Campbell; 11.10.2009

Вместо ShellExecute попробуйте CreateProcess или его эквиваленты. Я бы поставил на CreateProcess.

person hackworks    schedule 14.10.2009
comment
Какие преимущества это даст по сравнению с ShellExecute? - person Brian Campbell; 15.10.2009