如何读/写Windows 7库位置? [英] How to Read/Write Windows 7 Library Locations?
问题描述
简介
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屋!