Forum > Windows

SHGetFileInfoW and extra-long pathes

(1/2) > >>

HomeBoy38:
Hello,

Context:
My program search for files, and make some actions on them. So far, there was a chance to have errors when the path+name was exceeding MAX_PATH, which was an opportunity to detect those.
I was looking at a bug (unhandled error) and I came to this from Microsoft : https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd. They are mentioning the "\\?\" and "\\?\UNC\" syntax which I tried (so far with a bit success, but I need a lot more tests).

Issue:
The unhandled error I was previously referring to was due to SHGetFileInfoW which was causing an error when the path was too long (and my code was wrong).
But, this function seems to fail because of the "\\?\" and "\\?\UNC\" syntax and the Microsoft's page (https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shgetfileinfow) let me think it has not been handled.

Bonus:
SHGetFileInfoW: on the forum, I saw that using SHGFI_USEFILEATTRIBUTES should speed up the function but I did not see a real difference. May I keep it anyway?
EDIT: I removed it because it does not work for folders

Function:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---// Get a file's associated iconfunction GetFileIcon(FileName: String; MyIcon: TIcon): Boolean;var FileInfo: SHFILEINFOW; Res: DWORD;begin // Get imagelist index, display name and type of file Res := SHGetFileInfoW(PWideChar(UTF8ToUTF16(FileName)), 0, FileInfo, SizeOf(FileInfo),                       SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX); if Res <> 0 then begin  MyIcon.Handle := FileInfo.hIcon;  Result := True; end else  Result := False;end; 
Calling function:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---   MyIcon := TIcon.Create;   MyFilePath := PathName + PathDelim + FileName;   if GetFileIcon(MyFilePath, MyIcon) = True then   begin    ListItem.ImageIndex := Icons.AddIcon(MyIcon);    ListItem.ImageIndex := ImageList_ReplaceIcon(Icons.ResolutionByIndex[0].Reference.Handle, ListItem.ImageIndex, MyIcon.Handle);    if (MyEXT = '.LNK') or (MyEXT = '.EXE') or (MyEXT = '.ICO') then     VLEIcons.InsertRow(IntToStr(ListItem.Index), IntToStr(ListItem.ImageIndex), True)    else     VLEIcons.InsertRow(MyEXT, IntToStr(ListItem.ImageIndex), True);   end;   MyIcon.Free; Note: VLEIcons is a TValueListEditor.

Summary:
Thanks for your input on this

marcov:
(Hint: try to just enable long file support in the resources tab of program options, please report back how it worked)

HomeBoy38:
I was not aware of such option and unfortunately, I do not find it nor found instructions how to access it: do you have any screenshot to point it to me, maybe because of my French version.

ASerge:

--- Quote from: HomeBoy38 on November 13, 2021, 01:45:30 pm ---I was not aware of such option and unfortunately, I do not find it nor found instructions how to access it: do you have any screenshot to point it to me, maybe because of my French version.

--- End quote ---
activer les chemins d’accès longs dans Windows 10, Version 1607 et versions ultérieures.
But as far as I know, shell functions still don't support long names.
And the introduced "innovation" is intended only for programs that are not written by you (without using shell functions, of course). Because in your programs, you can simply add a prefix \\?\ to the name, which removes the restriction. And it's been working for a very long time.

HomeBoy38:
I am a bit confused now: I thought marcov's suggestion was a Lazarus option to enable before building my program?

I do not want to change the operating system, \\?\ option was a good alternative to me (I will make a few tests under 7, and 32/64 OS - so far, only Win10x64 21H1 tested), only the icon retrieval was failing so far.

Navigation

[0] Message Index

[#] Next page

Go to full version