Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создания ярлыка к Vista-приложению, Падает Delphi при выполнении кода 
:(
    Опции темы
Illusion Dolphin
  Дата 11.1.2008, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 4
Всего: 63



Код

program ProgramTest;

uses
  ShellApi, Windows, Messages, SysUtils, ExtCtrls, Classes,
  StdCtrls, ComCtrls, ActiveX, ShlObj, ComObj, ExtDlgs, Registry;

var FEndDirectory : string = '';

procedure CreateShortcutW(SourceFileName, ShortcutName: string;  // the file the shortcut points to
                        Location: integer; // shortcut location
                        SubFolder,  // subfolder of location
                        WorkingDir, // working directory property of the shortcut
                        Parameters,
                        Description: string);
var
  MyObject: IUnknown;
  MySLink: IShellLink;
  MyPFile: IPersistFile;
  WideFileName : WideString;
  FS : TFileStream;
begin
  CoCreateInstance(CLSID_ShellLink,nil,CLSCTX_INPROC_SERVER,
                    IID_IShellLinkA,MyObject);
  MySLink := MyObject as IShellLink;
  MyPFile := MyObject as IPersistFile;
  MySLink.SetPath(PChar(SourceFileName));
  WideFileName := 'd:\1.lnk';
//  FS:=TFileStream.Create(SourceFileName,fmShareExclusive);
  MyPFile.Save(PWideChar(WideFileName), False);
//  FS.Free;
end;

begin
  CoInitialize(nil);
  FEndDirectory := 'D:\';
  CreateShortcutW(FEndDirectory+'test.exe','1.lnk',0,'',FEndDirectory,'','');
  CoUnInitialize;
end.

Код, приведенный выше вызывает падение Delphi7\2007 при наличии файла D:\1.exe в котором (!!!) содержится иконка в стиле Vista (для тех кто не в курсе - 256x256 c сжатием). Если не на первой прогонке то на энной прогонке падает на строчке MyPFile.Save и отказывается говорить что либо вразумительное кроме того что произошла внутренняя ошибка. Возникает несколько вопросов:
1) Что вызывает ошибку на самом деле? Если раскоментировать строчки со стримами то всё работает без ошибок! 
2) Как можно создать ярлык другим методом чтобы ошибки не было? А то метод блокировки файла чтото мне не нравится.

P.S. приложение с такой иконкой - это хотя бы последний (8й) Nero. Тестил на Vista на 2х компьютерах, в XP поведение меня не волнует т.к. приложение надо под Vista.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
FractalizeR
Дата 21.1.2008, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 27.12.2007
Где: Россия/Москва

Репутация: нет
Всего: 4



Код

unit VRSIShortCuts;

 //==============================================================================
 //                     FractalizeR's Delphi Library
 //               <- ShortCut Operations Class v1.0 ->

 //             Автор: Раструсный Владислав
 //                          http://www.vrsi.ru
 //                           [email protected]
 //==============================================================================

{-------------------------------------------------------------------------------
Usage example on existing shortcut file:

var MyShortCut: TVRSIShortCut;

MyShortCut:=TVRSIShortCut.Create('C:\MyShortcut.lnk');
MyShortCut.IconLocation:='E:\Program Files\FlashGet\flashget.exe,0';
MyShortCut.Save('C:\MyShortcut.lnk');
MyShortCut.Free;
-------------------------------------------------------------------------------}

{-------------------------------------------------------------------------------
Shortcut creation example:

var MyShortCut: TVRSIShortCut;

MyShortCut:=TVRSIShortCut.Create;
MyShortCut.Path:='E:\Program Files\FlashGet\flashget.exe';
MyShortCut.IconLocation:='E:\Program Files\FlashGet\flashget.exe,0';
MyShortCut.ShowCMD:=SW_MAXIMIZE;
MyShortCut.Save('C:\MyShortcut.lnk');
MyShortCut.Free;
-------------------------------------------------------------------------------}


interface

uses ActiveX, Classes, ComObj, ShlObj, SysUtils, Windows;

