Конференция "WinAPI" » Как создать ярлык ? [D7, WinXP]
 
  • Winni (21.01.10 06:29) [0]
    Здравствуйте !

    Пытаюсь создать программу для инсталляции. Естественно, нужно, чтобы она размещала на раб.столе пользователя (и хорошо бы - в меню программ) ярлык, указывающий на экзешник. Install Shield с диска Делфи7 прекрасно это делает, но нужен самодельный инсталлятор.  То есть нужно создать ярлык, задать адрес и задать иконку. Далее вроде бы,  могу поместить ее в ресурс, а при инсталляции - извлечь.
  • oldman © (21.01.10 11:41) [1]

    > То есть нужно создать ярлык, задать адрес и задать иконку.
    >  Далее вроде бы,  могу поместить ее в ресурс, а при инсталляции
    > - извлечь.


    Ну так и создай. Руками. И в ресурс помести.
    Но будет жестко привязана к адресу.
    Значит создай, посмотри, где пишется адрес, и при инсталляции меняй его.
  • Anatoly Podgoretsky © (21.01.10 11:55) [2]
    Вот и используй Install Shield, оно много чего делает и делает правильно.
  • В. Молчанов (21.01.10 14:44) [3]
    Создать ярлык:

    function MakeShortcut(const sFName, sLnk, sWorkDir, sArgs, sIconFile: string;
                         IconIndex: integer): boolean;
    var CO: IUnknown;
    begin
     Result := False;
     CO := CreateComObject(CLSID_ShellLink);
     try
       with IShellLink(CO) do
       begin
         if SetPath(PChar(sFName)) <> S_OK then exit;
         if sIconFile <> '' then
           if SetIconLocation(PChar(sIconFile), IconIndex) <> S_OK then exit;
         if SetArguments(PChar(sArgs)) <> S_OK then exit;
         if SetWorkingDirectory(PChar(sWorkDir)) <> S_OK then exit;
       end;
       Result := Succeeded((CO as IPersistFile).Save(PWChar(WideString(sLnk)), False))
     finally
       CO := Unassigned
     end
    end;


    Получить путь для ярлыка:

    // S = '' -> Desktop folder
    function GetFullMenuPath(const S: string): string;
    var PIDL: PItemIDList;
       TempPath: array[0..MAX_PATH] of Char;
       Dir: integer;
    begin
     Result := '';
     if S = '' then Dir := CSIDL_DESKTOPDIRECTORY
               else Dir := CSIDL_COMMON_PROGRAMS;

     SHGetSpecialFolderLocation(Application.Handle, Dir, PIDL);
     if PIDL <> nil then
     begin
       SHGetPathFromIDList(PIDL, TempPath);
       Result := string(TempPath) + '\';
       GlobalFreePtr(PIDL)
     end
    end;


    Вызов:

     MakeShortcut(ParamStr(0),
                  GetFullMenuPath('')+'\Qwerty1.lnk',
                  ExtractFileDir(ParamStr(0)),
                  '/H',
                  ExtractFilePath(ParamStr(0)) + 'FileWithIcon.exe',  // ''
                  0
                  )

  • Winni (21.01.10 16:51) [4]
    Спасибо большое !
  • Winni (21.01.10 20:04) [5]
    Здравствуйте !

    Действительно, все это прекрасно работает. Возможно, кому-нибудь пригодятся мои комментарии:
    (* Разборка (комментарии):
    Необходимо добавит в uses: ShlObj, ComOBJ, ActiveX

    CLSID_ShellLink - описана в ShlObj.pas :
     {$EXTERNALSYM CLSID_ShellLink}
     CLSID_ShellLink: TGUID = (
       D1:$00021401; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
    ----------
    IShellLink - интерфейс описан в ShlObj.pas
    SetPath - описан в ShlObj.pas:
       function SetPath(pszFile: PAnsiChar): HResult; stdcall;
    ----------
    SetIconLocation - описана в ShlObj.pas
    function SetIconLocation(pszIconPath: PAnsiChar; iIcon: Integer):
      HResult; stdcall;
    ----------
    SetArguments - описана в ShlObj.pas
    function SetArguments(pszArgs: PAnsiChar): HResult; stdcall;
    --------
    SetWorkingDirectory - описана в ShlObj.pas
    function SetWorkingDirectory(pszDir: PAnsiChar): HResult; stdcall;
    ---------
    Succeeded - описана в Windows.pas
    {$EXTERNALSYM Succeeded}
    function Succeeded(Status: HRESULT): BOOL;
    ----------
    IPersistFile  - интерфейс описан в ActiveX.pas
    { IPersistFile interface }
     {$EXTERNALSYM IPersistFile}
     IPersistFile = interface(IPersist)
       ['{0000010B-0000-0000-C000-000000000046}']
       function IsDirty: HResult; stdcall;
       function Load(pszFileName: POleStr; dwMode: Longint): HResult;stdcall;
       function Save(pszFileName: POleStr; fRemember: BOOL): HResult;stdcall;
       function SaveCompleted(pszFileName: POleStr): HResult;stdcall;
       function GetCurFile(out pszFileName: POleStr): HResult;stdcall;
     end;
    *)

    Вызов функции немного изменил, чтобы создавать ярлык для инсталлированной программы, а не для
    инсталлятора:
    MakeShortcut(papka+'\TXTPLAYER.EXE',
       GetFullMenuPath('')+'\TXTPLAYER.lnk', // Если ярлык - на рабочий стол
       papka,
       '/H',
       papka+'\TXTPLAYER.EXE',
       0);
    где papka - строка, хранящая имя папки, в которую инсталлирована программа
    (ярлык создается позже копирования файлов в эту папку),
    TXTPLAYER.EXE - имя инсталлируемой программы.
    TXTPLAYER.lnk - имя ярлыка, создаваемого на рабочем столе.
  • clickmaker © (22.01.10 13:44) [6]
    > TXTPLAYER

    проигрыватель текстов? типа аудиокнига голосом робота?
    просто интересно...
  • Winni (23.01.10 18:26) [7]
    Не, просто переформатирует файлы *.txt так, чтобы при просмотре в mp3-плеере (например, Kingston KPEX-100) сохранялся перенос на новую строку. Мне кажется, это удобнее, а я много читаю в KPEX-100 - чтобы не сидеть за компом, а читать мануалы лежа на диване.
    В моих комментариях дефект: не указал, что
    .SetPath -
    .SetIconLocation -
    .SetArguments -
    .SetWorkingDirectory
    - это методы интерфейса IShellLink
 
Конференция "WinAPI" » Как создать ярлык ? [D7, WinXP]
Есть новые Нет новых   [134431   +16][b:0][p:0.002]