2009-10-10 2 views
1

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

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

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

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

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

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

редактировать добавить: Некоторые дополнительные требования мы имеем:

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

Возможно, вам удастся задать этот вопрос на сайте-партнере. –

+0

Какой? Это скорее вопрос программирования, чем вопрос администрирования сервера или вопрос с электрическим пользователем. –

ответ

1

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

1

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

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

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

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

+0

Есть две проблемы. Один из них - как найти ярлыки, даже для установки по умолчанию; установщик (Inno Setup) позволяет пользователю выбрать имя каталога в меню «Пуск» для установки. Нам нужно выяснить, как извлечь информацию о том, где Inno Setup поместил свои ярлыки, вероятно, из журнала удаления, и это может быть хрупким. Во-вторых, пользователи могут копировать или перемещать ярлыки, не имея представления о том, как исправить проблему, если она появится (и уже давно забыла о любых диалоговых окнах, которые они, возможно, видели). Я хотел бы сделать этот процесс максимально плавным. –

+0

См. Последний параграф ... он ссылается на способ поиска и обновления ярлыков WSH. –

+0

Ну, не правда, он ссылается на метод обновления ярлыка и на другой способ поиска файлов, вам нужно сделать микс :) ​​ –

0

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

+0

Наша программа включает в себя несколько носителей на гигабайтах, которые также перешли на другой путь. Насколько я знаю, Inno Setup не имеет функций для создания инкрементного обновления для такого типа ситуаций, что не связано с загрузкой всех носителей заново. Требование, чтобы пользователь обновил свои ярлыки вручную, представляет большую проблему, чем вы думаете. Мы либо должны были бы повторно создать ярлыки, которые пользователь ушел с пути, или пользователь должен был бы углубиться в нашу иерархию файлов программ, чтобы найти движок с именем, не связанным с именем программы. –

0

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

+0

Какая польза от этого даст ShellExecute? –

1

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

3

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

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

+0

Хм, интересная идея. Возможно, это сработало, но я уже развернул ситуацию с исполняемым файлом-заглушкой. Благодаря! –

+0

Добро пожаловать. Это для будущей справки, я знаю, что вы решили проблему несколько месяцев назад. Я прочитал всю тему. ;-) – MaD70