草庐IT

python - 有没有办法获取shell :appsfolder on Windows 10?的完整路径

coder 2024-06-11 原文

我希望能够在 python 脚本中列出 shell:apps 文件夹中的文件,但需要使用 os.list 执行此操作的完整路径。有没有办法获得完整路径(或者有人知道)?或者,我可以通过其他方式列出这些文件吗?我可以“cd”到它吗?

脚本背后的想法是自动创建所有 Windows 应用商店应用程序的快捷方式(我认为是通过它们具有“长名称”属性这一事实来识别的)并将这些快捷方式提取到程序 Launchy 可以检测到它们的文件夹中.我不喜欢每次下载或删除应用程序时都必须手动完成创建快捷方式(并将其重命名以删除“- 快捷方式)的过程,所以我想我可以自动化它。

最佳答案

在为“应用程序”虚拟文件夹(即 FOLDERID_AppsFolder)中列出的 Windows 应用商店应用程序创建快捷方式方面,这里有一个函数有望满足您的需求。为了对 Windows 应用商店应用进行分类,它会在应用程序用户模型 ID 中查找感叹号,因为 AUMID 的形式应该是“PackageFamily!ApplicationID”(请参阅​​ Automate Launching UWP Apps)。为了可靠性,它会交叉检查每个包系列与用户注册的包系列。

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)

关于python - 有没有办法获取shell :appsfolder on Windows 10?的完整路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43618668/

有关python - 有没有办法获取shell :appsfolder on Windows 10?的完整路径的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  3. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  4. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  5. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  6. 没有类的 Ruby 方法? - 2

    大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow

  7. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  8. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  9. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  10. ruby - 没有类方法获取 Ruby 类名 - 2

    如何在Ruby中获取BasicObject实例的类名?例如,假设我有这个:classMyObjectSystem我怎样才能使这段代码成功?编辑:我发现Object的实例方法class被定义为returnrb_class_real(CLASS_OF(obj));。有什么方法可以从Ruby中使用它? 最佳答案 我花了一些时间研究irb并想出了这个:classBasicObjectdefclassklass=class这将为任何从BasicObject继承的对象提供一个#class您可以调用的方法。编辑评论中要求的进一步解释:假设你有对象

随机推荐