unit Lnk; {* Additional unit. Has two procedures to get system folder by its CSIDL and to create shortcut to the specified file object. Sources are from public place. Actually, made on base of sample from MSDN. Adapted to use with KOL. Last update: 17-May-2007 (with KOL v 2.61) } interface {$I KOLDEF.INC} uses windows, shlobj, ShellAPI, ActiveX, {OLE2,} KOL; function GetSystemFolder(Const Folder:integer):string; {* Returns specified system folder location. Following constant can be passed as a parameter: |
CSIDL_DESKTOPsee other in documentation on API "CSIDL Values" } function CreateLinkDesc(const FileName,Arguments,WorkDir,IconFile:String; IconNumber:integer; LinkName:String; Description:String ): Boolean; {* Creates a shortcut with description. } function CreateLink(const FileName,Arguments,WorkDir,IconFile:String; IconNumber:integer; LinkName:String ): Boolean; {* Creates a shortcut to specified file object. An example: ! ! CreateLink( ParamStr( 0 ), '', '', '', 1, GetSystemFolder(CSIDL_DESKTOP)+ ! '\MyProg.lnk' ); } function ResolveLink( const LinkName: KOLString; var FileName, Arguments, WorkDir, Description: KOLString; var IconSmall, IconLarge: HIcon; need_icons: Boolean; DialogParentWnd: HWND ): Boolean; {* Attempts to resolve given link (given by a path to link file). If a link is resolved, TRUE returned and FileName, Arguments, WorkDir, Description, Icon(s) fields are containing resolved parameters of the link. Set ParentDialogWnd to a handle of your window (or 0), if a dialog is allowed to appear if linked file is absent (moved or renamed). If DialogParentWnd = THandle(-1) and linked file is not found, FALSE is returned silently, without showing dialog box. |(root of namespace) CSIDL_PROGRAMS Start Menu\Programs CSIDL_STARTMENU Settings\username\Start Menu CSIDL_PERSONAL Settings\username\My Documents CSIDL_FAVORITES CSIDL_STARTUP CSIDL_INTERNET CSIDL_CONTROLS CSIDL_PRINTERS CSIDL_RECENT CSIDL_SENDTO CSIDL_BITBUCKET |
FExt - file extension расширение файла Desc - file type description описание типа файла Cmd - context menu command команда для контекстного меню Exe - path to executable путь к исполняемому файлу Default - if command is default назначается действием по умолчанию Run - if reaction needed when clicked нужны ли действия при щелчке на файле с таким расширением |Example: ! FileTypeReg('.abc','ABC Data File','Open','d:\abc_edit.exe',True); } function FileTypeGetReg(const FExt,Cmd: KOLString; var Desc, OldIcoExe: KOLString; var OldIcoIdx: Integer; var OldId: KOLString ): KOLString; {* Get registered file type association, if any (by command). |
in: FExt - file extension расширение файла Cmd - context menu command команда для контекстного меню out: Desc - file type description описание типа файла Result - path to executable путь к исполняемому файлу |Shell is always notified about file association changes. See also FileTypeRegEx. } procedure FileTypeRegEx(FExt,Desc,Cmd,Exe: string; IconIndex: integer; Default,Run: boolean; const IcoExe: String; NotifyShell: Boolean ); {* The same as FileTypeReg, but additional parameters are available: IcoExe - file where the icon is stored; NotifyShell - TRUE if to notify shell about changes. } procedure FileTypeReg2(FExt,Desc,Cmd,Exe,Id: string; IconIndex: integer; Default,Run: boolean; const IcoExe: String; DfltIcoExe: String; NotifyShell: Boolean ); {* The same as above (FileTypeRegEx), but should also work in XP. Provide ID string in form 'Vendor.Appname.Version', e.g. 'Litcorp Inc.My App.5'. DfltIcoExe and DfltIcoIndex are used to set default application icon, this does affect associations of other files with the application, not having its own DefaultIcon settings in the registry. } function FileTypeReg2Ex(FExt,Desc,Cmd,Exe,Id: string; IconIndex: integer; Default,Run: boolean; const IcoExe: String; DfltIcoExe: String; NotifyShell: Boolean ): String; {* The same as above (FileTypeReg2), but also returs a string which can be passed later to FileTypeUnreg as a parameter to undo registration to a previous state. } procedure FileTypeUnreg( const UndoStr: String; NotifyShell: Boolean ); {* Pass as UndoStr a string returned by FileTypeReg2Ex to undo the association made with it. } function RegKeyDeleteAll( Key: HKey; const Subkey: KOLString ): Boolean; {* In addition to RegKeyXXXXX functions in KOL.pas, allows to delete entire key with all nested keys and values (careful, please!) } implementation function GetSystemFolder(Const Folder:integer):string; var PIDL: PItemIDList; Path: array[ 0..MAX_PATH ] of Char; begin Result := ''; if SHGetSpecialFolderLocation(0, Folder, PIDL) = NOERROR then begin if SHGetPathFromIDList(PIDL, Path) then Result := IncludeTrailingPathDelimiter( Path ); CoTaskMemFree( PIDL ); end; end; const IID_IPersistFile: TGUID = ( D1:$0000010B;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46)); function CreateLink(const FileName,Arguments,WorkDir,IconFile:String; IconNumber:integer; LinkName:String ): Boolean; begin Result := CreateLinkDesc( FileName, Arguments, WorkDir, IconFile, IconNumber, LinkName, '' ); end; function CreateLinkDesc(const FileName,Arguments,WorkDir,IconFile:String; IconNumber:integer; LinkName:String; Description:String): Boolean; var SLink : IShellLink; PFile : IPersistFile; WFileName : WideString; begin Result := FALSE; CoInitialize( nil ); if CoCreateInstance( TGUID( CLSID_ShellLink ), nil, CLSCTX_INPROC_SERVER, TGUID( IID_IShellLinkA ), SLink ) <> S_OK then Exit; if SLink.QueryInterface( System.TGUID( IID_IPersistFile ), PFile ) <> S_OK then Exit; SLink.SetArguments(PChar(Arguments)); SLink.SetPath(PChar(FileName)); SLink.SetWorkingDirectory(PChar(WorkDir)); SLink.SetDescription(PChar(Description)); SLink.SetIconLocation(PChar(IconFile),IconNumber); if not DirectoryExists(ExtractFilePath(LinkName)) then CreateDir( ExtractFilePath(LinkName) ); WFileName := LinkName; PFile.Save(PWChar(WFileName),False); Result := TRUE; end; {$IFDEF UNICODE_CTRLS} type IShellLink_ = IShellLinkW; {$ELSE} type IShellLink_ = IShellLinkA; {$ENDIF} function ResolveLink( const LinkName: KOLString; var FileName, Arguments, WorkDir, Description: KOLString; var IconSmall, IconLarge: HIcon; need_icons: Boolean; DialogParentWnd: HWND ): Boolean; var SLink : IShellLink_; PFile : IPersistFile; WFileName : WideString; Wnd: HWnd; Flg: DWORD; Buf: array[ 0..4095 ] of KOLChar; FD: TWin32FindData; I: Integer; begin Result := FALSE; CoInitialize( nil ); if CoCreateInstance( TGUID( CLSID_ShellLink ), nil, CLSCTX_INPROC_SERVER, TGUID( IID_IShellLinkA ), SLink ) <> S_OK then Exit; if SLink.QueryInterface( System.TGUID( IID_IPersistFile ), PFile ) <> S_OK then Exit; WFileName := LinkName; PFile.Load(PWChar(WFileName),STGM_READ); Wnd := DialogParentWnd; if Wnd = THandle( -1 ) then Wnd := 0; Flg := SLR_UPDATE; if DialogParentWnd = THandle(-1) then Flg := SLR_NO_UI; if SLink.Resolve( Wnd, Flg ) = NOERROR then begin if SLink.GetPath( Buf, Sizeof( Buf ) div Sizeof( KOLChar ), PWin32FindDataA(@ FD)^ {error in ShlObj.pas !} , 0 ) <> NOERROR then FileName := '' else FileName := Buf; if SLink.GetArguments( Buf, Sizeof( Buf ) ) <> NOERROR then Exit; Arguments := Buf; if SLink.GetWorkingDirectory( Buf, Sizeof( Buf ) div Sizeof( KOLChar ) ) <> NOERROR then Exit; WorkDir := Buf; if SLink.GetDescription( Buf, Sizeof( Buf ) div Sizeof( KOLChar ) ) <> NOERROR then Exit; Description := Buf; IconSmall := 0; IconLarge := 0; if need_icons and (SLink.GetIconLocation( Buf, Sizeof( Buf ) div Sizeof( KOLChar ), I ) = NOERROR) then {$IFDEF UNICODE_CTRLS} ExtractIconExW( Buf, I, IconLarge, IconSmall, 1 ); {$ELSE} ExtractIconExA( Buf, I, IconLarge, IconSmall, 1 ); {$ENDIF} Result := TRUE; end; end; function IsLink2RecycleBin( const LinkName: String ): Boolean; var SLink : IShellLink; PFile : IPersistFile; WFileName : WideString; Flg: DWORD; ppidl, ppidl1, p, p1: PItemIDList; begin Result := FALSE; CoInitialize( nil ); if CoCreateInstance( TGUID( CLSID_ShellLink ), nil, CLSCTX_INPROC_SERVER, TGUID( IID_IShellLinkA ), SLink ) <> S_OK then Exit; if SLink.QueryInterface( System.TGUID( IID_IPersistFile ), PFile ) <> S_OK then Exit; WFileName := LinkName; PFile.Load(PWChar(WFileName),STGM_READ); Flg := SLR_NO_UI; if SLink.Resolve( 0, Flg ) = NOERROR then begin if SLink.GetIDList( ppidl ) = NOERROR then begin if SHGetSpecialFolderLocation( 0, CSIDL_BITBUCKET, ppidl1 ) = NOERROR then begin Result := TRUE; p := ppidl; p1 := ppidl1; while TRUE do begin if (p1.mkid.cb = p.mkid.cb) and (p1.mkid.cb = 0) then break; if (p1.mkid.cb <> p.mkid.cb) or not CompareMem( @ p.mkid.abID[ 0 ], @ p1.mkid.abID[ 0 ], p.mkid.cb ) then begin Result := FALSE; break; end; p := Pointer( Integer( p ) + p.mkid.cb ); p1 := Pointer( Integer( p1 ) + p1.mkid.cb ); end; CoTaskMemFree( ppidl1 ); end; CoTaskMemFree( ppidl ); end; end; end; function RegKeyDeleteAll( Key: HKey; const Subkey: KOLString ): Boolean; type TSHDeleteKey = function( Key: HKey; Subkey: PKOLChar ): DWORD; stdcall; var SHDeleteKey: TSHDeleteKey; M: THandle; begin Result := FALSE; M := LoadLibrary( 'shlwapi.dll' ); if M <> 0 then TRY SHDeleteKey := GetProcAddress( M, {$IFDEF UNICODE_CTRLS} 'SHDeleteKeyW' {$ELSE} 'SHDeleteKeyA' {$ENDIF} ); if Assigned( SHDeleteKey ) then Result := SHDeleteKey( Key, PKOLChar( SubKey ) ) = 0; FINALLY FreeLibrary( M ); END; end; procedure FileTypeRegEx(FExt,Desc,Cmd,Exe: string; IconIndex: integer; Default,Run: boolean; const IcoExe: String; NotifyShell: Boolean ); begin FileTypeRegEx( FExt, Desc, Cmd, Exe, IconIndex, Default, Run, IcoExe, NotifyShell ); end; //[procedure FileTypeReg] procedure FileTypeReg(FExt,Desc,Cmd,Exe: string; IconIndex: integer; Default,Run: boolean); begin FileTypeRegEx( Fext,Desc,Cmd,Exe, IconIndex, Default, Run, Exe, TRUE ); end; procedure FileTypeReg2(FExt,Desc,Cmd,Exe,Id: string; IconIndex: integer; Default,Run: boolean; const IcoExe: String; DfltIcoExe: String; NotifyShell: Boolean ); var Reg: HKey; Key: string; begin Reg:=RegKeyOpenWrite(HKEY_CLASSES_ROOT,'Applications'); //if not RegKeyExists(Reg,ExtractFileName(Exe)) then begin RegKeyClose(Reg); Reg := RegKeyOpenCreate(HKEY_CLASSES_ROOT, 'Applications\'+ExtractFileName(Exe)+'\Shell\Open\Command'); RegKeySetStr(Reg,'',Exe+' "%1"'); RegKeyClose(Reg); end; //else RegKeyClose( Reg ); // {VK} if Id <> '' then begin Reg := RegKeyOpenCreate(HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\' + FExt); RegKeySetStr( Reg, 'Progid', Id ); RegKeyClose( Reg ); end; // HKCR\.ext Default=extfile Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,FExt); Key:=LowerCase(FExt)+'file'; Delete(Key,1,1); RegKeySetStr(Reg,'',Key); RegKeyClose(Reg); // HKCR\extfile Default=id if Id <> '' then begin Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key); RegKeySetStr(Reg,'',Id); RegKeyClose(Reg); end; // HKCR\id Default=pathto.exe if Id <> '' then begin Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Id); RegKeySetStr(Reg,'',Exe); RegKeyClose(Reg); end; if DfltIcoExe <> '' then begin // HKCR\id\DefaultIcon Default=DfltIcoExe Reg := RegKeyOpenCreate(HKEY_CLASSES_ROOT,Id + '\DefaultIcon'); RegKeySetStr(Reg,'',DfltIcoExe); RegKeyClose( Reg ); end; if (IcoExe <> '') {or (IconIndex<>-1)} then begin Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\DefaultIcon'); if IconIndex = -1 then RegKeySetStr(Reg,'',IcoExe + ',0' ) else RegKeySetStr(Reg,'',IcoExe + ',' + Int2Str(IconIndex) ); RegKeyClose(Reg); end; if Run then begin {Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\Shell'); if Default then RegKeySetStr(Reg,'',Cmd) else RegKeySetStr(Reg,'',''); RegKeyClose(Reg); Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\Shell\'+Cmd); RegKeyClose(Reg);} {$IFNDEF LNK_NODELETE_OLDCMD} Reg := RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\Shell\'); RegKeyDeleteAll( Reg, Cmd ); if Default then RegKeySetStr(Reg,'',Cmd); RegKeyClose( Reg ); {$ENDIF} Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\Shell\'+Cmd+'\Command'); RegKeySetStr(Reg,'',Exe+' "%1"'); RegKeyClose(Reg); end; //+ {VK} if NotifyShell then begin SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil ); //SHChangeNotify( SHCNE_ALLEVENTS, SHCNF_IDLIST, nil, nil ); end; end; function FileTypeReg2Ex(FExt,Desc,Cmd,Exe,Id: string; IconIndex: integer; Default,Run: boolean; const IcoExe: String; DfltIcoExe: String; NotifyShell: Boolean ): String; var Reg: HKey; Key: string; Strm: PStream; procedure add4Undo( const RegClass, RegKey, Cmd, Value: String ); var s: String; begin s := RegClass+','; if RegKey <> '' then s := s +Int2Str(Length(RegKey))+'('+RegKey+'),'; s := s+Cmd; if Value <> '' then s := s + ',' + Int2Str(Length(Value))+'('+Value+')'; Strm.WriteStr( s+#13 ); end; procedure DeleteAllSubKeys( const RegClass, RegKey: String; Reg: THandle; const SubKey: String ); var SL: PKOLStrList; i: Integer; Reg1: THandle; procedure not_supported; asm nop end; begin SL := NewKOLStrList; Reg1 := RegKeyOpenWrite( Reg, SubKey ); TRY RegKeyGetSubKeys(Reg1, SL); for i := 0 to SL.Count-1 do begin DeleteAllSubKeys( RegClass, RegKey + '\' + SL.Items[ i ], Reg1, SL.Items[ i ] ); end; SL.Clear; RegKeyGetValueNames( Reg1, SL ); for i := 0 to SL.Count-1 do begin //todo: support more types of values CASE RegKeyGetValueTyp(Reg1, SL.Items[ i ]) OF REG_BINARY: not_supported; REG_DWORD : // = REG_DWORD_LITTLE_ENDIAN add4Undo( RegClass, RegKey, 'd=' + SL.Items[i], Int2Str( RegKeyGetDw(Reg1,SL.Items[i]) ) ); REG_DWORD_BIG_ENDIAN: add4Undo( RegClass, RegKey, 'D=' + SL.Items[i], Int2Str( RegKeyGetDw(Reg1,SL.Items[i]) ) ); REG_EXPAND_SZ: add4Undo( RegClass, RegKey, 'X=' + SL.Items[i], RegKeyGetStr(Reg1,SL.Items[i]) ); REG_LINK: not_supported; REG_MULTI_SZ: not_supported; REG_NONE: not_supported; REG_RESOURCE_LIST: not_supported; REG_SZ: add4Undo( RegClass, RegKey, 'S=' + SL.Items[i], RegKeyGetStr(Reg1,SL.Items[i]) ); END; end; FINALLY SL.Free; RegKeyClose( Reg1 ); add4Undo( RegClass, RegKey, 'K-', SubKey ); RegKeyDelete( Reg, SubKey ); END; end; function q( const s: String ): String; begin if pos( ' ', s ) > 0 then Result := '"' + s + '"' else Result := s; end; begin Result := ''; Strm := NewMemoryStream; TRY Reg:=RegKeyOpenWrite(HKEY_CLASSES_ROOT,'Applications'); if not RegKeyExists( Reg, ExtractFileName(Exe) ) then add4Undo( 'HKCR', 'Applications', 'K+', ExtractFileName(Exe)+'\Shell\Open\Command' ); //if not RegKeyExists(Reg,ExtractFileName(Exe)) then begin RegKeyClose(Reg); Reg := RegKeyOpenCreate(HKEY_CLASSES_ROOT, 'Applications\'+ExtractFileName(Exe)+'\Shell\Open\Command'); add4Undo( 'HKCR', 'Applications\'+ExtractFileName(Exe)+'\Shell\Open\Command', 'S=', RegKeyGetStr(Reg,'') ); RegKeySetStr(Reg,'',q(Exe)+' "%1"'); RegKeyClose(Reg); end; //else RegKeyClose( Reg ); // {VK} if Id <> '' then begin if not RegKeyExists( HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\' + FExt ) then add4Undo( 'HKCU', '', 'K+', 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\' + FExt ); Reg := RegKeyOpenCreate(HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\' + FExt); if not RegKeyValExists( Reg, 'ProgId' ) then add4Undo( 'HKCU', 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\' + FExt, 'V+', 'ProgId' ) else add4Undo( 'HKCU', 'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\' + FExt, 'S=ProgId', RegKeyGetStr(Reg,'ProgId') ); RegKeySetStr( Reg, 'Progid', Id ); RegKeyClose( Reg ); end; // HKCR\.ext Default=extfile if not RegKeyExists( HKEY_CLASSES_ROOT, FExt ) then add4Undo( 'HKCR', '', 'K+', FExt ); Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,FExt); Key:=LowerCase(FExt)+'file'; Delete(Key,1,1); add4Undo( 'HKCR', FExt, 'S=', RegKeyGetStr( Reg, '' ) ); RegKeySetStr(Reg,'',Key); RegKeyClose(Reg); // HKCR\extfile Default=id if Id <> '' then begin if not RegKeyExists( HKEY_CLASSES_ROOT, Key ) then add4Undo( 'HKCR', '', 'K+', Key ); Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key); add4Undo( 'HKCR', Key, 'S=', RegKeyGetStr( Reg, '' ) ); RegKeySetStr(Reg,'',Id); RegKeyClose(Reg); end; // HKCR\id Default=pathto.exe if Id <> '' then begin if not RegKeyExists( HKEY_CLASSES_ROOT, Id ) then add4Undo( 'HKCR', '', 'K+', Id ); Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Id); add4Undo( 'HKCR', Id, 'S=', RegKeyGetStr( Reg, '' ) ); RegKeySetStr(Reg,'',Exe); RegKeyClose(Reg); end; if DfltIcoExe <> '' then begin // HKCR\id\DefaultIcon Default=DfltIcoExe if not RegKeyExists( HKEY_CLASSES_ROOT, Id + '\DefaultIcon' ) then add4Undo( 'HKCR', '', 'K+', Id + '\DefaultIcon' ); Reg := RegKeyOpenCreate(HKEY_CLASSES_ROOT,Id + '\DefaultIcon'); add4Undo( 'HKCR', Id+'\DefaultIcon', 'S=', RegKeyGetStr( Reg, '' ) ); RegKeySetStr(Reg,'',DfltIcoExe); RegKeyClose( Reg ); end; if (IcoExe <> '') then begin if not RegKeyExists( HKEY_CLASSES_ROOT, Key + '\DefaultIcon' ) then add4Undo( 'HKCR', '', 'K+', Key + '\DefaultIcon' ); Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\DefaultIcon'); add4Undo( 'HKCR', Key+'\DefaultIcon', 'S=', RegKeyGetStr( Reg, '' ) ); if IconIndex = -1 then RegKeySetStr(Reg,'',IcoExe + ',0' ) else RegKeySetStr(Reg,'',IcoExe + ',' + Int2Str(IconIndex) ); RegKeyClose(Reg); end; if Run then begin {$IFNDEF LNK_NODELETE_OLDCMD} if not RegKeyExists( HKEY_CLASSES_ROOT, Key + '\Shell' ) then add4Undo( 'HKCR', '', 'K+', Key + '\Shell' ); Reg := RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\Shell\'); DeleteAllSubKeys( 'HKCR', Key + '\Shell', Reg, Cmd ); if Default then begin add4Undo( 'HKCR', Key+'\Shell', 'S=', RegKeyGetStr( Reg, '' ) ); RegKeySetStr(Reg,'',Cmd); end; RegKeyClose( Reg ); {$ENDIF} if not RegKeyExists( HKEY_CLASSES_ROOT, Key+'\Shell\'+Cmd+'\Command' ) then add4Undo( 'HKCR', '', 'K+', Key+'\Shell\'+Cmd+'\Command' ); Reg:=RegKeyOpenCreate(HKEY_CLASSES_ROOT,Key+'\Shell\'+Cmd+'\Command'); add4Undo( 'HKCR', Key+'\Shell\'+Cmd+'\Command', 'S=', RegKeyGetStr( Reg, '' ) ); RegKeySetStr(Reg,'',Exe+' "%1"'); RegKeyClose(Reg); end; if NotifyShell then SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil ); SetString( Result, PChar( Strm.Memory ), Strm.Size ); FINALLY Strm.Free; END; end; procedure FileTypeUnreg( const UndoStr: String; NotifyShell: Boolean ); var SL: PStrList; i: Integer; s: KOLString; RegClass, RegKey, Cmd, Value, ValName: KOLString; R: THandle; Cls: DWORD; procedure ExtractStr( var s: KOLString ); var i: Integer; begin if s = '' then Exit; i := Str2Int( s ); if i = 0 then Exit; Parse( s, '(' ); s := Copy( s, 1, i ); end; begin SL := NewStrList; TRY SL.Text := UndoStr; for i := SL.Count-1 downto 0 do begin s := SL.Items[ i ]; RegClass := Parse( S, ',' ); RegKey := Parse( S, ',' ); ExtractStr( RegKey ); Cmd := Parse( s, ',' ); Value := s; ExtractStr( Value ); if RegClass = 'HKCU' then Cls := HKEY_CURRENT_USER else if RegClass = 'HKLM' then Cls := HKEY_LOCAL_MACHINE else if RegClass = 'HKCR' then Cls := HKEY_CLASSES_ROOT else Cls := HKEY_CURRENT_USER; if Cmd = 'K+' then // удалить ключ RegKeyDelete( Cls, RegKey ) else if Cmd = 'K-' then // восстановить ключ begin R := RegKeyOpenCreate( Cls, RegKey + '\' + Value ); RegKeyClose( R ); end else begin R := RegKeyOpenWrite( Cls, RegKey ); ValName := CopyEnd( Cmd, 3 ); TRY if Cmd = 'V+' then // удалить значение RegKeyDeleteValue( R, Value ) else if Cmd[1] = 'S' then // восстановить строковое значение RegKeySetStr( R, ValName, Value ) else if Cmd[1] = 'd' then // восстановить значение типа DWORD: RegKeySetDw( R, ValName, Str2Int( Value ) ) else if Cmd[1] = 'X' then RegKeySetStrEx( R, ValName, Value, TRUE ); FINALLY RegKeyClose( R ); END; end; end; if NotifyShell then SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil ); FINALLY SL.Free; END; end; function FileTypeGetReg(const FExt,Cmd: KOLString; var Desc, OldIcoExe: KOLString; var OldIcoIdx: Integer; var OldId: KOLString ): KOLString; var Reg: HKey; Key: KOLString; S: KOLString; begin Result := ''; Desc := ''; Reg := RegKeyOpenRead(HKEY_CLASSES_ROOT,FExt); if Reg = 0 then Exit; OldId := RegKeyGetStr( Reg, '' ); Key:=LowerCase(FExt)+'file'; Delete(Key,1,1); Key := RegKeyGetStr(Reg,''); RegKeyClose(Reg); Reg:=RegKeyOpenRead(HKEY_CLASSES_ROOT,Key); Desc := RegKeyGetStr(Reg,''); RegKeyClose(Reg); Reg:=RegKeyOpenRead(HKEY_CLASSES_ROOT,Key+'\Shell\'+Cmd+'\Command'); Result := Trim( RegKeyGetStr(Reg,'') ); RegKeyClose(Reg); if CopyTail( Result, 4 ) = '"%1"' then Result := Trim( Copy( Result, 1, Length( Result )-4 ) ); Reg:=RegKeyOpenRead(HKEY_CLASSES_ROOT,Key+'\DefaultIcon'); S := RegKeyGetStr(Reg,'' ); OldIcoExe := Parse( S, ',' ); OldIcoIdx := Str2Int( S ); RegKeyClose(Reg); end; end.