2017-03-19 1 views
0

私はIDataObjectのプロパティを変更できるように添付ファイルのドラッグドロップを傍受したいOutlookプラグインを開発していましたが、同じことを達成するためにEasyHookオープンライブラリを使用して、私は正常にCreateFileなどのような他のいくつかの一般的なAPIを引っ張ってきた。Ole32.dllで定義されたDoDragDropメソッドをフックすることができません

以下はコードスナップショットです。

公共部分クラスのDragDrop {

private LocalHook DragDropHook; 
    Stack<String> Queue = new Stack<string>(); 

    internal class HookCallbackHelper 
    { 
     public HookCallbackHelper(bool isUnicode) { IsUnicode = isUnicode; } 
     public bool IsUnicode; 
    } 
    private void DragDrop_Load(object sender, RibbonUIEventArgs e) 
    { 

    } 

    private void btnHook_Click(object sender, RibbonControlEventArgs e) 
    { 
     try 
     { 

      DragDropHook = LocalHook.Create(LocalHook.GetProcAddress("Ole32.dll", "DoDragDrop"), 
       new DDoDragDrop(DoDragDrop_Hooked),new HookCallbackHelper(true)); 

      DragDropHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 }); 


     } 
     catch (Exception ExtInfo) 
     { 
      System.Windows.Forms.MessageBox.Show(ExtInfo.Message); 
      //Interface.ReportException(ExtInfo); 

      return; 
     } 
    } 

    private int DoDragDrop_Hooked(IDataObject pDataObj, IDropSource pDropSource, uint dwOKEffects, uint[] pdwEffect) 
    { 


     System.Windows.Forms.MessageBox.Show("Hooked"); 

     try 
     { 

      HookCallbackHelper hch = HookRuntimeInfo.Callback as HookCallbackHelper; 
      lock (Queue) 
      { 
       Queue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" + 
        RemoteHooking.GetCurrentThreadId() + "]"); 
      } 
     } 
     catch 
     { 
     } 

     // call original API... 
     return DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect); 
    } 

    [UnmanagedFunctionPointer(CallingConvention.StdCall, 
     CharSet = CharSet.Ansi, 
     SetLastError = true)] 
    public delegate int DDoDragDrop(
     IDataObject pDataObj, 
     IDropSource pDropSource, 
     UInt32 dwOKEffects, 
     UInt32[] pdwEffect 
    ); 

    [DllImport("Ole32.dll", 
     CharSet = CharSet.Unicode, 
     SetLastError = true, 
     CallingConvention = CallingConvention.StdCall)] 
    public static extern int DoDragDrop(IDataObject pDataObj, IDropSource pDropSource, 
     UInt32 dwOKEffects, UInt32[] pdwEffect); 
} 

[ComImport, Guid("00000121-0000-0000-C000-000000000046"), 
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IDropSource 
{ 
    [PreserveSig] 
    UInt32 QueryContinueDrag(
    [MarshalAs(UnmanagedType.Bool)] bool fEscapePressed, 
    UInt32 grfKeyState); 

    [PreserveSig] 
    UInt32 GiveFeedback(
    UInt32 dwEffect); 
} 

答えて

1

私の代わりにSetExclusiveACL()

[DllImport("Ole32.dll")] 
static extern int DoDragDrop(IDataObject pDataObj, IDropSource pDropSource, uint dwOKEffects, uint[] pdwEffect); 

[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)] 
[return: MarshalAs(UnmanagedType.I4)] 
delegate int DragDropDelegate(IDataObject pDataObj, IDropSource pDropSource, uint dwOKEffects, uint[] pdwEffect); 

private LocalHook dragDropHook; 

private void ThisAddIn_Startup(object sender, System.EventArgs e) 
{ 
     try 
     { 

      dragDropHook = EasyHook.LocalHook.Create(EasyHook.LocalHook.GetProcAddress("Ole32.dll", "DoDragDrop"), 
       new DragDropDelegate(DoDragDropHook), this); 

      // Only hook this thread (threadId == 0 == GetCurrentThreadId) 
      dragDropHook.ThreadACL.SetInclusiveACL(new Int32[] {0}); 
     } 
     catch (Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.Message); 
     } 
} 

static int DoDragDropHook(IDataObject pDataObj, IDropSource pDropSource, uint dwOKEffects, uint[] pdwEffect) 
{ 
    //Do something... 
} 

の成功はVSTOスタートアップ方法でプロセスをフックし、SetInclusiveACL();を使用して更新#1

を持っていました

CF_FORMATにアクセスする必要がある場合は、 FORMATETCを作成し、それをGetDataメソッドに渡していました。私は「たFileContents」形式を参照するために

FORMATETC format = new FORMATETC(); 
format.cfFormat = (short)DataFormats.GetFormat("FileContents").Id; 
format.dwAspect = DVASPECT.DVASPECT_CONTENT; 
format.lindex = 0; 
format.ptd = new IntPtr(0); 
format.tymed = TYMED.TYMED_HGLOBAL | TYMED.TYMED_ISTREAM | TYMED.TYMED_ISTORAGE; 
STGMEDIUM medium = new STGMEDIUM(); 
pDataObj.GetData(ref format, out medium); 

それを設定しています以下は、これを使用すると、現在のプロセスのためのフックを有効にする必要が何をすべきかexactclyあるhttps://msdn.microsoft.com/en-us/library/windows/desktop/ms678431(v=vs.85).aspx

+0

DoDrを正常にフックできましたOutlookのagDrop関数。 – Markus1980Wien

+0

しかし、私はCF_HDROPフォーマットをpDataObjに追加できませんでした。実例がありますか? – Markus1980Wien

+0

@ Markus1980Wienフォーマットがどのようになっているかを示す答えを更新しました。これがあなたのニーズに合っているかどうかはわかりませんが、それは自分のニーズに合っています。 – Michael

-1

を参照してください。

DragDropHook.ThreadACL.SetInclusiveACL(new Int32[] { 0 }); 

へ現在のプロセスのフックを無効にしてください:

DragDropHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 }); 
+0

@Michael、私はDoDragDrop for Outlookをフックしました。電子メール/連絡先/仕事項目に最適です。しかし、カレンダーアイテムをドラッグすると、入力COMObjectがIDropSourceを実装していないと言ってクラッシュしました。それはあなたのために働くのですか? – uoxon

関連する問題