0

私は python2.7 と py2exe を使用して、python スクリプトから dll を作成しています。

DLL を正常に作成し、アイコン オーバーレイ ステータスのエントリを登録してから、タスク マネージャーを使用して Windows エクスプローラー プロセスを再起動しました。

私のエントリがレジストリにあるかどうかを確認し、はい、そこにありました.

しかし、特定のフォルダーの場所の python テスト アプリ スクリプトを使用してステータスを設定すると、.

選択したパス内のすべてのファイルとフォルダーがオーバーレイ アイコンでオーバーレイされるはずです。

いいえ、アイコンのオーバーレイはまったく発生していません。

しかし、登録エントリのPythonスクリプトを使用して(DLLを作成せずに)テストし、テストアプリスクリプトを使用してアイコンオーバーレイを設定する場合。

はい、完全に機能しています。

私のDLLで試してみると、なぜそれが起こらないのか混乱していますか???

以下は、ステータスエントリを登録するための私のpythonスクリプトです

import os
import win32traceutil
import pythoncom
import winerror
from win32com.shell import shell, shellcon
from multiprocessing.connection import Client

REG_PATH = r'Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers'
REG_KEY  = "IconOverlayTest"

class IconOverlay:
    _reg_desc_       = 'Icon Overlay COM Server'
    _public_methods_ = ['GetOverlayInfo', 'GetPriority','IsMemberOf']
    _com_interfaces_ = [shell.IID_IShellIconOverlayIdentifier, pythoncom.IID_IDispatch]
    def __init__(self, *_args, **_kwargs):
        self._icon = None
        self._icon_id = None
        raise NotImplementedError
    def GetOverlayInfo(self):
        return self._icon, 0, shellcon.ISIOI_ICONFILE
    def GetPriority(self):
        return 0
    def IsMemberOf(self, path, _attrs):
        if is_member(path, self._icon_id):
            return winerror.S_OK
        return winerror.E_FAIL

class IconOverlay_test(IconOverlay):
    _reg_progid_     = 'a.TestServer1'
    _reg_clsid_      = '{8B19F050-8354-11E1-A0FE-5C260A5D15E4}'
    def __init__(self):
        self._icon = "C:\\Users\\Administrator\\mat\\icon_overlay\\icons\\1.ico"
        self._icon_id = 101 

classes =   [IconOverlay_test,]

def is_member(path, icon_id):
    try:
        conn = None
        conn = Client("\\\\.\\pipe\\test.listener", "AF_PIPE")
        conn.send(path)
        if conn.poll(3):
            reply   =   conn.recv()
            return reply == icon_id
    except Exception:
        pass
    finally:
        conn and conn.close()
    return False

def DllRegisterServer():
    print("Registering %s ......."%IconOverlay._reg_desc_)
    import winreg
    #winreg = _winreg
    for view in [winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_32KEY]:
        for cls in classes:
            with winreg.CreateKeyEx(winreg.HKEY_LOCAL_MACHINE, r"%s\%s" %
                    (REG_PATH, cls._reg_progid_), 0,
                    winreg.KEY_ALL_ACCESS|view) as hkey:
                print("    %s"%cls)
                winreg.SetValueEx(hkey, None, 0, winreg.REG_SZ, cls._reg_clsid_)
    print("Registration complete: %s" % IconOverlay._reg_desc_)

def DllUnregisterServer():
    print("Unregistering %s ......."%IconOverlay._reg_desc_)
    import winreg
    #winreg = _winreg
    for view in [winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_32KEY]:
        for cls in classes:
            try:
                _key = winreg.DeleteKeyEx(winreg.HKEY_LOCAL_MACHINE, r"%s\%s"
                        % (REG_PATH, cls._reg_progid_),
                        winreg.KEY_ALL_ACCESS|view)
            except WindowsError as err:
                if err.errno != 2:
                    raise
    print("Unregistration complete: %s" % IconOverlay._reg_desc_)

if __name__ == '__main__':
    from win32com.server import register
    register.UseCommandLine(*classes,
                            finalize_register = DllRegisterServer,
                            finalize_unregister = DllUnregisterServer)
4

1 に答える 1

0

これは正しく機能するのに本当に苦痛です、頑張ってください!

Windowsでは10種類のアイコンしか登録できず、アルファベット順に登録された最初の10個でのみ機能すると思います。すでに10件登録していますか?ドロップボックス、tortoise-svnなどがインストールされている場合、各イメージがエントリとしてカウントされるため、10を超えるのは非常に簡単です。その場合は、名前の前にアンダースコアまたは0を付けて、優先順位が付けられるようにしてください。ただし、別のアイコンが失われることを意味します。これを回避する方法はないと思います。

また、ウィンドウがアイコンのステータスを更新することを知らない場合もあります。どのバージョンのWindowsを実行していますか?あるものは他のものより悪いです。XPはこれがあまり得意ではないことを覚えているようです。更新するにはいくつかのトリックがありますが、Windows APIを使用してウィンドウを更新できますが、見た目はひどく、エクスプローラー全体が点滅します。私が見つけたより良い方法は、ファイルの属性を変更することです。これは私が使用したトリックです:

import stat,os

file_att= os.stat(path)[0]
if file_att & stat.S_IWRITE:
    os.chmod(path,stat.S_IREAD)
    os.chmod(path,stat.S_IWRITE)
else:
    os.chmod(path,stat.S_IWRITE)
    os.chmod(path,stat.S_IREAD)
于 2012-11-16T17:00:59.650 に答える