介绍
在Windows 7中,您有一些文件,图片和音乐等特殊文件夹,称为库。
如果你不知道他们,基本上每个库文件夹可以包含位置(path),这基本上是每个库的快捷方式。
一些例子:
如何检查是否有默认打印机(Windows)?
Windows视觉主题:部件和国家图库?
CreateProcess钩子添加CommandLine
RegisterDragDrop返回S_OK,但不调用dragenter方法
德尔菲计时器比毫秒更精确
Documents (Library)
E:个人文件(Location)
F: Backups Documents (Location)
Music (Library)
E: Media Music Albums (Location)
E: Media Music Singles (Location)
Pictures (Library)
E:媒体照片(Location)
当您从Windows资源pipe理器或“开始”菜单中单击任何这些库文件夹时,Windows资源pipe理器将显示该库中定义的位置。
任务
我需要做的是读取每个库types的位置,并能够用我自己的位置写回(更新)库。 我发现这些库存储在用户的AppData文件夹中,如下所示:
C:UseRSSOMEUSERAppDaTaroamingMicrosoftwindowsLibraries
这些库是这种文件types: 库(.library-ms) – 如果你右键点击一个,select属性,库选项卡,你可以看到与该库相关联的库位置。
我没有看到解压缩这些方法,并把它们放在一个TStringList中,以便在Delphi中进行编辑。 我想知道,如果这些库位置实际存储在Windowsregistry,所以从谷歌的一些研究,我发现这些path:
HKEY_CURRENT_USER Software Microsoft Windows CurrentVersion Explorer Shell文件夹
HKEY_CURRENT_USER Software Microsoft Windows CurrentVersion Explorer User Shell Folders
但是,我再次看不到实际的库位置列表。
那么,如何在Delphi中读取库文件中的位置列表,将它们添加到ListBox或TStringList,编辑条目,然后写回更改? 刚刚能够提取库位置path将是一个开始。
我只是有一种感觉,这将是一个简单的答案,我似乎无法find的问题之一!
在Windows 8中,具有pipe理员权限的Delphi外部exe被最小化
我可以打开/closures个别键盘上的Capslock指示灯吗?
RTTI元数据存储在可执行文件中的位置在哪里?
如何为仅用于远程COM对象的TLB创build清单文件?
我怎样才能让任务pipe理器杀死我的程序?
使用SHLoadLibraryFrom...()函数SHLoadLibraryFromKNownFolder()如SHLoadLibraryFromKNownFolder()来获取IShellLibrary接口,然后可以使用其方法来枚举和操作库,例如IShellLibrary::GetFolders() , IShellLibrary::AddFolder() , IShellLibrary::RemoveFolder()等
更新:例如:
uses ...,ActiveX,KNownFolders,ShlObj; // The SHLoadLibraryFrom...() functions are implemented inline in the Win32 SDK // shobjidl.h header file,so you have to implement them manually in your // code if you you are not using a version of Delphi that already implements // them in the RTL's ShlObj.pas unit for you... // SHLoadLibraryFromKNownFolder() is defined wrong in ShlObj.pas!!! See QC #109306 function My_SHLoadLibraryFromKNownFolder(const kfidLibrary: TGUID; grfMode: DWORD; riid: TIID; out ppv): HRESULT; var plib: IShellLibrary; begin Result := CoCreateInstance(CLSID_ShellLibrary,nil,CLSCTX_INPROC_SERVER,IShellLibrary,plib); if SUCCEEDED(Result) then begin Result := plib.LoadLibraryFromKNownFolder(kfidLibrary,grfMode); if SUCCEEDED(Result) then Result := plib.QueryInterface(riid,ppv); end; end; function GetLibraryFileSystemFolders(FolderID: TGUID; Folders: TStrings): Boolean; var SL: IShellLibrary; Arr: IShellItemArray; Enum: IEnumShellItems; Item: IShellItem; Path: LPWSTR; begin Result := False; if Failed(My_SHLoadLibraryFromKNownFolder(FolderID,STGM_READ,SL)) then Exit; if Failed(SL.GetFolders(LFF_FORCEFILESYstem,IShellItemArray,Arr)) then Exit; if Failed(Arr.EnumItems(Enum)) then Exit; while Enum.Next(1,Item,nil) = S_OK then begin if Failed(Item.GetdisplayName(SIGDN_FILESYSPATH,Path)) then Exit; try Folders.Add(Path); finally CoTaskMemFree(Path); end; Item := nil; end; Result := True; end;
。
var Folders: TStringList; begin Folders := TStringList.Create; try if GetLibraryFileSystemFolders(FOLDERID_DocumentsLibrary,Folders) then begin //... end; finally Folders.Free; end; end;
更新 : SHLoadLibraryFromKNownFolder()仅适用于定义了KNowNFOLDERID值的Microsoft定义的库。 如果要访问自定义库,则必须使用稍微修改的方法来获取IShellLibrary接口,例如:
// SHLoadLibraryFromItem() is defined wrong in ShlObj.pas!!! See QC #109306 function My_SHLoadLibraryFromItem(const psiLibrary: IShellItem; grfMode: DWORD; const riid: TIID; out ppv): HResult; var plib: IShellLibrary; begin Result := CoCreateInstance(CLSID_ShellLibrary,IID_IShellLibrary,plib); if Succeeded(Result) then begin Result := plib.LoadLibraryFromItem(psiLibrary,grfMode); if Succeeded(Result) then Result := plib.QueryInterface(riid,ppv); end; end; function GetShellLibraryforLibrary(const LibraryName: String; grfMode: DWORD; var ppv: IShellLibrary): Boolean; var SL: IShellLibrary; Enum: IEnumShellItems; Item: IShellItem; displayName: LPWSTR; hr: HRESULT; begin Result := False; ppv := nil; if Failed(SHGetKNownFolderItem(FOLDERID_Libraries,IShellItem,PPointer(@Item)^) then Exit; hr := Item.BindToHandler(nil,BHID_EnumItems,IEnumShellItems,Enum); if Failed(hr) then Exit; Item := nil; while Enum.Next(1,nil) = S_OK do begin if Failed(Item.GetdisplayName(SIGDN_norMALdisPLAY,displayName)) then Exit; try if AnsiSameText(displayName,LibraryName) then begin Result := SUCCEEDED(My_SHLoadLibraryFromItem(Item,grfMode,ppv)); Break; end; finally CoTaskMemFree(displayName); end; Item := nil; end; end; function GetLibraryFileSystemFolders(const LibraryName: String; Folders: TStrings): Boolean; var SL: IShellLibrary; Arr: IShellItemArray; Enum: IEnumShellItems; Item: IShellItem; Path: LPWSTR; begin Result := False; if not GetShellLibraryforLibrary(LibraryName,SL) then Exit; if Failed(SL.GetFolders(LFF_FORCEFILESYstem,Path)) then Exit; try Folders.Add(Path); finally CoTaskMemFree(Path); end; Item := nil; end; Result := True; end;
。
var Folders: TStringList; begin Folders := TStringList.Create; try if GetLibraryFileSystemFolders('MyLibrary',Folders) then begin //... end; finally Folders.Free; end; end;
我刚刚在marco Cantu的Mastering Delphi书籍的源代码库中找到了一个Delphi 2010的例子,它显示了一个在库中获取位置的方法。
到版本库的链接在这里: http : //code.marcocantu.com/p/marcodelphibooks/source/tree/HEAD/
在chapter 05 (Win7Libraries) , chapter 05 (Win7Libraries)就是示例源码。
该演示中使用的方法基本上是已经提到的Windows API的使用,演示确认库文件确实是XML格式。
此外,我发现以下信息非常有用:
SHAddFolderPathToLibrary – 将文件夹添加到库。
SHCreateLibrary IShellLibrary – 创建一个对象。
SHLoadLibraryFromItem – 创建并加载IShellLibrary以从指定的库定义文件中对象。
SHLoadLibraryFromKNownFolder – 为指定的KNowNFOLDERID创建并加载IShellLibrary对象。
SHLoadLibraryFromParsingName – 创建并加载指定路径的IShellLibrary对象。
SHRemoveFolderPathFromLibrary – 从库中删除文件夹。
SHResolveFolderPathInLibrary – 尝试解析已移动或重命名的库文件夹的目标位置。
SHResolveLibrary – 尝试查找库的位置。
SHSaveLibraryInFolderPath – 将IShellLibrary对象保存到磁盘。
SHShowManageLibraryUI – 显示图书馆管理对话框,使用户能够管理图书馆文件夹和默认保存位置。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。