2010-01-06 75 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