Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Add to AutoRun [D7, WinXP]


Страницы:   1 2

Goorus ©   (2004-08-27 13:09:00) 

Необходимо добавить ярлык в атозагрзку. В самой программе это получилось, но по завершении выдавалась ошибка. Думал это связано с неосвобождением объектов, но у интерфейсов нет метода Free, а _Release не помогал.
Попробывал написать простую демку(форма с кнопкой), работать стало ещё хуже :) Демка даже не добавляет себя в автозагрузку, хотя код не изменялся. Причина: в переменную Folder передаётся неверный путь ("С:\Docum^    "). Вот код:

procedure TForm1.Button1Click(Sender: TObject);
var List:PItemIdList;
  SLink:IShellLink;
 Folder:PChar;
begin
 // создаём ярлык в автозагрузке
 // находим папку
 SHGetSpecialFolderLocation(0, CSIDL_STARTUP, List);
 New(Folder);
 SHGetPathFromIDList(List, Folder);
 ShowMessage(Folder); // <- неверный путь
 // прописываемся
 SLink:=IShellLink(CreateComObject(CLSID_ShellLink));
 SLink.SetArguments('/a');
 SLink.SetDescription('My Prog');
 SLink.SetPath( PChar(ParamStr(0)) );
 (SLink as IPersistFile).Save(PWChar(WideString(Folder+'\prog.lnk')), False);
end;


jack128   (2004-08-27 15:17:00) [21]

WondeRu ©   (27.08.04 15:03) [13]
finally
    Unk := nil;
    CoUninitialize; // Здесь мы Завершаем работу с СOM - значит к этому моменту все интерфейсы должны быть освобождены
  end;


WondeRu   (2004-08-27 15:03:00) [22]

еще пример из VCLCom.pas - borland'овская библтотека:

procedure TApartmentThread.Execute;
var
 msg: TMsg;
 Unk: IUnknown;
begin
 try
   CoInitialize(nil);
   try
     FCreateResult := FFactory.CreateInstanceLic(FUnkOuter, nil, FIID, '', Unk);
     FUnkOuter := nil;
     FFactory := nil;
     if FCreateResult = S_OK then
       CoMarshalInterThreadInterfaceInStream(FIID, Unk, IStream(FStream));
     ReleaseSemaphore(FSemaphore, 1, nil);
     if FCreateResult = S_OK then
       while GetMessage(msg, 0, 0, 0) do
       begin
         DispatchMessage(msg);
         Unk._AddRef;
         if Unk._Release = 1 then break;
       end;
   finally
      Unk := nil;
     CoUninitialize;
   end;
 except
   { No exceptions should go unhandled }
 end;
end;


2DiamondShark
Так что почему Вы не присваиваете nil? Счетчик ссылок на объект данного интерфейса не обнулится (пока прога не завершится), соотвествсвенно объект останется в памяти, только указатель на него потеряется! (как смог так и сформулировал, а терминологией у меня проблемы:)


WondeRu   (2004-08-27 14:46:00) [23]

DiamondShark ©   (27.08.04 14:29) [10]
Компилятор сам следит за освобождением интерфейсов

и чего люди мучаются?

из модуля DSUtil.pas (входит в DSPack):

......................
 function AddGraphToRot(Graph: IFilterGraph; out ID: integer): HRESULT;
 var
   Moniker: IMoniker;
   ROT    : IRunningObjectTable;
   wsz    : WideString;
 begin
   result := GetRunningObjectTable(0, ROT);
   if (result <> S_OK) then exit;
   wsz := format('FilterGraph %p pid %x',[pointer(graph),GetCurrentProcessId()]);
   result  := CreateItemMoniker('!', PWideChar(wsz), Moniker);
   if (result <> S_OK) then exit;
   result  := ROT.Register(0, Graph, Moniker, ID);
   Moniker := nil;
 end;
.........
procedure TSysDevEnum.GetCat(catlist: TList; CatGUID: TGUID);
 var
   SysDevEnum : ICreateDevEnum;
   EnumCat    : IEnumMoniker;
   Moniker    : IMoniker;
   Fetched    : ULONG;
   PropBag    : IPropertyBag;
   Name       : olevariant;
   hr         : HRESULT;
   i          : integer;
 begin
   if catList.Count > 0 then
     for i := 0 to (catList.Count - 1) do if assigned(catList.Items[i]) then Dispose(catList.Items[i]);
   catList.Clear;
   CocreateInstance(CLSID_SystemDeviceEnum, nil, CLSCTX_INPROC, IID_ICreateDevEnum, SysDevEnum);
   hr := SysDevEnum.CreateClassEnumerator(CatGUID, EnumCat, 0);
   if (hr = S_OK) then
   begin
     while(EnumCat.Next(1, Moniker, @Fetched) = S_OK) do
       begin
         Moniker.BindToStorage(nil, nil, IID_IPropertyBag, PropBag);
         new(ACategory);
         PropBag.Read('FriendlyName', Name, nil);
         ACategory^.FriendlyName := Name;
         if (PropBag.Read('CLSID',Name,nil) = S_OK) then
           ACategory^.CLSID := StringToGUID(Name)
         else
           ACategory^.CLSID := GUID_NULL;
         catlist.Add(ACategory);
         PropBag := nil;
         Moniker := nil;
       end;
   end;
   EnumCat :=nil;
   SysDevEnum :=nil;
 end;
