【问题标题】:How to implement AutoPlay for image import in c# under windows 10windows 10下c#如何实现图片导入自动播放
【发布时间】:2016-10-14 14:09:11
【问题描述】:

我正在尝试实现一个 AutoPlayHandler,当可移动存储连接到系统时,它会自动将图片导入我的应用程序(基于云的存储客户端,类似于即保管箱)。

我找到了 this questionthis article on code-project 并完成了所有代码项目文章的解释,但 我无法执行我的处理程序。每次我插入设备时,都会弹出一个消息框,说明“没有注册程序来打开此文件”。

处理程序在控制面板的列表中,我可以选择它。

我做错了什么或错过了什么?


这是我当前的代码:

using System;
using System.IO;
using System.Runtime.InteropServices;
using SpikeAutoPlay.AutoPlayOnArrivalHandler;

namespace MyAutoPlay
{
    [ComImport,
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
     Guid("00000122-0000-0000-C000-000000000046")]
    public interface IDropTarget
    {
        [PreserveSig]
        int DragEnter(IntPtr pDataObj,               //  IDataObject
                      ulong grfKeyState,             //  DWORD
                      POINTL pt,
                      ref ulong pdwEffect);          //  DWORD*

        [PreserveSig]
        int DragOver(ulong grfKeyState,              //  DWORD
                     POINTL pt,
                     ref ulong pdwEffect);           //  DWORD*

        [PreserveSig]
        int DragLeave();

        [PreserveSig]
        int Drop(IntPtr pDataObj,                    //  IDataObject
                 ulong grfKeyState,                  //  DWORD
                 POINTL pt,
                 ref ulong pdwEffect);               //  DWORD*

    }

    [ComVisible(true), Guid("06D15143-F98C-48D0-AEA8-F0675C103511")]
    public class AutoPlayOnArrivalHandler : IDropTarget
    {        
        public int DragEnter(IntPtr pDataObj,
            ulong grfKeyState,
            POINTL pt,
            ref ulong pdwEffect)
        {
            return 0; // Not needed for autoplay
        }

        public int DragOver(ulong grfKeyState,
            POINTL pt,
            ref ulong pdwEffect)
        {
            return 0; // Not needed for autoplay
        }

        public int DragLeave()
        {
            return 0; // Not needed for autoplay
        }

        public int Drop(IntPtr pDataObj,
            ulong grfKeyState,
            POINTL pt,
            ref ulong pdwEffect)
        {
            File.Create("C:\\temp\\works.txt");

            return 0;
        }
    }
}

这是我在注册表中创建的条目:

HKEY_LOCAL_MACHINE
  SOFTWARE
    Microsoft
      Windows
        CurrentVersion
          Explorer
            AutoplayHandlers
              Handlers
                SpikeAutoplay 
                  Action [REG_SZ]= SpikeAutoPlay Action Value
                  DefaultIcon [REG_SZ]= C:\path\to\myApp.ico
                  InvokeProgID [REG_SZ]= MyAutoPlay.AutoPlayOnArrivalHandler
                  InvokeVerb [REG_SZ]= import
                  Provider [REG_SZ]= SpikeAutoPlay Provider Value


HKEY_CLASSES_ROOT
  MyAutoPlay.AutoPlayOnArrivalHandler
    shell
      import
        DropTarget
           ClSID [REG_SZ]= {{06D15143-F98C-48D0-AEA8-F0675C103511}}


HKEY_LOCAL_MACHINE
  SOFTWARE
    Microsoft
      Windows
        CurrentVersion
          Explorer
            AutoplayHandlers
              EventHandlers
                ShowPicturesOnArrival
                  SpikeAutoplay [REG_SZ]

HKEY_CLASSES_ROOT
  CLSID
    {06D15143-F98C-48D0-AEA8-F0675C103511}
      InprocServer32
        (Standard) [RES_SZ] = c:\_sources\MyAutoPlayHander\bin\Debug\MyShellExtensions.dll
        ThreadingModel [REG_SZ]= Apartment

【问题讨论】:

  • 我在您的消息中没有看到 HKEY_CLASSES_ROOT\CLSID\{06D15143-F98C-48D0-AEA8-F0675C103511}。
  • 操作系统位数?扩展位数?
  • 扩展是 x86 编译的,操作系统是 win10 x64。我的问题中描述的注册表项已自动复制到 WOW6432Node
  • 您的扩展程序也必须是 x64。
  • 我现在仔细检查了一下,我错了。我的解决方案平台是 x86 但扩展是编译的 AnyCPU,对不起。您是否注意到我对实际错误的更新? ("没有注册程序来打开这个文件")

标签: c# windows winapi


【解决方案1】:

万一其他人有这个问题。这是我最终得到的解决方案:

我完全放弃了实现 IDropTarget 的最初想法。相反,我决定启动我的应用程序实例并仅传递可移动设备的驱动器号。然后,该应用程序将对该信息执行所需的任何操作(在我的情况下,将特定类型的所有文件从可移动设备复制到另一个驱动器上的特定文件夹中)。由于我的应用程序已经确保在启动时只有一个实例,这对我来说不是问题。


下面是它的工作原理

需要创建一个处理程序:

HKEY_LOCAL_MACHINE
    SOFTWARE
        Microsoft
          Windows
            CurrentVersion
              Explorer
                AutoplayHandlers
                  Handlers
                    SpikeAutoplay
                      Action [REG_SZ]= Import pictures (This value will be shown to the user)
                      DefaultIcon [REG_SZ]= C:\path\to\myApp.ico
                      InvokeProgID [REG_SZ]= MyAutoPlay.AutoPlayOnArrivalHandler
                      InvokeVerb [REG_SZ]= open
                      Provider [REG_SZ]= human readable app name (This value will be shown to the user as well)

现在,对于作为“InvokeProgID”给出的字符串值,必须有一个具有完全相同值的键(请注意,键从 importdropTarget 更改为 打开命令

HKEY_CLASSES_ROOT\HiDrive.AutoPlayOnArrivalHandler
    shell
        open
            command
                (Standard) [REG_SZ] = "C:\Path\To\Your\App.exe" %1 (mind the quotes)

%1 会将媒体的驱动器号作为参数传递给您的应用。

现在,对于您想要处理的每个事件,您都必须将事件处理程序添加到

下的相应子键中
HKEY_LOCAL_MACHINE
  SOFTWARE
    Microsoft
      Windows
        CurrentVersion
          Explorer
            AutoplayHandlers
              EventHandlers

例如,如果您想处理“ShowPictureOnArrival”事件,则必须添加一个新值 [REG_SZ],并将事件处理程序的名称(在本例中为“SpikeAutoplay”)作为值。示例:

HKEY_LOCAL_MACHINE
  SOFTWARE
    Microsoft
      Windows
        CurrentVersion
          Explorer
            AutoplayHandlers
              EventHandlers
                ShowPicturesOnArrival               
                  AnotherEventHandler [REG_SZ] = 
                  SpikeAutoplay [REG_SZ] =
                  YetAnotherEventHandler [REG_SZ] =

可以在here 找到一些事件处理程序的详细信息。我对这个主题的一般理解的来源——即使它误导我实施 IDropTarget——是this msdn article

【讨论】:

    猜你喜欢
    • 2013-02-20
    • 2015-12-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多