type
  TVRSIShortCut = class
  private
    FShellLink:   IShellLink;
    FPersistFile: IPersistFile;

    function GetArguments: string;
    function GetDescription: string;
    function GetHotKey: TShortCut;
    function GetIconLocation: string;
    function GetIDList: PItemIDList;
    function GetPath: string;
    function GetShowCMD: Integer;
    function GetWorkingDirectory: string;
    procedure SetArguments(const Value: string);
    procedure SetDescription(const Value: string);
    procedure SetHotKey(const Value: TShortCut);
    procedure SetIconLocation(const Value: string);
    procedure SetIDList(const Value: PItemIDList);
    procedure SetPath(const Value: string);
    procedure SetRelativePath(const Value: string);
    procedure SetShowCMD(const Value: Integer);
    procedure SetWorkingDirectory(const Value: string);
  public

    // Creates empty unlinked shortcut
    constructor Create; overload;

    //Creates shortcut object loading parameters from specified *.lnk file
    constructor Create(LinkPath: string); overload;

    //Destroys shortcut without saving
    destructor Destroy; override;

    //Saves shortcut info to a specified file
    procedure Save(Filename: string);

    //Loads shortcut object from specified *.lnk file
    procedure Load(Filename: string);

    //Resolves shortcut (validates path and if object shortcut points to does not exists,
    //opens window and searchs for lost object. Under Windows NT and NTFS if Distributed Link
    //Tracking system is enabled method finds shortcut object and sets correct path
    function Resolve(Window: HWND; Options: DWORD): HResult;

    //Returns last error text
    function GetLastErrorText(ErrorCode: Cardinal): string;

    //Property to access command line parameters for shortcut object
    property Arguments: string Read GetArguments Write SetArguments;

    //Property to access shortcut object description
    property Description: string Read GetDescription Write SetDescription;

    //Hot key for shortcut object
    property HotKey: TShortCut Read GetHotKey Write SetHotKey;

    //Icon location property
    property IconLocation: string Read GetIconLocation Write SetIconLocation;

    //IDList property for special shell icon objects
    property IDList: PItemIDList Read GetIDList Write SetIDList;

    //Path to shortcut abject
    property Path: string Read GetPath Write SetPath;

    //Relative path set property
    property RelativePath: string Write SetRelativePath;

    //Property to find out how to show the running shortcut object
    property ShowCMD: Integer Read GetShowCMD Write SetShowCMD;

    //Property to access working directory for shortcut object
    property WorkingDirectory: string Read GetWorkingDirectory
      Write SetWorkingDirectory;
  end;

type
  EVRSIShortCutError = class (Exception)
  end;

function VRSIGetSpecialDirectoryName(ID: integer; PlusSlash: Boolean): string;
 //Autostart : CSIDL_Startup
 //Startmenu : CSIDL_Startmenu
 //Programs  : CSIDL_Programs
 //Favorites : CSIDL_Favorites
 //Desktop   : CSIDL_Desktopdirectory
 //"Send to"-dir : CSIDL_Sendto


implementation

const
  IID_IPersistFile: TGUID = (D1: $0000010B; D2: $0000; D3: $0000;
    D4: ($C0, $00, $00, $00, $00,
    $00, $00, $46));

function VRSIGetSpecialDirectoryName(ID: integer; PlusSlash: Boolean): string;
var
  pidl: PItemIDList;
  Path: PChar;
begin
  if SUCCEEDED(SHGetSpecialFolderLocation(0, ID, pidl)) then
  begin
    Path := StrAlloc(MAX_PATH);
    SHGetPathFromIDList(pidl, Path);
    Result := string(Path);
    if PlusSlash then
      Result := IncludeTrailingBackSlash(Result);
  end;
end;

constructor TVRSIShortCut.Create;
var
  Err: Integer;
