Python 在Windows10上有没有办法获取shell:appsfolder的完整路径?
我希望能够在python脚本中列出shell:appsfolder中的文件,但需要使用Python 在Windows10上有没有办法获取shell:appsfolder的完整路径?,python,windows,Python,Windows,我希望能够在python脚本中列出shell:appsfolder中的文件,但需要使用os.list完成此操作的完整路径。有没有办法获得完整的路径(或者有人知道它)?或者,是否有其他方法可以列出这些文件?我可以用“cd”吗 该脚本背后的思想是自动创建所有Windows应用商店应用程序的快捷方式(我认为它们具有“长名称”属性),并将这些快捷方式提取到程序启动可以检测到它们的文件夹中。我不喜欢每次下载或删除应用程序时都要手动创建快捷方式(并将其重命名以删除“-快捷方式),因此我认为应该自动执行该过程
os.list
完成此操作的完整路径。有没有办法获得完整的路径(或者有人知道它)?或者,是否有其他方法可以列出这些文件?我可以用“cd”吗
该脚本背后的思想是自动创建所有Windows应用商店应用程序的快捷方式(我认为它们具有“长名称”属性),并将这些快捷方式提取到程序启动可以检测到它们的文件夹中。我不喜欢每次下载或删除应用程序时都要手动创建快捷方式(并将其重命名以删除“-快捷方式),因此我认为应该自动执行该过程。这里有一个函数,希望它能为“应用程序”中列出的Windows应用商店应用程序创建快捷方式“虚拟文件夹(即
FOLDERID\u AppsFolder
)。要对Windows应用商店应用进行分类,它会在应用程序用户模型ID中查找感叹号,因为AUMID的格式应为“PackageFamily!ApplicationID”(请参阅)。为了可靠性,它将每个包族与用户注册的包族进行交叉检查
import os
import ctypes
import pywintypes
import pythoncom
import winerror
try:
import winreg
except ImportError:
# Python 2
import _winreg as winreg
bytes = lambda x: str(buffer(x))
from ctypes import wintypes
from win32com.shell import shell, shellcon
from win32com.propsys import propsys, pscon
# KNOWNFOLDERID
# https://msdn.microsoft.com/en-us/library/dd378457
# win32com defines most of these, except the ones added in Windows 8.
FOLDERID_AppsFolder = pywintypes.IID('{1e87508d-89c2-42f0-8a7e-645a0f50ca58}')
# win32com is missing SHGetKnownFolderIDList, so use ctypes.
_ole32 = ctypes.OleDLL('ole32')
_shell32 = ctypes.OleDLL('shell32')
_REFKNOWNFOLDERID = ctypes.c_char_p
_PPITEMIDLIST = ctypes.POINTER(ctypes.c_void_p)
_ole32.CoTaskMemFree.restype = None
_ole32.CoTaskMemFree.argtypes = (wintypes.LPVOID,)
_shell32.SHGetKnownFolderIDList.argtypes = (
_REFKNOWNFOLDERID, # rfid
wintypes.DWORD, # dwFlags
wintypes.HANDLE, # hToken
_PPITEMIDLIST) # ppidl
def get_known_folder_id_list(folder_id, htoken=None):
if isinstance(folder_id, pywintypes.IIDType):
folder_id = bytes(folder_id)
pidl = ctypes.c_void_p()
try:
_shell32.SHGetKnownFolderIDList(folder_id, 0, htoken,
ctypes.byref(pidl))
return shell.AddressAsPIDL(pidl.value)
except WindowsError as e:
if e.winerror & 0x80070000 == 0x80070000:
# It's a WinAPI error, so re-raise it, letting Python
# raise a specific exception such as FileNotFoundError.
raise ctypes.WinError(e.winerror & 0x0000FFFF)
raise
finally:
if pidl:
_ole32.CoTaskMemFree(pidl)
def enum_known_folder(folder_id, htoken=None):
id_list = get_known_folder_id_list(folder_id, htoken)
folder_shell_item = shell.SHCreateShellItem(None, None, id_list)
items_enum = folder_shell_item.BindToHandler(None,
shell.BHID_EnumItems, shell.IID_IEnumShellItems)
for item in items_enum:
yield item
def list_known_folder(folder_id, htoken=None):
result = []
for item in enum_known_folder(folder_id, htoken):
result.append(item.GetDisplayName(shellcon.SIGDN_NORMALDISPLAY))
result.sort(key=lambda x: x.upper())
return result
def create_shortcut(shell_item, shortcut_path):
id_list = shell.SHGetIDListFromObject(shell_item)
shortcut = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None,
pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink)
shortcut.SetIDList(id_list)
persist = shortcut.QueryInterface(pythoncom.IID_IPersistFile)
persist.Save(shortcut_path, 0)
def get_package_families():
families = set()
subkey = (r'Software\Classes\Local Settings\Software\Microsoft'
r'\Windows\CurrentVersion\AppModel\Repository\Families')
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, subkey) as hkey:
index = 0
while True:
try:
families.add(winreg.EnumKey(hkey, index))
except OSError as e:
if e.winerror != winerror.ERROR_NO_MORE_ITEMS:
raise
break
index += 1
return families
def update_app_shortcuts(target_dir):
package_families = get_package_families()
for item in enum_known_folder(FOLDERID_AppsFolder):
try:
property_store = item.BindToHandler(None,
shell.BHID_PropertyStore, propsys.IID_IPropertyStore)
app_user_model_id = property_store.GetValue(
pscon.PKEY_AppUserModel_ID).ToString()
except pywintypes.error:
continue
# AUID template: Packagefamily!ApplicationID
if '!' not in app_user_model_id:
continue
package_family, app_id = app_user_model_id.rsplit('!', 1)
if package_family not in package_families:
continue
name = item.GetDisplayName(shellcon.SIGDN_NORMALDISPLAY)
shortcut_path = os.path.join(target_dir, '%s.lnk' % name)
create_shortcut(item, shortcut_path)
print('{}: {}'.format(name, app_user_model_id))
示例
if __name__ == '__main__':
desktop = shell.SHGetFolderPath(0, shellcon.CSIDL_DESKTOP, 0, 0)
target_dir = os.path.join(desktop, 'Windows Store Apps')
if not os.path.exists(target_dir):
os.mkdir(target_dir)
update_app_shortcuts(target_dir)
恐怕appfolder不是一个真正的文件夹。您是否考虑过这样一种可能性,即
shell:appsfolder
是一个虚拟文件夹,其中包含多个文件系统文件夹的内容?换句话说:你所要求的并不存在。现在,你为什么不去问你的问题,而不是你提出的解决方案呢?@IInspectable好吧,如果你读了第二段,你就可以推断出我所问的关于堆栈溢出的问题了。关于堆栈溢出的问题并不是用来推断出问题是什么的。他们应该询问这个问题(包括标题)。看。@IInspectable是个坏词,你可以直接读第二段,知道问题是关于什么的。其他人管理了它,并提供了一个有效的解决方案,所以我相信你可以。这是完美的,谢谢!有点想自己写,但不用担心;)注意到一个问题,以这种方式创建的快捷方式没有应用程序图标。你知道用他们各自的图标创建它们的方法吗?@AdamShort,他们在你的案例中有什么图标?对我来说,他们确实有应用程序图标。对不起,忘记回复了。不幸的是,它们根本没有图标。作为记录,这在Windows 10.0.15063中对我来说很好。