Asynchronous Pluggable Protocols(异步可插拔协议)
问题描述
使用 this 作为参考,我正在尝试创建一个异步可插入协议,仅对我的应用程序暂时可用(并且未在系统范围内注册).我正在使用 CoInternetGetSession
然后调用 RegisterNameSpace
来完成它.但是,当我调用 RegisterNameSpace
时,我得到一个 AccessViolation 异常:Attempting to read or write protected memory
.
Using this as reference, I'm trying to create an asynchronous pluggable protocol that is only temporarily available to my app (and not registered systemwide). I'm using CoInternetGetSession
and then calling RegisterNameSpace
to do it. However, when I make the call to RegisterNameSpace
I get an AccessViolation exception: 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
方法内部发生了其他事情.
The CreateInstance
method in PluggableProtocolFactory never gets called. (A break point there never gets hit) so something else is happening inside the RegisterNameSpace
method.
我尝试以管理员和普通用户的身份运行.两种情况都出现同样的错误.
I tried running both as an administrator and a normal user. Same error in both occasions.
推荐答案
好的,搞清楚了:IInternetSession接口的声明错误:
OK, figured it out: The declaration of the IInternetSession interface was wrong:
这是我从 monoblog 中挑选的一个更好的::p>
Here's a better one I picked up from 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();
}
这篇关于异步可插拔协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:异步可插拔协议


基础教程推荐
- 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
- 如何动态获取文本框中datagridview列的总和 2022-01-01
- 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
- 全局 ASAX - 获取服务器名称 2022-01-01
- JSON.NET 中基于属性的类型解析 2022-01-01
- 错误“此流不支持搜索操作"在 C# 中 2022-01-01
- 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
- 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
- 首先创建代码,多对多,关联表中的附加字段 2022-01-01
- 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01