begin
  inherited;

  Err:=CoInitialize(nil);

  if Err <> S_OK then
    raise EVRSIShortCutError.Create(
      'Невозможно выполнить CoInitialize!' +
      #10#13 + GetLastErrorText(Err));

  Err := CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER,
    IID_IShellLinkA, FShellLink);
  if Err <> S_OK then
    raise EVRSIShortCutError.Create(
      'Невозможно получить интерфейс IShellLink!' +
      #10#13 + GetLastErrorText(Err));

  Err := FShellLink.QueryInterface(IID_IPersistFile, FPersistFile);

  if (Err <> S_OK) then
    raise EVRSIShortCutError.Create(
      'Невозможно получить интерфейс IPersistFile!' +
      #10#13 + GetLastErrorText(Err));

end;

constructor TVRSIShortCut.Create(LinkPath: string);
begin
  Self.Create;
  Self.Load(LinkPath);
end;

destructor TVRSIShortCut.Destroy;
begin
  Self.FPersistFile._Release;
  Self.FShellLink._Release;
  CoUninitialize;
  inherited;
end;

function TVRSIShortCut.GetArguments: string;
var
  Arguments: string;
begin
  SetLength(Arguments, MAX_PATH);
  Self.FShellLink.GetArguments(PChar(Arguments), MAX_PATH);
  SetString(Result, PChar(Arguments), Length(PChar(Arguments)));
end;

function TVRSIShortCut.GetDescription: string;
var
  Description: string;
begin
  SetLength(Description, MAX_PATH);
  Self.FShellLink.GetDescription(PChar(Description), MAX_PATH);
  SetString(Result, PChar(Description), Length(PChar(Description)));
end;

function TVRSIShortCut.GetHotKey: TShortCut;
var
  HotKey: TShortCut;
begin
  Self.FShellLink.GetHotkey(Word(HotKey));
  Result := HotKey;
end;

function TVRSIShortCut.GetIconLocation: string;
var
  IconLocation: string;
  Icon: Integer;
begin
  SetLength(IconLocation, MAX_PATH);
  Self.FShellLink.GetIconLocation(PChar(IconLocation), MAX_PATH, Icon);
  Result := PChar(IconLocation) + ',' + IntToStr(Icon);
end;

function TVRSIShortCut.GetIDList: PItemIDList;
var
  List: PItemIDList;
begin
  Self.FShellLink.GetIDList(List);
  Result := List;
end;

function TVRSIShortCut.GetLastErrorText(ErrorCode: Cardinal): string;
var
  WinErrMsg: PChar;
begin
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
    nil, ErrorCode, (((WORD((SUBLANG_DEFAULT)) shl 10)) or Word((LANG_NEUTRAL))),
    @WinErrMsg, 0, nil);
  Result := WinErrMsg;
end;


function TVRSIShortCut.GetPath: string;
var
  Path: string;
  FindData: WIN32_FIND_DATA;
begin
  SetLength(Path, MAX_PATH);
  Self.FShellLink.GetPath(PChar(Path), MAX_PATH, FindData, 0);
  SetString(Result, PChar(Path), Length(PChar(Path)));
end;

function TVRSIShortCut.GetShowCMD: Integer;
var
  ShowCMD: Integer;
begin
  Self.FShellLink.GetShowCmd(ShowCMD);
  Result := ShowCMD;
end;

function TVRSIShortCut.GetWorkingDirectory: string;
var
  WorkDir: string;
begin
  SetLength(WorkDir, MAX_PATH);
  Self.FShellLink.GetWorkingDirectory(PChar(WorkDir), MAX_PATH);
  SetString(Result, PChar(WorkDir), Length(PChar(WorkDir)));
end;

procedure TVRSIShortCut.Load(Filename: string);
begin
  FPersistFile.Load(StringToOLEStr(Filename), 0);
end;

function TVRSIShortCut.Resolve(Window: HWND; Options: DWORD): HResult;
begin
  Result := Self.FShellLink.Resolve(Window, Options);
end;

procedure TVRSIShortCut.Save(Filename: string);
begin
  FPersistFile.Save(StringToOLEStr(Filename), True);
end;

procedure TVRSIShortCut.SetArguments(const Value: string);
begin
  Self.FShellLink.SetArguments(PChar(Value));
end;

procedure TVRSIShortCut.SetDescription(const Value: string);
begin
  Self.FShellLink.SetDescription(PChar(Value));
end;

procedure TVRSIShortCut.SetHotKey(const Value: TShortCut);
begin
  Self.FShellLink.SetHotkey(Value);
end;

procedure TVRSIShortCut.SetIconLocation(const Value: string);
begin
  Self.FShellLink.SetIconLocation(PChar(Copy(Value, 0, Pos(',', Value) - 1)),
    StrToInt(Copy(Value, Pos(',', Value) + 1, MAX_PATH)));
end;

procedure TVRSIShortCut.SetIDList(const Value: PItemIDList);
begin
  Self.FShellLink.SetIDList(Value);
end;

procedure TVRSIShortCut.SetPath(const Value: string);
begin
  Self.FShellLink.SetPath(PChar(Value));
end;

procedure TVRSIShortCut.SetRelativePath(const Value: string);
begin
  Self.FShellLink.SetRelativePath(PChar(Value), 0);
end;

procedure TVRSIShortCut.SetShowCMD(const Value: Integer);
begin
  Self.FShellLink.SetShowCmd(Value);
end;

procedure TVRSIShortCut.SetWorkingDirectory(const Value: string);
begin
  Self.FShellLink.SetWorkingDirectory(PChar(Value));
end;

end.





Воспользуйтесь моим классом. Очень удобно.


--------------------
Чтобы поблагодарить или наоборот поругать участника форума лучше пользоваться значками "+" и "-", изменяющими репутацию. Они находятся слева от поста под именем пользователя.
PM MAIL   Вверх
Illusion Dolphin
Дата 22.1.2008, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 4
Всего: 63



Код

program Project1;

uses
  VRSIShortCuts in 'D:\VRSIShortCuts.pas';

var
  MyShortCut: TVRSIShortCut;

begin
MyShortCut:=TVRSIShortCut.Create();
MyShortCut.IconLocation:='D:\test.exe,0';
MyShortCut.RelativePath:='d:\test.exe';
MyShortCut.Save('d:\1.lnk');
MyShortCut.Free;
end.

программа падает на MyShortCut.Free; smile 
Код

destructor TVRSIShortCut.Destroy;
begin
//  Self.FPersistFile._Release;
//  Self.FShellLink._Release;
  CoUninitialize;
  inherited;
end;

вроде должно быть так, т.к. _Release вызывается автоматически - при этом всё вроде работает и не падает.  Спасибо за вариант решения, хотя что именно было не так в моём коде я так и не понял.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
MetalFan
Дата 22.1.2008, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Цитата(Illusion Dolphin @  22.1.2008,  12:44 Найти цитируемый пост)
//  Self.FPersistFile._Release;
//  Self.FShellLink._Release;

здесь достаточно присвоить nil...


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
FractalizeR
Дата 22.1.2008, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 27.12.2007
Где: Россия/Москва

Репутация: нет
Всего: 4



Спасибо, я проверю еще раз сегодня, но у меня не падало, вроде бы. Либо падало незаметно smile


--------------------
Чтобы поблагодарить или наоборот поругать участника форума лучше пользоваться значками "+" и "-", изменяющими репутацию. Они находятся слева от поста под именем пользователя.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0563 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.