ADD: Open link to folder as folder

This commit is contained in:
Alexander Koblov 2010-07-25 06:20:47 +00:00
commit 87adbf3eb8
4 changed files with 87 additions and 4 deletions

View file

@ -59,9 +59,20 @@ end;
procedure TFileSystemExecuteOperation.MainExecute;
begin
// if file is link to folder then return fseorSymLink
if FileIsLinkToFolder(AbsolutePath, FSymLinkPath) then
begin
FExecuteOperationResult:= fseorSymLink;
Exit;
end;
// try to open by system
mbSetCurrentDir(CurrentPath);
ShellExecute(RelativePath);
case ShellExecute(RelativePath) of
True:
FExecuteOperationResult:= fseorSuccess;
False:
FExecuteOperationResult:= fseorError;
end;
end;
procedure TFileSystemExecuteOperation.Finalize;

View file

@ -29,7 +29,7 @@ interface
uses
SysUtils, Classes, LCLProc, uClassesEx, uTypes
{$IF DEFINED(MSWINDOWS)}
, Windows, ShellApi, uNTFSLinks, uMyWindows, JwaWinNetWk
, Windows, ShellApi, uNTFSLinks, uMyWindows, JwaWinNetWk, uShlObjAdditional
{$ELSEIF DEFINED(UNIX)}
, BaseUnix, Unix, UnixType, dl, uFileAttributes
{$IFDEF DARWIN}
@ -115,6 +115,7 @@ function FileIsExeLib(const sFileName : String) : Boolean;
@returns(The function returns @true if successful, @false otherwise)
}
function FileIsReadOnly(iAttr: TFileAttrs): Boolean;
function FileIsLinkToFolder(const FileName: UTF8String; out LinkTarget: UTF8String): Boolean;
function FileCopyAttr(const sSrc, sDst:String; bDropReadOnlyFlag : Boolean):Boolean;
function ExecCmdFork(sCmdLine:String; bTerm : Boolean = False; sTerm : String = ''; bKeepTerminalOpen: Boolean = True):Boolean;
{en
@ -452,6 +453,22 @@ begin
end;
{$ENDIF}
function FileIsLinkToFolder(const FileName: UTF8String; out
LinkTarget: UTF8String): Boolean;
{$IF DEFINED(MSWINDOWS)}
begin
Result:= False;
if LowerCase(ExtractOnlyFileExt(FileName)) = 'lnk' then
Result:= SHFileIsLinkToFolder(FileName, LinkTarget);
end;
{$ELSEIF DEFINED(UNIX)}
begin
Result:= False;
if LowerCase(ExtractOnlyFileExt(FileName)) = 'desktop' then
Result:= uMyUnix.FileIsLinkToFolder(FileName, LinkTarget);
end;
{$ENDIF}
function FileCopyAttr(const sSrc, sDst:String; bDropReadOnlyFlag : Boolean):Boolean;
{$IFDEF MSWINDOWS}
var

View file

@ -163,13 +163,16 @@ function fpCloseDir(__dirp: pDir): cInt; cdecl; external libc name 'closedir';
function LinuxToWinAttr(pFileName: PChar; const srInfo: BaseUnix.Stat): Longint;
function GetDesktopEnvironment: Cardinal;
function FileIsLinkToFolder(const FileName: UTF8String; out LinkTarget: UTF8String): Boolean;
implementation
{$IFNDEF FPC_USE_LIBC}
uses
SysCall;
uClassesEx, uClipboard
{$IFNDEF FPC_USE_LIBC}
, SysCall
{$ENDIF}
;
{$IFNDEF FPC_USE_LIBC}
@ -212,5 +215,26 @@ begin
Exit(DE_XFCE);
end;
function FileIsLinkToFolder(const FileName: UTF8String; out LinkTarget: UTF8String): Boolean;
var
iniDesktop: TIniFileEx = nil;
StatInfo: BaseUnix.Stat;
begin
Result:= False;
try
iniDesktop:= TIniFileEx.Create(FileName, fmOpenRead);
if iniDesktop.ReadString('Desktop Entry', 'Type', EmptyStr) = 'Link' then
begin
LinkTarget:= iniDesktop.ReadString('Desktop Entry', 'URL', EmptyStr);
LinkTarget:= URIDecode(LinkTarget);
if fpLStat(PAnsiChar(LinkTarget), StatInfo) <> 0 then Exit;
Result:= FPS_ISDIR(StatInfo.st_mode);
end;
finally
if Assigned(iniDesktop) then
FreeAndNil(iniDesktop);
end;
end;
end.

View file

@ -1802,6 +1802,7 @@ function SHGetDesktopFolder(var ppshf: IShellFolder): HResult; stdcall;
function SHChangeIconDialog(hOwner: THandle; var FileName: UTF8String; var IconIndex: Integer): Boolean;
function SHGetOverlayIconIndex(const sFilePath, sFileName: UTF8String): Integer;
function SHGetInfoTip(const sFilePath, sFileName: UTF8String): UTF8String;
function SHFileIsLinkToFolder(const FileName: UTF8String; out LinkTarget: UTF8String): Boolean;
function PathIsUNCA(pszPath: LPCSTR): WINBOOL; stdcall; external 'shlwapi' name 'PathIsUNCA';
function PathIsUNCW(pwszPath: LPCWSTR): WINBOOL; stdcall; external 'shlwapi' name 'PathIsUNCW';
@ -1991,6 +1992,36 @@ begin
end;
end;
function SHFileIsLinkToFolder(const FileName: UTF8String; out LinkTarget: UTF8String): Boolean;
var
Unknown: IUnknown;
ShellLink: IShellLinkW;
PersistFile: IPersistFile;
FindData: TWin32FindDataW;
pszFile:LPWSTR;
begin
Result := False;
try
Unknown := CreateComObject(CLSID_ShellLink);
ShellLink := Unknown as IShellLinkW;
PersistFile := Unknown as IPersistFile;
if Failed(PersistFile.Load(PWideChar(UTF8Decode(FileName)), OF_READ)) then Exit;
pszFile:= GetMem(MAX_PATH * 2);
try
if Failed(ShellLink.GetPath(pszFile, MAX_PATH, @FindData, 0)) then Exit;
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
begin
LinkTarget := UTF8Encode(WideString(pszFile));
Result := (LinkTarget <> EmptyStr);
end;
finally
FreeMem(pszFile);
end;
except
LinkTarget := EmptyStr;
end;
end;
procedure OleErrorUTF8(ErrorCode: HResult);
begin
raise EOleError.Create(UTF8Encode(SysErrorMessage(ErrorCode)));