如何读/写Windows 7库位置? [英] How to Read/Write Windows 7 Library Locations?

查看:194
本文介绍了如何读/写Windows 7库位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介

Intro

在Windows 7中,您有一些名为Libraries的文档,图片和音乐等特殊文件夹。

In Windows 7 you have some special folders for documents, pictures and music etc called Libraries.

如果您不知道它们,基本上每个Library文件夹都可以包含基本上每个库的快捷方式的位置(路径)。

If you are not aware of them, basically each Library folder can contain Locations (paths) which are basically shortcuts for each Library.

某些示例

文档(图书馆)


  • E:\Personal\Documents (位置)

  • F :\Backups\Documents (位置)

  • E:\Personal\Documents (Location)
  • F:\Backups\Documents (Location)

音乐(图书馆)


  • E:\Media\Music\Albums (位置)

  • E:\Media\Music\Singles (位置)

  • E:\Media\Music\Albums (Location)
  • E:\Media\Music\Singles (Location)

图片(图书馆)


  • E:\Media\Photos (位置)

  • E:\Media\Photos (Location)

当您从W单击任何这些库文件夹indows Explorer或开始菜单,Windows资源管理器将显示该库中定义的位置。

When you click any of these Library folders from Windows Explorer or Start menu, Windows Explorer will show with the Locations defined inside that Library.

任务

我需要做的是阅读每个库类型的位置,并能够使用我自己的位置写回(更新)库。我发现库存储在用户AppData文件夹中,如下所示:

What I need to be able to do is read the Locations for each Library type, and be able to write back (update) the Library with my own Locations. I have found that the Libraries are stored in the user AppData folder like this:

C:\Users\SOMEUSER\AppData\ Roaming\Microsoft\Windows\Libraries

这些库是这种文件类型:库(.library-ms) - 如果您右键单击并选择属性,库选项卡可以查看与该库相关联的库位置。

These Libraries are this file type: Library (.library-ms) - if you right click on one and select properties, Library tab you can see the Library locations associated with that Library.

我没有看到提取这些,并将它们放在一个用于在Delphi中编辑的TStringList中。我想知道这些图书馆地点是否实际存储在Windows注册表中,所以从Google的一些研究我发现这些路径:

I don't see a way of extracting these and putting them for example into a TStringList for editing in Delphi. I wondered if these Library Locations were actually stored in the Windows Registry so with some research from Google I found these paths:


  • HKEY_CURRENT_USER\Software \Microsoft\Windows\CurrentVersion\Explorer\Shell文件夹

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

但是,我再也看不到图书馆地点的实际列表。

But again, I don't see the actual list of Library Locations.

那么,如何在Delphi中读取Library文件中的Locations列表,将它们添加到Listbox或TStringList中,编辑条目然后写入更改?刚刚能够提取图书馆的位置路径将是一个开始。

So, how can I read the list of Locations inside a Library file in Delp add them to a Listbox or TStringList, edit the entries and then write back the changes? Just been able to extract the Library Location paths would be a start.

我只是有一种感觉,这将是其中一个问题,有一个简单的答案,我不能似乎找到!

I just have a feeling this is going to be one of those questions that has a simple answer I cannot seem to find!

推荐答案

使用 SHLoadLibraryFrom ...()函数,如 SHLoadLibraryFromKnownFolder(),以获取一个 IShellLibrary 接口,那么你可以使用它的方法枚举和操纵库,例如 IShellLibrary :: GetFolders() IShellLibrary :: AddFolder() IShellLibrary :: RemoveFolder()等。

Use one of the SHLoadLibraryFrom...() functions, like SHLoadLibraryFromKnownFolder(), to get an IShellLibrary interface, then you can use its methods to enumerate and manipulate the Library, such as IShellLibrary::GetFolders(), IShellLibrary::AddFolder(), IShellLibrary::RemoveFolder(), etc.

更新:例如:

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, IShellLibrary, 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 接口,例如:

Update: SHLoadLibraryFromKnownFolder() only works for Microsoft-defined Libraries that have KNOWNFOLDERID values defined. If you want to access custom Libraries, you have to use a slightly modified approach to obtaining the IShellLibrary interface, eg:

// 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, nil, CLSCTX_INPROC_SERVER, 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, 0, 0, IShellItem, PPointer(@Item)^) then
    Exit;

  hr := Item.BindToHandler(nil, BHID_EnumItems, IEnumShellItems, Enum);
  if FAILED(hr) then
    Exit;

  Item := nil;
  while Enum.Next(1, Item, 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, IShellLibrary, 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, 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('MyLibrary', Folders) then
    begin
      //...
    end;
  finally
    Folders.Free;
  end;
end;

这篇关于如何读/写Windows 7库位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