2010-01-06 92 views
3

使用this作爲參考,我試圖創建一個異步可插入協議,它只是暫時可用於我的應用程序(並且未在系統範圍內註冊)。我正在使用CoInternetGetSession,然後撥打RegisterNameSpace來執行此操作。但是,當我撥打RegisterNameSpace時,出現AccessViolation例外情況:Attempting to read or write protected memory異步可插入協議

任何想法是怎麼回事?

我的代碼如下所示:

[ComImport] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
[Guid("00000001-0000-0000-C000-000000000046")] 
[ComVisible(true)] 
public interface IClassFactory 
{ 
    void CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject); 
    void LockServer(bool fLock); 
} 

/* Custom class to act as a class factory that create's an instance of the protocol */ 
[Guid("0b9c4422-2b6e-4c2d-91b0-9016053ab1b1")] 
[ComVisible(true),ClassInterface(ClassInterfaceType.AutoDispatch)] 
public class PluggableProtocolFactory : IClassFactory 
{ 
    public Type AppType; 
    public PluggableProtocolFactory(Type t) 
    { 
     this.AppType = t; 
    } 
    public void CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject) 
    { 
     riid = ProtocolSupport.GetGuid(this.AppType); 
     IInternetProtocol p = Activator.CreateInstance(this.AppType) as IInternetProtocol; 
     ppvObject = Marshal.GetComInterfaceForObject(p, typeof(IInternetProtocol)); 
    } 

    public void LockServer(bool fLock) 
    { 
     var b = fLock; 
    } 

} 

[ComVisible(true)] 
[ComImport] 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
[Guid("79eac9e7-baf9-11ce-8c82-00aa004ba90b")] 
public interface IInternetSession 
{ 
    void CreateBinding(); // Not Implemented 
    void GetCache(); // Not Implemented 
    void GetSessionOption(); // Not Implemented 
    void RegisterMimeFilter([MarshalAs(UnmanagedType.Interface)] IClassFactory pCF, ref Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] string pwzType); 
    void RegisterNameSpace([MarshalAs(UnmanagedType.Interface)] IClassFactory pCF, ref Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol, 
          UInt32 cPatterns, [MarshalAs(UnmanagedType.LPArray,ArraySubType=UnmanagedType.LPWStr)] string[] ppwzPatterns, UInt32 dwReserved); 
    void SetCache(); // Not Implemented 
    void SetSessionOption(); // Not Implemented 
    void UnregisterMimeFilter(IClassFactory pCF, [MarshalAs(UnmanagedType.LPWStr)] string pwzType); 
    void UnregisterNameSpace(IClassFactory pCF, [MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol); 
} 

[ComVisible(false)] public interface IComRegister 
{ 
    void Register(Type t); 
    void Unregister(Type t); 
} 

[ComVisible(false), AttributeUsage(AttributeTargets.Class, AllowMultiple=true) ] 
public class AsyncProtocolAttribute : Attribute, IComRegister 
{ 
    public string Name; 
    public string Description; 

    [DllImport("urlmon.dll",PreserveSig=false)] 
    public static extern int CoInternetGetSession(UInt32 dwSessionMode /* = 0 */, ref IInternetSession ppIInternetSession, UInt32 dwReserved /* = 0 */); 

    public void Register(Type t) 
    { 
     IInternetSession session = null; 
     CoInternetGetSession(0, ref session, 0); 
     Guid g = new Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B"); 
     session.RegisterNameSpace(new PluggableProtocolFactory(t), ref g, this.Name, 0, null, 0); 

    } 

在PluggableProtocolFactory的CreateInstance方法不會被調用。 (一個斷點從來沒有被擊中),所以RegisterNameSpace方法中發生了其他事情。

我試着以管理員和普通用戶身份運行。兩種場合都有同樣的錯誤。

+0

是否可以粘貼包括樣本的更新你在類上使用'AsyncProtocolAttribute'屬性?我一直試圖自己實現同樣的'臨時協議處理程序'範例,但我看到了你的工作,而且我對你的屬性方法很感興趣。 – Codesleuth 2010-06-15 11:04:45

+0

我基於我的代碼:http://www.codeproject.com/kb/aspnet/AspxProtocol.aspx 這是一個完整的工作示例。 – 2010-06-16 10:32:46

+0

@HS感謝您的回覆,我使用相同的資源爲我的大型項目構建示例基礎項目。我收到一個錯誤,雖然你已經得到了你的工作,我想知道你是否可以闡明這一點:http://stackoverflow.com/questions/3062642/feeding-pdf-through-iinternetsession-to-webrbrowser -control-error – Codesleuth 2010-06-17 14:46:09

回答

0

OK,想通了:在IInternetSession接口的聲明是錯誤的:

這裏有一個更好的我從monoblog拿起:

[ComVisible(true), Guid("79eac9e7-baf9-11ce-8c82-00aa004ba90b"),InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IInternetSession 
{ 
    [PreserveSig] 
    int RegisterNameSpace(
     [In] IClassFactory classFactory, 
     [In] ref Guid rclsid, 
     [In, MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol, 
     [In] 
      int cPatterns, 
     [In, MarshalAs(UnmanagedType.LPWStr)] 
      string ppwzPatterns, 
     [In] int dwReserved); 

    [PreserveSig] 
    int UnregisterNameSpace(
     [In] IClassFactory classFactory, 
     [In, MarshalAs(UnmanagedType.LPWStr)] string pszProtocol); 

    int Bogus1(); 

    int Bogus2(); 

    int Bogus3(); 

    int Bogus4(); 

    int Bogus5(); 
} 
0

您在RegisterNameSpace方法中調用PluggableProtocolFactory的構造函數,但不調用CreateInstance方法。我認爲這就是你的問題所在,從來沒有創建一個IInternetProtocol實例傳遞給你的方法。

+0

RegisterNameSpace方法將IClassFactory作爲其第一個參數。我假設RegisterNameSpace方法在準備好時會調用CreateInstance本身?這不是ClassFactory接口的目的嗎? – 2010-01-07 01:26:54

+0

不,它不會自己調用它,你必須在PluggableProtocolFactory的構造函數中調用它,或者在你的Register方法中調用它。你應該回顧一下接口的功能和功能。 – 2010-01-07 14:17:14

+0

有一個接口的全部重點是消費方法能夠使用它。如果消費方法不會使用它,爲什麼需要在界面中聲明它?對不起,這沒有任何意義。這是一個思想實驗:假設我手動調用CreateInstance。我會傳遞什麼參數?我將如何處理它返回的價值? RegisterNameSpace如何使用它?如果RegisterNameSpace沒有使用它,那麼如果我實際調用它或不會怎麼樣? – 2010-01-09 02:15:31