.............


VMcL   (2004-08-27 14:34:00) [24]

>> WondeRu ©  (27.08.04 14:13) [9]

пожалуйста, указывайте людям на ошибки в более мягкой форме (и желательно исправляйте)!

Нет проблем. Только для этого нужно советы (а особенно неправильные) тоже давать в более мягкой форме.


DiamondShark   (2004-08-27 14:29:00) [25]


> WondeRu ©   (27.08.04 14:13) [9]

Если убрать в конце SLink := nil; работать будет точно так же.

Компилятор сам следит за освобождением интерфейсов, точно так же как он это делает для строк, динмассивов и вариантов.
При выходе за область видимости интерфейс всегда будет освобождён.

И не надо так возмущаться.
В вопросе проблема была из-за неправильного обращения с PChar-ом. Ты же влез с советом, который совершенно не в тему, при этом ещё и не понимая смысла своего же предложения.


WondeRu   (2004-08-27 14:13:00) [26]

VMcL ©   (27.08.04 13:46) [6]
Чушь.

DiamondShark ©   (27.08.04 13:57) [8]
В хелп. Читать до просветления.


пожалуйста, указывайте людям на ошибки в более мягкой форме (и желательно исправляйте)!

данный вариант работает нормально

procedure TForm1.Button1Click(Sender: TObject);
var List:PItemIdList;
 SLink:IShellLink;
Folder:array[0..1000] of Char;
begin
SHGetSpecialFolderLocation(0, CSIDL_STARTUP, List);

SHGetPathFromIDList(List, Folder);
ShowMessage(Folder);
SLink:=IShellLink(CreateComObject(CLSID_ShellLink));
SLink.SetArguments('/a');
SLink.SetDescription('My Prog');
SLink.SetPath( PChar(ParamStr(0)) );
(SLink as IPersistFile).Save(PWChar(WideString(Folder+'\prog.lnk')), False);
SLink := nil;
end;


DiamondShark   (2004-08-27 13:57:00) [27]


> WondeRu ©   (27.08.04 13:51) [7]
> DiamondShark ©   (27.08.04 13:45) [5]
> Думаешь, поможет?
>
> поможет - не поможет - без понятия, но это обязательно!
> Освобождается интерфейс!

В хелп. Читать до просветления.


> New(Folder); - объясните мне эту строчку!

Это ко мне вопрос?


WondeRu   (2004-08-27 13:51:00) [28]

DiamondShark ©   (27.08.04 13:45) [5]
Думаешь, поможет?


поможет - не поможет - без понятия, но это обязательно! Освобождается интерфейс!

New(Folder); - объясните мне эту строчку!


VMcL   (2004-08-27 13:46:00) [29]

>> Goorus ©  (27.08.04 13:09)

> SLink:=IShellLink(CreateComObject(CLSID_ShellLink));

По-хорошему нужно писать так:
SLink := CreateComObject(CLSID_ShellLink) as IShellLink;

>> WondeRu ©  (27.08.04 13:40) [4]

> в конце процедуры пиши! SLink := nil

Чушь.


DiamondShark   (2004-08-27 13:45:00) [30]


> WondeRu ©   (27.08.04 13:40) [4]
> в конце процедуры пиши!
> SLink := nil

Думаешь, поможет?


WondeRu   (2004-08-27 13:40:00) [31]

в конце процедуры пиши!
SLink := nil

а нафига ярлык в автозагрузку? поверь мне, легче в реестре прописать!


DiamondShark   (2004-08-27 13:29:00) [32]

Кстати, пидл не плохо было бы потом освобождать...


Skier   (2004-08-27 13:25:00) [33]

не поможет ?
http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988622611&n=15


DiamondShark   (2004-08-27 13:25:00) [34]


>  New(Folder);

Вот мне интересно, от этой строчки что ожидалось?

procedure TForm1.Button1Click(Sender: TObject);
var
 List:PItemIdList;
 SLink:IShellLink;
  Folder:array[0..MAX_PATH] of char;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо