dai*_*tzu 1 python windows registry winreg
我正在尝试使用 Windows 注册表中的 shellbag 构建一个小型应用程序。我正在尝试解码表单中的一些数据REG_BINARY,但不知道从哪里开始。如果你去:
Computer\HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\BagMRU\0
您会发现一系列值,0、1、2、3 等类型REG_BINARY,打开它们有时会显示似乎是一个文件夹的内容以及大量看似乱码的内容。
我还需要了解以下形式的键的二进制列 ('Sort'和):'Colinfo'
Computer\HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\Bags\1\Shell\{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}
我尝试在网上查看 shellbags python 程序,但老实说,我不知道它们在做什么,而且它们似乎是用 python2 编写的,所以没有骰子。
我已经编写了一个小的 python 程序来提供帮助,但它缺少获取节点槽的方法,并且我正在尝试将任何给定的文件夹名称链接到节点槽。这是我目前的程序。
from winreg import *
from codecs import decode
folder_reg_path = "Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\Shell\\Bags\\1375\\Shell"
bags_mru_path = "Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU"
def get_sniffed_folder_type(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
value = QueryValueEx(key, 'SniffedFolderType')
return '%s' % (value[0])
def get_current_nodeid(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key, 0, KEY_READ) as key:
#value = QueryValueEx(key, '0')
#return value[0].hex().decode('utf-8')
value = EnumValue(key, 2)
return decode(value[1], 'ascii', 'ignore')
# which clsid should be used? the last one in the list
def get_current_clsid(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
key_idx = 0
value = None
# keep looping until the last clsid entry is found
while 1:
try:
temp = EnumKey(key, key_idx)
key_idx += 1
value = temp
except:
break
return value
# the size of icons used by the folder
def get_folder_icon_size(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
value = QueryValueEx(key, 'IconSize')
return '%d pixels' % (value[0])
# the folder view. details, list, tiles e.t.c
def get_logical_view_mode(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
value = QueryValueEx(key, 'LogicalViewMode')
logical_view_mode_dict = {1 : "Details view", 2 : "Tiles view", 3 : "Icons view", 4 : "List view", 5 : "Content view"}
return logical_view_mode_dict[value[0]]
# folder view is based on view mode. so you can have a logical view mode of icons view with a view mode of large icons for instance
def get_folder_view_mode(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
value = QueryValueEx(key, 'Mode')
# view_mode 7 is only available on xp. A dead os
view_mode_dict = {1 : "Medium icons", 2 : "Small icons", 3 : "List", 4 : "Details", 5 : "Thumbnail icons", 6 : "Large icons", 8 : "Content"}
return view_mode_dict[value[0]]
# how is the folder being sorted
def get_folder_sort_by(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
value = QueryValueEx(key, 'Sort')
folder_sort_dict = {"0E000000" : "Date Modified", "10000000" : "Date Accessed", "0F000000" : "Date Created", "0B000000" : "Type", "0C000000" : "Size", "0A000000" : "Name", "02000000" : "Title", "05000000" : "Tags"}
# we get a byte value which we will hexify and get a rather long string
# similar to : 000000000000000000000000000000000100000030f125b7ef471a10a5f102608c9eebac0c000000ffffffff
reg_value = value[0].hex()
# now for this string, we need to get the last 16 strings. then we now get the first 8 out of it. so we will have
folder_sort_dict_key = (reg_value[-16:][:8]).upper()
#return folder_sort_dict[folder_sort_dict_key]
print (reg_value)
return folder_sort_dict_key
# in what order is the folder being sorted. ascending or descending???
def get_folder_sort_by_order(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
value = QueryValueEx(key, 'Sort')
folder_sort_dict = {"01000000" : "Ascending", "FFFFFFFF" : "Descending"}
# we get a byte value which we will hexify and get a rather long string
# similar to : 000000000000000000000000000000000100000030f125b7ef471a10a5f102608c9eebac0c000000ffffffff
reg_value = value[0].hex()
# now for this string, we need to get the last 16 strings. then we now get the last 8 out of it. so we will have
folder_sort_dict_key = (reg_value[-16:][-8:]).upper()
return folder_sort_dict[folder_sort_dict_key]
# How is the folder being grouped
def get_folder_group_by(reg_key):
with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
value = QueryValueEx(key, 'GroupByKey:PID')
folder_group_dict = {'10' : "Name", '14' : "Date Modified", '4*' : "Type", '12' : "Size", '15' : "Date Created", '5' : "Tags", '2' : "Title", '16' : "Date Accessed", '0' : "No Group Applied"}
return folder_group_dict[str(value[0])]
# Registry is of the form:
# HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\1375\Shell\{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}
# where 1375 is a value called the NodeList, and {5C4F28B5-F869-4E84-8E60-F11DB97C5CC7} is a value under Shell chosen based on creation date
print ( 'The suggested folder type is %s' % get_sniffed_folder_type(folder_reg_path) )
# lets start by getting a value similar to {5C4F28B5-F869-4E84-8E60-F11DB97C5CC7} by finding the last child of folder_reg_path
folder_reg_path = folder_reg_path + '\\' + get_current_clsid(folder_reg_path)
print ( get_current_nodeid(bags_mru_path) )
print ( 'The registry path is %s' % (folder_reg_path) )
icon_size = get_folder_icon_size(folder_reg_path)
logical_view_mode = get_logical_view_mode(folder_reg_path)
view_mode = get_folder_view_mode(folder_reg_path)
sorted_by = get_folder_sort_by(folder_reg_path)
sorted_by_order = get_folder_sort_by_order(folder_reg_path)
folder_group_by = get_folder_group_by(folder_reg_path)
print ('The folder icon size is %s' % icon_size)
print('The folder logical view mode is %s' % logical_view_mode)
print('The folder view mode is %s' % view_mode)
print('The folder is sorted by %s in %s order' % (sorted_by, sorted_by_order))
print('The folder is grouped by: %s' % folder_group_by)
Run Code Online (Sandbox Code Playgroud)
Kei*_*ler 11
当在新创建的帐户中第一次打开资源管理器时,文件夹视图将由注册表中定义的相应FolderType的TopView设置决定:
\nHKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FolderTypes\nRun Code Online (Sandbox Code Playgroud)\n大多数用户都熟悉其中的一部分,即文件夹属性对话框的“自定义”选项卡上提供的模板:
\n联系人和下载模板也存在,但它们仅使用以下路径分配到各自的系统文件夹:
\nHKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\nRun Code Online (Sandbox Code Playgroud)\n可以使用以下PowerShell代码生成文件夹类型ID 及其各自名称的完整列表:
\ngp (gci HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FolderTypes).PSPath |\n select PSChildName, CanonicalName | sort CanonicalName |\nOut-GridView # or Out-File FTList.txt # or Set-Clipboard\n\n\nPSChildName CanonicalName\n----------- -------------\n{db2a5d8f-06e6-4007-aba6-af877d526ea6} AccountPictures\n{91475fe5-586b-4eba-8d75-d17434b8cdf6} Communications\n{503a4e73-1734-441a-8eab-01b3f3861156} Communications.SearchResults\n{80213e82-bcfd-4c4f-8817-bb27601267a9} CompressedFolder\n...\n{5fa96407-7e77-483c-ac93-691d05850de8} Videos\n{631958a6-ad0f-4035-a745-28ac066dc6ed} Videos.Library\n{292108be-88ab-4f33-9a26-7748e62e37ad} Videos.LibraryFolder\n{ea25fbd7-3bf7-409e-b97f-3352240903f4} Videos.SearchResults\nRun Code Online (Sandbox Code Playgroud)\n在资源管理器中查看文件夹后,Windows会将该单个文件夹的查看设置保存在两个注册表项下。如果文件夹是本地的,则键为:
\nHKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\nRun Code Online (Sandbox Code Playgroud)\n- - 和 - -
\nHKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\nRun Code Online (Sandbox Code Playgroud)\n网络位置和一个特殊的包,桌面布局,都在这里:
\nHKCU\\Software\\Microsoft\\Windows\\Shell\\BagMRU\nRun Code Online (Sandbox Code Playgroud)\n- - 和 - -
\nHKCU\\Software\\Microsoft\\Windows\\Shell\\Bags\nRun Code Online (Sandbox Code Playgroud)\nBags下的每个编号子项对应一个文件夹。每个都可以保存三个单独的视图状态:Shell(资源管理器)、ComDLg(例如记事本)和ComDlgLegacy(例如Reg Export)。它们每个都可以有一个以 GUID 命名的子项,该子项对应于应用于文件夹的FolderType的 ID 。该子键包含视图的各种属性:
\nPS C:\\> $Bags = \'HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\'\nPS C:\\> (gci $bags -Recurse | ? PSChildName -like "{*}" | select -first 2)[1] | ft -AutoSize\n\n Hive: HKEY_CURRENT_USER\\Software\\Classes\\Local\n Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\\1\\Shell\n\nName Property\n---- --------\n{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7} Rev : 67\n FFlags : 1090519041\n Vid : {137E7700-3573-11CF-AE69-08002B2E1262}\n Mode : 4\n LogicalViewMode : 1\n IconSize : 16\n Sort : {0, 0, 0, 0...}\n ColInfo : {0, 0, 0, 0...}\n GroupView : 0\n GroupByKey:FMTID : {00000000-0000-0000-0000-000000000000}\n GroupByKey:PID : 0\n GroupByDirection : 1\nRun Code Online (Sandbox Code Playgroud)\nValue Name Description\n---------- -----------\nRev \xe2\x80\xa2 Seems to be a counter that increments when BagMRU/Bags are deleted or Reset\n Folders is executed from the Folder Options dialog\nFflags \xe2\x80\xa2 The FolderFlags that apply to the folder view.\nGroupView A DWORD flag determining whether or not the view is grouped:\n \xe2\x80\xa2 0x00000000 = No grouping\n \xe2\x80\xa2 0xffffffff = View grouped by column specified by the GroupByKey pair.\nGroupByDirection A DWORD flag determing sort direction of group names:\n \xe2\x80\xa2 0x00000001 = Ascending\n \xe2\x80\xa2 0xffffffff = Descending\nRun Code Online (Sandbox Code Playgroud)\nName LVM Mode Vid IconSize\n---- --- ---- --- --------\nDetails 1 4 {137E7700-3573-11CF-AE69-08002B2E1262} 16\nTiles 2 8 {65F125E5-7BE1-4810-BA9D-D271C8432CE3} 48\nSmIcons 3 1 {089000C0-3573-11CF-AE69-08002B2E1262} 16..31\nIcons(M-XL) 3 1 {0057D0E0-3573-11CF-AE69-08002B2E1262} 33..256\nList 4 3 {0E1FA5E0-3573-11CF-AE69-08002B2E1262} 16\nContent 5 8 {30C2C434-0889-4C8D-985D-A9F71830B0A9} 32\nRun Code Online (Sandbox Code Playgroud)\n指定列的所有值:
\n通过将相应的属性指定为FMTID-PID对来执行此操作。确定给定属性对的最简单方法是对该属性上的文件夹进行分组,关闭它,然后检查相应Bag中生成的GroupByKey:FMTID和GroupByKey:PID值。这里\xe2\x80\x99是我到目前为止得到的\xe2\x80\x99:
\nFMTID PID Name\n----- --- ----\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x010f Camera Maker\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x0110 Camera Model\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x829a Exposure Time\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x8822 Expsure Program\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x9003 Date Taken\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x9204 Expsure Bias\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x9209 Flash Mode\n{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 0x920a Focal Length\n{28636AA6-953D-11D2-B5D6-00C04FD918D0} 0x05 Computer\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x02 Contributing Artists\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x04 Album\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x05 Year\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x07 #\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x0b Genre\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x0d Album Artist\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x23 Beats-per-minute\n{56A3372E-CE9C-11D2-9F0E-006097C686F6} 0x24 Conductor\n{5CBF2787-48CF-4208-B90E-EE5E5D420294} 0x15 Description\n{5CBF2787-48CF-4208-B90E-EE5E5D420294} 0x17 DateVisited\n{6444048F-4C8B-11D1-8B70-080036B11A03} 0x0d Dimensions\n{64440491-4C8B-11D1-8B70-080036B11A03} 0x03 Frame Width\n{64440491-4C8B-11D1-8B70-080036B11A03} 0x04 Frame Height\n{64440491-4C8B-11D1-8B70-080036B11A03} 0x06 Frame Rate\n{64440492-4C8B-11D1-8B70-080036B11A03} 0x04 Bit Rate\n{64440492-4C8B-11D1-8B70-080036B11A03} 0x0b Copyright\n{64440492-4C8B-11D1-8B70-080036B11A03} 0x13 Composer\n{9B174B34-40FF-11D2-A27E-00C04FC30871} 0x04 Owner\n{A0E74609-B84D-4F49-B860-462BD9971F98} 0x64 35 mm Focal Length\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x02 FolderName\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x04 Type\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x0a Name\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x0c Size\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x0d Attributes\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x0e DateModified\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x0f DateCreated\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x10 DateAccessed\n{D35F743A-EB2E-47F2-A286-844132CB1427} 0x64 EXIF Version\n{D5CDD502-2E9C-101B-9397-08002B2CF9AE} 0x02 Categories\n{DABD30ED-0043-4789-A7F8-D013A4736622} 0x64 Folder\n{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 0x06 FolderPath\n{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 0x02 Title\n{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 0x04 Authors\n{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 0x05 Tags\n{F7DB74B4-4287-4103-AFBA-F1B13DCD75CF} 0x64 Date\nRun Code Online (Sandbox Code Playgroud)\n在ColInfo & Sort中,该对采用二进制格式,即PROPERTYKEY结构:
\ntypedef struct {\n GUID fmtid;\n DWORD pid;\n} PROPERTYKEY;\nRun Code Online (Sandbox Code Playgroud)\n将 CLSID 样式的 GUID 转换为其二进制等效项时需要进行一些字节混排。以名称为例:
\n{B725F130-47EF-101A-A5F1-02608C9EEBAC} 0x0a
变成
\n[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac][0a 00 00 00] (在注册表中连续,为清晰起见分组)
我使用此PowerShell代码片段将二进制 GUID/CLSID 转换为其更熟悉的文本表示形式:
\n$Bags = \'HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\'\n$Sample = gci $rp.Bags -Recurse | ? Property -Contains Sort | Select -First 5 | gp\n$Sample | ForEach{ \'{{{0}}}\' -f [GUID][Byte[]]$_.Sort[20..35] }\n\nOutput:\n{b725f130-47ef-101a-a5f1-02608c9eebac}\n{b725f130-47ef-101a-a5f1-02608c9eebac}\n{f29f85e0-4ff9-1068-ab91-08002b27b3d9}\n{83914d1a-c270-48bf-b00d-1c4e451b0150}\n{f7db74b4-4287-4103-afba-f1b13dcd75cf}\nRun Code Online (Sandbox Code Playgroud)\nPROPERTYKEY结构用于构建定义ColInfo和Sort 的结构。如果我们将文件夹设置为具有单列Name,并检查生成的ColInfo值,我们会看到以下字节:
\n00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \\ Constant\nfd df df fd 10 00 00 00 00 00 00 00 00 00 00 00 / Header\n[01 00 00 00] \xe2\x86\x90 Column Count\n[18 00 00 00] \xe2\x86\x90 Byte count per column?\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac] \xe2\x86\x90 FMTID\n[0a 00 00 00] \xe2\x86\x90 PID ] \xe2\x86\x90 PROPERTYKEY\n[da 01 00 00] \xe2\x86\x90 Width (Pixels?) ] <- PROPERTYKEY/Width pair\nRun Code Online (Sandbox Code Playgroud)\n对于添加到视图中的每一列,列计数都会增加,并添加适当的 PROPERTYKEY/Width 对:
\n[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\nfd df df fd 10 00 00 00 00 00 00 00 00 00 00 00]\n[03 00 00 00]\n[18 00 00 00]\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac]\n[0d 00 00 00]] \xe2\x86\x90 \'Attributes\'\n[53 00 00 00]]\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac]\n[0a 00 00 00]] \xe2\x86\x90 \'Name\'\n[10 01 00 00]]\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac]\n[04 00 00 00]] \xe2\x86\x90 \'Type\'\n[0a 01 00 00]]\nRun Code Online (Sandbox Code Playgroud)\n排序使用SORTCOLUMN结构:
\ntypedef struct SORTCOLUMN {\nPROPERTYKEY propkey;\nSORTDIRECTION direction; \n} SORTCOLUMN;\nRun Code Online (Sandbox Code Playgroud)\n排序结构包括:
\n名称,升序:
\n[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00] <- Header\n[01 00 00 00] <- SORTCOLUMN count\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac] <- FMTID\n[0a 00 00 00] <- PID ] <- PROPERTYKEY\n[01 00 00 00] <- Direction ] <- SORTCOLUMN\nRun Code Online (Sandbox Code Playgroud)\n和名称,降序:
\n[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]\n[01 00 00 00]\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac]\n[0a 00 00 00]]\n[ff ff ff ff] <- Direction ] <- SORTCOLUMN\nRun Code Online (Sandbox Code Playgroud)\n当通过< Shift > 键并单击列标题选择二级、三级或四级属性时,相应的 SORTCOLUMN 将添加到排序结构中。
\n输入,降序,然后输入名称,升序:
\n(gp \'HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\\66\\Shell\\{7D49D726-3C21-4F05-99AA-FDC2C9474656}\\\').Sort | Format-Hex \n\n Path:\n\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\n00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................\n00000010 02 00 00 00 30 F1 25 B7 EF 47 1A 10 A5 F1 02 60 ....0\xc3\xb1%\xc2\xb7\xc3\xafG..\xc2\xa5\xc3\xb1.`\n00000020 8C 9E EB AC 04 00 00 00 FF FF FF FF 30 F1 25 B7 \xc3\xab\xc2\xac........0\xc3\xb1%\xc2\xb7\n00000030 EF 47 1A 10 A5 F1 02 60 8C 9E EB AC 0A 00 00 00 \xc3\xafG..\xc2\xa5\xc3\xb1.`\xc3\xab\xc2\xac....\n00000040 01 00 00 00 ....\n\n[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]\n[02 00 00 00] <- Two columns specified\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac]\n[04 00 00 00]] <- \'TYpe\'\n[ff ff ff ff]]\n[[[30 f1 25 b7 ef 47 1a 10 a5 f1 02 60 8c 9e eb ac]\n[0a 00 00 00]] <- \'Name\'\n[01 00 00 00]]\nRun Code Online (Sandbox Code Playgroud)\nBagMRU及其子键是树形结构索引,它将文件夹的路径与其编号的Bag ( NodeSlot ) 相关联。BagMRU及其子项镜像Shell 命名空间,BagMRU项本身对应于 root(虚拟)Desktop。BagMRU中的每个节点对应于 Shell 命名空间中的一个文件夹。文件夹由其名称空间路径引用这一事实意味着一个文件系统文件夹(例如Documents)将具有三个单独的视图:
\n检查BagMRU时,没有明显的文件夹名称;节点具有简单的整数名称,并且没有字符串值。人类可读的路径在哪里?!?!?为什么 MS 让一切变得如此困难?!?!?:D\n好吧,每个整数命名的节点在其父节点中都有一个相应的整数命名的 REG_BINARY 值。正是该值标识了其关联的子密钥。谜底的关键?这些二进制值是项目 ID (实际上是ITEMIDLIST 结构的相应ITEMID_CHILD类型)。因此,我们可以使用节点及其祖先的 ID 列表来构造 IDLIST_ABSOLUTE ,类似于完全限定路径:\n
但它仍然只是一个神秘字节数组。为了提取有意义的信息,我们求助于 Windows API,特别是SHGetNameFromIDList。根据文档:
\n\n\n“检索由 IDList 标识的项目的显示名称。”
\n
幸运的是,PowerShell可以通过Add-Type合并 API 。不幸的是,如果 PInvoke.net 的数据库中没有 C# 签名/包装器,那么发现有效的签名和包装器可能会令人沮丧。但通过研究其他签名和反复试验,我找到了一个,然后定义了一个包装函数:
\nAdd-Type -TypeDefinition @\'\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\npublic class API\n{\n [DllImport("shell32.dll", SetLastError=true, CharSet=CharSet.Unicode)]\n [return: MarshalAs(UnmanagedType.Error)]\n static extern int SHGetNameFromIDList(IntPtr pidl, uint sigdnName, out StringBuilder ppszName);\n\n public static string GetFolderName(Byte[] IDL) {\n GCHandle pinnedArray = GCHandle.Alloc(IDL, GCHandleType.Pinned);\n IntPtr PIDL = pinnedArray.AddrOfPinnedObject();\n StringBuilder name = new StringBuilder(2048);\n int result = SHGetNameFromIDList(PIDL, 0x0, out name);\n pinnedArray.Free();\n return name.ToString();\n }\n}\n\'@\n\n# Invocation:\n# $FolderName = [API]::GetFolderName($IDL)\n# Where $IDL is a [Byte[]] ItemIDList\nRun Code Online (Sandbox Code Playgroud)\n这足以解码桌面上根文件夹的 IDL :
\n$BagMRU = \'HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\'\n((Get-ItemProperty $Bagmru).PsObject.Properties).Where{$_.Name -match \'\\d+\'} |\nForEach -Process{\n [PSCustomObject]@{\n \'KeyName\' = $_.Name\n \'Folder\' = [API]::GetFolderName($_.Value)\n}}\nRun Code Online (Sandbox Code Playgroud)\n输出:(具体结果会有所不同:D)
\nKeyName Folder\n------- ------\n0 Quick access\n1 This PC\n2 Keith Miller\n3 Libraries\n4 Control Panel\n5 Sandbox\n6 Search Results in Sandbox\n7 Search Results in Sandbox\n8 Search Results in Desktop\n9 Search Results in Desktop\n10 Keith Miller\n11 ::{1434B6DB-0A53-454A-B1C7-69A56B454078}\n12 Search Results in System32\n13 Search Results in System32\n14 Search Results in Keith Miller\n15 Search Results in Altenate Folder Tree\n16 Search Results in Altenate Folder Tree\n17 H:\\\n18 I:\\\n19 Reg Transfers\n20 Quick access\n21 Quick access\n22 This PC\n23 Recent folders\n24 OneDrive - Personal\n25 This Device\n26 Recent files\nRun Code Online (Sandbox Code Playgroud)\n漂亮吧?别担心,那些看似重复的“搜索结果...”行实际上并不是重复的——它们是一起工作的。由于.SearchResults和.Library FolderTypes具有多个可用的TopView(通过 进行选择ArrangeBy >),因此一个包指定最后使用的TopView(因此在重新显示文件夹时使用),而其他包则保存特定TopView. 稍后会详细介绍——我们还没有完成路径。
要构造子文件夹的 IDL,请从“父”字节数组中去除两个终止空字节,然后附加“子”字节数组。如果子文件夹有子文件夹,请使用新构建的 IDL 重复该过程。
\nTypeDefinition通过包含SIGDN常量的缩写枚举的充实内容,可以使用递归函数来获取BagMRU键的快照,并将每个节点与其在 Shell 命名空间中的相应路径以及文件系统路径相关联(如果适用)以及虚拟位置的解析路径:
Add-Type -TypeDefinition @\'\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\n[FlagsAttribute]\npublic enum SIGDN : uint {\n NORMALDISPLAY = 0x00000000,\n DESKTOPABSOLUTEPARSING = 0x80028000,\n FILESYSPATH = 0x80058000,\n URL = 0x80068000,\n};\n\npublic class API\n{\n [DllImport("shell32.dll", SetLastError=true, CharSet=CharSet.Unicode)]\n [return: MarshalAs(UnmanagedType.Error)]\n static extern int SHGetNameFromIDList(IntPtr pidl, SIGDN sigdnName, out StringBuilder ppszName);\n\n public static string Get_FolderName(Byte[] IDL , SIGDN sigdnName) {\n GCHandle pinnedArray = GCHandle.Alloc(IDL, GCHandleType.Pinned);\n IntPtr PIDL = pinnedArray.AddrOfPinnedObject();\n StringBuilder name = new StringBuilder(2048);\n int result = SHGetNameFromIDList(PIDL, sigdnName, out name);\n pinnedArray.Free();\n return name.ToString();\n }\n}\n\'@\n\nFunction Get-BagMRU\n\n# Parametrs are for recursive calls only. Calling the function\n# with no parameters returns the complete collection.\n\n{\n Param(\n [PSObject[]]$Keys = ( Get-Item @(\n \'HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\',\n \'HKCU:\\Software\\Microsoft\\Windows\\Shell\\BagMRU\'\n )),\n [Byte[]]$IDL = [Byte[]]@(),\n [String]$ParentPath = $null,\n [Byte[]]$ParentIDL = [Byte[]]@()\n )\n ForEach ($key in $Keys)\n {\n If ( $IDL )\n {\n ### Build nameSpacePath ###\n\n [Byte[]]$absIDL = [Byte[]]($ParentIDL + $IDL)\n\n Try { $nameSpacePath = $ParentPath + [API]::Get_FolderName( $absIDL ,
| 归档时间: |
|
| 查看次数: |
3575 次 |
| 最近记录: |