VS 2017年定義Microsoft.VisualStudio.Shell.Interop.15.0.DesignTime.dll這個接口:在C#中定義Visual Studio COM接口時,應該使用哪個類/方法/參數屬性?
[Guid("A459C228-5617-4136-BCBE-C282DF6D9A62")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IVsSolutionEvents7
{
void OnAfterCloseFolder(string folderPath);
void OnAfterLoadAllDeferredProjects();
void OnAfterOpenFolder(string folderPath);
void OnBeforeCloseFolder(string folderPath);
void OnQueryCloseFolder(string folderPath, ref int pfCancel);
}
我想實現這個接口在我的擴展,使我可以對這些事件作出迴應,但我想相同的擴展程序集與Visual Studio 2015兼容,所以我不希望依賴於該VS 2016 DLL。因此,我將該定義複製粘貼到我的代碼中。
我可以從文檔或從Visual Studio本身通過F12獲得該定義,當我添加對該DLL的引用時,或從JustDecompile。它們都給出了大致相同的界面定義。
但是,接口定義不工作:
- 的方法是在錯誤的順序,所以那些錯誤的被調用。
- 字符串沒有正確傳入 - 我的猜測是它們被認爲是Bstrs,但是這些是LPWStrs。
- 我經常在通話後遇到訪問衝突 - 我的猜測是不正確的調用約定。
如果我申請了一堆屬性的接口,因此它成爲這樣的:
[ComVisible(true)]
[ComImport]
[Guid("A459C228-5617-4136-BCBE-C282DF6D9A62")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IVsSolutionEvents7
{
[PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int OnAfterOpenFolder([In, MarshalAs(UnmanagedType.LPWStr)] string folderPath);
...
,並把這些方法在正確的順序,那麼它的工作原理。
你怎麼會知道要使用的這些屬性,或者把它才能在方法呢?文檔不一定有用 - 例如,documentation for that interface對上面的簡單破碎定義沒有任何意義。
即使我有權訪問定義接口的組合件(本例中爲Microsoft.VisualStudio.Shell.Interop.15.0.DesignTime.dll),這些屬性的位置在哪裏?當我在Visual Studio或JustDecompile中查看該DLL中的定義時,我只能看到那個簡單的定義,但如果通過對該DLL的引用使用該接口,則可以工作。這些屬性在某種程度上存在但不可見,或者與我自己定義接口時的默認屬性不同。
我拼湊起了我從貨物崇拜覆制,檢查IDL和盲目試驗和錯誤中使用的屬性,因此我並不真正相信它們。 我該怎麼做呢?
謝謝,是的,我使用IDL作爲我的來源之一。但是,例如,MethodImplOptions.InternalCall與IDL有什麼關係? (如果它不在IDL中,但作爲STDMETHODCALLTYPE存在於.h中,則同樣的問題適用 - 你如何將它與另一個相關聯?) – RichieHindle
感謝指向dotPeek的指針 - 它已立即替換了我的工具箱中的JustDecompile!我不知道JustDecompile會悄悄丟棄這樣的屬性。 – RichieHindle
STDMETHODCALLTYPE是一個基本上在方法上應用'__stdcall'調用約定的Windows C宏。它在平臺調用方法的.NET方面是隱含的,所以你不需要添加它。 InternalCall不一樣,它與CLR如何實現所有這些有關,但是你可以忘記這個屬性。 –