zoukankan      html  css  js  c++  java
  • Windows Shell编程实现重叠图标OverlayIcon

    转载:https://www.codeproject.com/Articles/7484/How-to-overlay-an-icon-over-existing-shell-objects

    转载:https://blog.csdn.net/u012741077/article/details/50641518

    系统默认的:                                         贴上图标后:

                              

    第一步:新建一个ATL项目,输入工程名:TxtInfo,具体如下图:

    第二步:点击next

    第三步:应用类型选择动态库链接(DLL),同时勾选 允许合并代理/存根代码和支持MFC,最后点击Finish。

    第四步:新建一个ATL简单对象(英文版的VS为ATLSimple Object)

     

    单击 Add,在第二页面中, 在Short Name编辑框中输入TxtShlExt,点击 Finish.

    第五步:开始我们需要添加IShellIconOverlayIdentifier到CTxtShlExt实现的接口列表中.打开 TxtShlExt.h, 并添加如下代码:

    复制代码
    class ATL_NO_VTABLE CTxtShlExt :
        public CComObjectRootEx<CComSingleThreadModel>,
        public CComCoClass<CTxtShlExt, &CLSID_TxtShlExt>,
        public IDispatchImpl<ITxtShlExt, &IID_ITxtShlExt, &LIBID_IconOverlayLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
        public IShellIconOverlayIdentifier//添加实现接口
    {
    public:
        CTxtShlExt()
        {
        }
    
    DECLARE_REGISTRY_RESOURCEID(IDR_TXTSHLEXT)
    
    
    BEGIN_COM_MAP(CTxtShlExt)
        COM_INTERFACE_ENTRY(ITxtShlExt)
        COM_INTERFACE_ENTRY(IDispatch)
        COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)//添加接口入口
    END_COM_MAP()
    
    
    
        DECLARE_PROTECT_FINAL_CONSTRUCT()
    
        HRESULT FinalConstruct()
        {
            return S_OK;
        }
    
        void FinalRelease()
        {
        }
    
    public:
        //实现接口的三个函数
        STDMETHOD(GetPriority(THIS_ _Out_ int * pIPriority));
        STDMETHOD(IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib));
        STDMETHOD(GetOverlayInfo(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile, int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags));
    
    
    };
    
    OBJECT_ENTRY_AUTO(__uuidof(TxtShlExt), CTxtShlExt)
    复制代码

    TxtShlExt.cpp

    复制代码
    //pwszPath 为当前文件的全路径
    STDMETHODIMP CTxtShlExt::IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib)
    {
        HRESULT hRef = S_FALSE;
    
        wchar_t* fileClass = _wcsdup(wcsrchr(pwszPath, '.'));
        if (fileClass != NULL)
        {
            if (_wcsicmp(fileClass, L".txt") == 0)
            {//判断是否是txt后缀的文件
                hRef = S_OK;
            }
        }
    
        free(fileClass);
        //如果是符合要求的文件,就返回S_OK
        return hRef;
    }
    
    //pwszIconFile 用于设置图标文件的路径,路径长度不能超过cchMax个字符。
    //pIndex 用于设置图标覆盖的先后顺序
    STDMETHODIMP CTxtShlExt::GetOverlayInfo(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile, int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags)
    {
        WCHAR *buff = new WCHAR[cchMax];
        //获取当前程序的路径,而不是调用该程序的程序的路径,因为调用该程序的是资源管理器(explorer.exe),直接过去路径的话,获取的是资源管理器的路径。
        GetModuleFileNameW(_AtlBaseModule.GetModuleInstance(), buff, cchMax);
    
        WCHAR *nChar = wcsrchr(buff, L'\');
        if (nChar != NULL)
        {//写入当前程序路径下的图标的名字
            wcscpy_s(nChar, cchMax - wcslen(buff), L"\star.ico");
            wcscpy_s(pwszIconFile, cchMax, buff);
        }
    
        //设置顺序
        *pIndex = 0;
    
        //标识所修改过的数据pwszIconFile 与 pIndex
        *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
    
        free(buff);
        //完成返回S_OK
        return S_OK;
    }
    
    STDMETHODIMP CTxtShlExt::GetPriority(THIS_ _Out_ int * pIPriority)
    {
        *pIPriority = 0;
        return S_OK;
    }
    复制代码

    第六步:注册COM接口

    方式一:HKLM内容加入TxtShlExt.rgs中

    编辑TxtShlExt.rgs文件

    方式二:HKLM内容加入IconOverlay.rgs中

    编辑IconOverlay.rgs

     

    这段代码的意思就是将这个程序注册到资源管理器下的注册表项中。

    需要注意的是需要区分系统是X86/X64,如果是X64的系统,请生成X64的程序,要不然不起作用的。

     然后将程序中标明的图标的名字“star.ico”的图标与生成的程序放在一个目录。

    用命令行注册COM :regsvr32 dll的绝对路径

    注:必须以管理员运行cmd

    卸载COM: regsvr32 /u dll的绝对路径

     

    程序虽然注册成功了,但是还没有真正被使用,需要重启资源管理器,可以手动重启下。或在控制台下输入以下重启命令。

    taskkill /f /im explorer.exe & explorer

    重启后就可以看到效果了!

    出处:https://www.cnblogs.com/chechen/p/8758263.html

    =======================================================================================

    OverlayIcon 制作流程及注意项

    OverlayIcon制作流程及注意项

        为了制作类似SVN的图标覆盖特效,我确实花了一些时间。目前做到的程度是开发的DLL其Release版本可以在XP、Win7上使用。

    第一步:

        参考Howto overlay an icon over existing shell objects in 3 easy steps – CodeProject这篇文章,按步骤做。

        这一步做完后,编译会出现:    error C2787: “IShellIconOverlayIdentifier”: 没有与该对象关联的 GUID , 这样的错误

    第二步:

        在MyOverlayIcon.h文件添加

    struct _declspec (uuid("987423F4-904A-4ACF-9803-EC28B51C1993"))IShellIconOverlayIdentifier;

        //UUID替换为自己工程中的UUID,    这样编辑将不会出现错误了。

    第三步:

        检查注册表:HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers下的项是否超过了15个

        如果该键含有太多的SubKey那么也将不会显示,或者仅在资源管理器的左边的树形结构上进行显示。

    第四步:

        重启Explorer进程,然后右键“刷新”。

    taskkill /f /im explorer.exe & explorer

    第五步:

        检查工程的属性->配置属性->C/C++->预处理器->预处理器定义,里面的值要包含:_ATL_NO_UUIDOF(我不知道为什么,但是不写就真的不行)

    IShellIconOverlayIdentifier说明三个函数说明:

    Shell通过调用IShellIconOverlayIdentifier::GetOverlayInfo请求处理程序图标覆盖的位置。图标覆盖处理程序返回包含覆盖图标的文件的名称,以及他们在文件中的索引。然后,Shell添加这些图标覆盖到系统图像列表。

    Shell通过调用IShellIconOverlayIdentifier::GetPriority来确定图标覆盖的优先级。优先级值是从0到100的数字,其中100表示最低优先级。如果有多个图标覆盖被特定文件请求,Shell使用这些值来帮助确定哪个图标覆盖将显示

    在绘画一个对象图标之前,Shell传递对象名称到每个图标覆盖处理程序的IShellIconOverlayIdentifier::IsMemberOf方法。图标覆盖处理程序通常与特定文件分组相关。例如,图标覆盖处理程序可能请求一个文件类型的所有成员的一个覆盖,就像一个.myp文件名扩展的所有文件。如果处理程序想要他的图标覆盖被显示,它返回S_OK。然后Shell调用处理程序IShellIconOverlayIdentifier::GetOverlayInfo方法决定哪个图标将显示。

    说明:

    1. 目前不知道如何调试实现IShellIconOverlayIdentifier接口的DLL。在VS2005下选择Debug模式,启动调试我也输入了C:windowsexplorer.exe进程,但是提示“无法找到explorer.exe的调试信息”。故开发OverlayIcon特效时如何调试是个问题。

    2.  为了能在XP上也运行,需要考虑在VS2005中,项目属性->配置属性->常规->ATL的使用选择“静态连接到ATL”。

    3. 在Win7上开发时,可以考虑先关掉UAC,不然效果也有可能无法出现。

    出处:https://blog.csdn.net/xiaoqiangxx/article/details/7239298

    =======================================================================================

    vs2013 windows 覆盖图标实现

    实现类似SVN小图标的功能,可以更清晰地给用户显示文件的状态,实现如图效果
    在这里插入图片描述

    一、创建工程

    在这里插入图片描述
    全部选择默认选项
    在这里插入图片描述

    生成如图目录,xxxxPS工程可以删掉,其中Generated Files文件夹里的文件,.def文件,.idl文件都是可以自动生成的,

    二、创建类

    通过引导创建一个类,工程->add->Class,选择ATL->ATL Simple Object,全部默认选项就可,通过引导来创建的ATL类vs会自动帮你写好idl文件,就不需要自己特意去看这个文件的编写了,你只需要关心自己创建的类就可以(.h和.cpp)。

    三、继承IShellIconOverlayIdentifier接口

    csdn可查这个接口的基本信息,基本上这个接口就是为了实现覆盖小图标的功能
    在这里插入图片描述

    四、实现接口的三个方法

    STDMETHOD(GetOverlayInfo)(LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD* pdwFlags);
    STDMETHOD(GetPriority)(int* pPriority);
    STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);

    五、基本实现代码

    // testicon.h : Declaration of the Ctesticon
    
    #pragma once
    #include "resource.h"       // main symbols
    
    
    
    #include "ATLProject1_i.h"
    
    
    
    #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
    #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
    #endif
    
    using namespace ATL;
    
    
    // Ctesticon
    
    class ATL_NO_VTABLE Ctesticon :
    	public CComObjectRootEx<CComSingleThreadModel>,
    	public CComCoClass<Ctesticon, &CLSID_testicon>,
    	public IDispatchImpl<Itesticon, &IID_Itesticon, &LIBID_ATLProject1Lib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
    	public IShellIconOverlayIdentifier
    {
    public:
    	Ctesticon()
    	{
    	}
    
    	STDMETHOD(GetOverlayInfo)(LPWSTR pwszIconFile,
    		int cchMax, int *pIndex, DWORD* pdwFlags);
    	STDMETHOD(GetPriority)(int* pPriority);
    	STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);
    DECLARE_REGISTRY_RESOURCEID(IDR_TESTICON)
    
    
    BEGIN_COM_MAP(Ctesticon)
    	COM_INTERFACE_ENTRY(Itesticon)
    	COM_INTERFACE_ENTRY(IDispatch)
    	COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)
    END_COM_MAP()
    
    
    
    	DECLARE_PROTECT_FINAL_CONSTRUCT()
    
    	HRESULT FinalConstruct()
    	{
    		return S_OK;
    	}
    
    	void FinalRelease()
    	{
    	}
    
    public:
    
    
    
    };
    
    OBJECT_ENTRY_AUTO(__uuidof(testicon), Ctesticon)
    // testicon.cpp : Implementation of Ctesticon
    
    #include "stdafx.h"
    #include "testicon.h"
    
    STDMETHODIMP Ctesticon::GetOverlayInfo(
    	LPWSTR pwszIconFile,
    	int cchMax,
    	int* pIndex,
    	DWORD* pdwFlags)
    {
    	std::wstring picpath = GetPicPath();
    	wcscpy(pwszIconFile, picpath.c_str()); // ico 文件的路径,用dll资源文件则传入dll路径,pIndex为资源文件的偏移
    	*pIndex = 0;
    	*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
    	return S_OK;
    }
    
    STDMETHODIMP Ctesticon::GetPriority(int* pPriority)
    {
    	// 返回优先级,0是最高级,这里的功能我没试过,应该是两个组件同时需要显示的时候,通过这个值去判断显示哪个
    	*pPriority = 0;
    	return S_OK;
    }
    
    STDMETHODIMP Ctesticon::IsMemberOf(LPCWSTR pwszPath, DWORD dwAttrib)
    {
    	// pwszPath 会传入文件路径,根据这个路径判断该文件是否需要显示图标
    	if (wcsncmp(pwszPath, L"C:\test", 7))
    		return S_FALSE; // 不显示
    	else
    		return S_OK; // 显示
    }

    下面是注册表配置文件

    HKCR
    {
    	NoRemove CLSID
    	{
    		ForceRemove {C9B4C1A1-CB96-4681-8C4C-0676C88F29A7} = s 'testicon Class'
    		{
    			ForceRemove Programmable
    			InprocServer32 = s '%MODULE%'
    			{
    				val ThreadingModel = s 'Apartment'
    			}
    			TypeLib = s '{89DC6A3E-B4AF-476D-9A6C-BDBA1F025E3C}'
    			Version = s '1.0'
    		}
    	}
    }
    HKLM
    {
      NoRemove SOFTWARE
      {
        NoRemove Microsoft
        {
          NoRemove Windows
          {
            NoRemove CurrentVersion
            {
              NoRemove Explorer
              {
                NoRemove ShellIconOverlayIdentifiers
                {
                  ForceRemove '1testico' = s '{C9B4C1A1-CB96-4681-8C4C-0676C88F29A7}'
                  {
                  }           
                }
              }
            }
          }
        }
      }
    }

    六、组件安装、卸载

    管理员权限运行cmd,执行下面命令,其中[dllpath]是编译生成的dll绝对路径,记得路径中有空格要用双引号

    : 安装
    regsrv32 "[dllpath]"
    : 卸载
    regsrv32 /u "[dllpath]"

    检查是否安装成功可以去注册表查看

    计算机HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers

    下面图片是SVN的小图标注册表
    在这里插入图片描述

    七、备注

    1. Windows Explorer Shell 支持的 Overlay Icon 最多 15 个,Windows 自身使用了 4 个,只剩 11 个可扩展使用,Windows 内部就是按图标名称的字母顺序来优先显示的。【参考连接

    出处:https://blog.csdn.net/lianjunming/article/details/102806525

    =======================================================================================

    如何创建Overlay Icon(覆盖图标)

    介绍

    何为Overlay Icon(覆盖图标),如果你有用过Github,Sky Drive,Dropbox,TortoiseSVN中的一款或者多款产品,就可以在相关的同步文件夹中看到文件夹和文件的图标上会有相关状态(新增、修改等)状态的显示,如下图所示。而显示这个状态用到的就是在Windows中注册的Overlay Icon。

    本文就是介绍如何创建自己的Overlay Icon,以实现自己的功能。
    图片描述

    开发方式

    有两种开发方式,用C++ ATL开发需要手动在程序中编写相关的注册表,调试也有一些难度;用C#调SharpShell来实现会方便很多,且有相关的调试工具。

    1. C++ ATL编写动态链接库
      由于开发相对耗时,本次并未采用此种开发方式

    2. C#使用SharpShell编写类库
      本节内容有参考.NET Shell Extensions - Shell Icon Overlay Handlers,对其作者,也是SharpShell的开发者Dave Kerr表示感谢!

      1.新建Visual C#项目,选择“类库”
      2.添加对SharpShell.dll的引用

      3.添加对应的显示覆盖图标的类,且该类要继承SharpShell.dll的SharpIconOverlayHandler类,并实现该类的方法。如在此我要实现一个显示 图片描述 图标,创建AddedFileStateOverlayHandler类,并根据实际要求实现对应的逻辑。

      具体代码如下:

        /// <summary>
        /// The AddedFileStateOverlayHandler is an IconOverlayHandler that shows
        /// a padlock icon over files that are localadded or serveradded.
        /// </summary>
        [ComVisible(true)]
        public class AddedFileStateOverlayHandler : SharpIconOverlayHandler
        {
            /// <summary>
            /// Called by the system to get the priority, which is used to determine
            /// which icon overlay to use if there are multiple handlers. The priority
            /// must be between 0 and 100, where 0 is the highest priority.
            /// </summary>
            /// <returns>
            /// A value between 0 and 100, where 0 is the highest priority.
            /// </returns>
            protected override int GetPriority()
            {
                //  The read only icon overlay is very low priority.
                return 10;
            }
    
            /// <summary>
            /// Determines whether an overlay should be shown for the shell item with the path 'path' and
            /// the shell attributes 'attributes'.
            /// </summary>
            /// <param name="path">The path for the shell item. This is not necessarily the path
            /// to a physical file or folder.</param>
            /// <param name="attributes">The attributes of the shell item.</param>
            /// <returns>
            ///   <c>true</c> if this an overlay should be shown for the specified item; otherwise, <c>false</c>.
            /// </returns>
            protected override bool CanShowOverlay(string path, FILE_ATTRIBUTE attributes)
            {
                try
                {
                    string folderPath = Path.GetDirectoryName(path);
                    string fileName = Path.GetFileName(path);
                    FileInfo fi = new FileInfo(path);
                    if (fi.Attributes == (FileAttributes.Normal | FileAttributes.System | FileAttributes.NotContentIndexed | FileAttributes.Hidden))
                        return false;
                    if (fileName.StartsWith("."))
                        return false;
                    if(!XmlHelper.isCfgFileExist(folderPath))
                        return false;
                    OverlayFile overlayFile = XmlHelper.getFileByName(fileName, folderPath);
                    if (overlayFile == null)
                    {
                        string physicalId =File.Exists(path)?WindowsApi.GetPhysicalId(path).ToString():string.Empty;
                        //cxb added 2017-04-18
                        if (!File.Exists(path) && Directory.Exists(path))
                        {
                            long folderId = FileHelper.ReadOatosSyncFile(path);
                            if (folderId != -1)
                                physicalId = folderId.ToString();
                        }
                        if(!string.IsNullOrEmpty(physicalId))
                            overlayFile = XmlHelper.getFileByPhysicalId(physicalId, folderPath);
                    }
                    if (overlayFile == null)
                    {
                        FileHelper.SetFolderOverlayState(folderPath,"LocalModified");
                        return true;
                    }
                    else
                    {
                        //当为文件夹时,PhysicalId可以标识该文件夹是否已经上传到云盘
                        if (overlayFile.ChangeType.Equals("ServerNew") || overlayFile.ChangeType.Equals("LocalNew")
                            || (overlayFile.IsFolder && string.IsNullOrEmpty(overlayFile.PhysicalId)))
                        {
                            FileHelper.SetFolderOverlayState(folderPath,"LocalModified");
                            return true;
                        }
                        else
                            return false;
                    }
                }
                catch (Exception)
                {
                    return false;
                }
            }
    
            /// <summary>
            /// Called to get the icon to show as the overlay icon.
            /// </summary>
            /// <returns>
            /// The overlay icon.
            /// </returns>
            protected override System.Drawing.Icon GetOverlayIcon()
            {
                return Properties.Resources.AddedIcon;
            }
        }
    
    
    

    编写完成后,编译即可生成dll.

    注意:这里编译的时候,需要给当前dll使用强签名,不然后买注册dll的时候会提示无法注册的,具体请自己是baidu强签名是怎么做的。

    安装部署

    1. C++ ATL编写的动态链接库
      使用regsvr32.exe注册,使用管理员权限运行cmd(命令行),regsvr32.exe mydll.dll

    2. C#使用SharpShell编写类库
      使用regasm.exe注册.net程序集,使用管理员权限运行cmd(命令行),%windir% egasm.exe mydll.dll /codebase,其中codebase选项用于将该程序集注册到全局GAC中。
      注意:

      • regasm.exe的版本必须要与要注册的程序的.net framework版本一致,如mydll.dll是在.net Framework 4.0平台下编写的,就需要使用4.0版本的regasm.exe注册

      • 需要区分64位和32位系统,采用对应系统的regasm.exe

    卸载

    1. C++ ATL编写的动态链接库
      使用regsvr32.exe注册,使用管理员权限运行cmd(命令行),regsvr32.exe mydll.dll -u

    2. C#使用SharpShell编写类库
      使用regasm.exe卸载.net程序集,使用管理员权限运行cmd(命令行),%windir% egasm.exe mydll.dll /u
      注意:

      • regasm.exe的版本必须要与要注册的程序的.net framework版本一致,如mydll.dll是在.net Framework 4.0平台下编写的,就需要使用4.0版本的regasm.exe注册

      • 需要区分64位和32位系统,采用对应系统的regasm.exe

    常见问题

    1.安装后未能显示OverlayIcon
    注册后,需要重启资源管理器,资源管理器才会重新加载注册表中我们通过Shell注册进去的覆盖图标。
    2.安装后未能显示OverlayIcon或者未全部显示
    Windows系统对于能够显示的Overlay Icon数目做了限制,按注册表中的顺序只取前10个,确保你写的OverlayIcon注册的顺序在前10个,注册表位置见下图:
    图片描述
    此处有一个小技巧:注册表的显示顺序是按照字母顺序来的,如果注意观察,就会发现像svn这类的产品,在注册表中对应的注册表项名称中多是以多个空格开始的,这样会排得比较靠前。可以在注册完成后,通过批处理文件(bat)将对应的注册表项改名来实现。

    集成到安装包

    本文是采用Advanced installer 11.0来制作安装包的,为了在安装及卸载过程中能注册和取消注册我们的覆盖图标类库(dll),需要分别写两个批处理文件,Install.batUninstall.bat,前者负责在安装时注册类库,后者负责在卸载时取消注册类库。
    Install.bat代码如下:

    ::type .AutoRegisterOverlay.txt
    ::关闭回显
    @echo off
    ::清除屏幕
    cls
    ::当前系统32位
    SET fwpath="%windir%Microsoft.NETFrameworkv4.0.30319"
    SET regPara="/reg:32"
    ::当前系统64
    if exist %windir%SysWOW64 (SET fwpath="%windir%Microsoft.NETFramework64v4.0.30319")
    if exist %windir%SysWOW64 (SET regPara="/reg:64")
    @echo %fwpath%
    @echo %regPara%
    @echo %~dp0
    ::install
    %fwpath%
    egasm.exe "%~dp0FileStateOverlayHandler.dll" /register /codebase
    ::Rename Registry
    reg copy "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersAddedFileStateOverlayHandler" "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   AddedFileStateOverlayHandler" /s /f  %regPara%
    reg delete "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersAddedFileStateOverlayHandler" /f  %regPara%
    reg copy "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersModifiedFileStateOverlayHandler" "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   ModifiedFileStateOverlayHandler" /s /f  %regPara%
    reg delete "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersModifiedFileStateOverlayHandler" /f  %regPara%
    reg copy "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersNormalFileStateOverlayHandler" "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   NormalFileStateOverlayHandler" /s /f  %regPara%
    reg delete "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersNormalFileStateOverlayHandler" /f  %regPara%
    ::完成后重启windows文件资源管理器
    taskkill   /im   explorer.exe   /f
    
    start   %windir%explorer.exe
    

    Uninstall.bat的代码如下:

    ::type .AutoRegisterOverlay.txt
    ::关闭回显
    @echo off
    ::清除屏幕
    cls
    ::当前系统32位
    SET fwpath="%windir%Microsoft.NETFrameworkv4.0.30319"
    SET regPara="/reg:32"
    ::当前系统64
    if exist %windir%SysWOW64 (SET fwpath="%windir%Microsoft.NETFramework64v4.0.30319") 
    if exist %windir%SysWOW64 (SET regPara="/reg:64")
    @echo %fwpath%
    @echo %regPara%
    ::Rename Registry
    reg copy "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   AddedFileStateOverlayHandler" "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersAddedFileStateOverlayHandler" /s /f  %regPara%
    reg delete "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   AddedFileStateOverlayHandler" /f  %regPara%
    reg copy "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   ModifiedFileStateOverlayHandler" "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersModifiedFileStateOverlayHandler" /s /f  %regPara%
    reg delete "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   ModifiedFileStateOverlayHandler" /f  %regPara%
    reg copy "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   NormalFileStateOverlayHandler" "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiersNormalFileStateOverlayHandler" /s /f  %regPara%
    reg delete "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifiers   NormalFileStateOverlayHandler" /f  %regPara%
    @echo %~dp0
    ::uninstall
    %fwpath%
    egasm.exe "%~dp0FileStateOverlayHandler.dll" /u

    完成以上步骤后,在Advanced Installer中选择“自定义操作”->“LaunchFile”,创建对应的操作过程,并注意其执行顺序。Install.bat是在完成了所有的安装复制操作后才执行的,Uninstall.bat是卸载一开始就要执行的,具体执行步骤见下图:
    图片描述图片描述图片描述

    参考资料

    1. Managing overlay icons for Dropbox and TortoiseSVN and TortoiseGit

    2. .NET Shell Extensions - Shell Icon Overlay Handlers

    3. Troubleshooting SharpShell Servers

    出处:https://segmentfault.com/a/1190000009279826/

    =======================================================================================

    个人总结

    1)我自己测试了使用C++语言开发,在vs2017中创建ATL项目的方式,创建的DLL,是可以成功显示对应图标的。

    2)我也测试了使用C#语言开发,对SharpShell.dll中的继承来实现,也是可以成功显示对应图标的。

    3)建议采用C++语法创建ATL项目的形式编写程序,灵活性强,都可以定制;使用SharpShell.dll来实现的方式,注册表中比较死板,当然后期可用bat改名等方式实现

    4)最好所有ico图标全部打包到DLL文件中,方便多台电脑的安装部署;

    5)注册方式不同,个人更倾向于C++的方式来注册,符合常规;

    =======================================================================================

    您的资助是我最大的动力!
    金额随意,欢迎来赏!
    款后有任何问题请给我留言。

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我。(●'◡'●)

    如果你觉得本篇文章对你有所帮助,请给予我更多的鼓励,求打             付款后有任何问题请给我留言!!!

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【Jack_孟】!

  • 相关阅读:
    Android ViewPager实现选项卡切换
    Android Fragment是什么
    Android 点击文字实现跳转
    海底捞的十五天,让我重当程序员
    saltstack 实现haproxy+keepalived
    saltstack 实现系统初始化
    saltstack 实现redis主从
    python类基础
    Mysql 数据库备份工具 xtrabackup
    Python函数式编程
  • 原文地址:https://www.cnblogs.com/mq0036/p/14926674.html
Copyright © 2011-2022 走看看