C# 调用托管代码的非托管代码在开发人员计算机上工作,而不是在部署的计算机上工作
我正在基于VideoRenderElement项目构建一个网络摄像头应用程序(http://videorendererelement.codeplex.com/),它使用DirectShowLib和与非托管activex组件的互操作。我正在使用VisualStudio2010,但目标是.NET3.5(2.0CLR运行时) 我已经能够在我的开发机器上构建和运行这个应用程序,没有任何问题(甚至在VisualStudio之外)。然而,当我在目标机器上部署应用程序(Windows 7,.NET,到目前为止,C++重新分发到目前为止)时,应用程序崩溃了。我设置了另一个方法,将正在运行的应用程序记录到目标机器上的文本文件中。跟踪到一个关键区别,非托管代码在托管代码中调用该方法,只有前面定义的静态字段丢失。这只发生在目标机器上(我将代码部署到的机器)。下面是一些代码片段和我记录的内容。令人困惑的是,这个错误只发生在目标机器上。如果能为我指明正确的方向,我将不胜感激C# 调用托管代码的非托管代码在开发人员计算机上工作,而不是在部署的计算机上工作,c#,c++,interop,com-interop,directshow,C#,C++,Interop,Com Interop,Directshow,我正在基于VideoRenderElement项目构建一个网络摄像头应用程序(http://videorendererelement.codeplex.com/),它使用DirectShowLib和与非托管activex组件的互操作。我正在使用VisualStudio2010,但目标是.NET3.5(2.0CLR运行时) 我已经能够在我的开发机器上构建和运行这个应用程序,没有任何问题(甚至在VisualStudio之外)。然而,当我在目标机器上部署应用程序(Windows 7,.NET,到目前为
namespace MediaBridge
{
.....
public class MediaBridgeManager
{
public delegate void NewMediaGraphInfo(MediaBridgeGraphInfo GraphInfo);
private static readonly Dictionary<string, NewMediaGraphInfo> _delegateHash = new Dictionary<string, NewMediaGraphInfo>();
......
public static void AddMediaGraphInfo(MediaBridgeGraphInfo GraphInfo)
{
if (_delegateHash.ContainsKey(GraphInfo.MediaUrl))
{
NewMediaGraphInfo callback = _delegateHash[GraphInfo.MediaUrl];
_delegateHash.Remove(GraphInfo.MediaUrl);
/* Suppress all errors on the callback */
try
{
callback(GraphInfo);
}
catch {}
}
}
......
public static bool RegisterCallback(string MediaUrl, NewMediaGraphInfo Callback)
{
bool returnval = true;
MediaUrl = FormatUrl(MediaUrl);
if (!_delegateHash.ContainsKey(MediaUrl))
{
_delegateHash.Add(MediaUrl, Callback);
}
else
{
returnval = false;
}
return returnval;
}
}
}
根据我的日志文件,.NET端正在调用MediaBridge::MediaBridgeManager::AddMediaGraphInfo(),但由于_delegateHash变量现在为空,因此永远无法回拨
下面是我的日志文件在我尝试部署应用程序的目标计算机上的说明:
RegisterCallback(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ Contains Key: True Delegate Hash count: 1
InitializeDirectShow(): RegisterCallback == true, Url == DShowMediaBridge://d0ffd222-d023-483b-8fc7-4b4035ce3922
AddMediaGraphInfo(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ FilterGraph: 71122304 Contains Key: False Delegate Hash count: 0
请注意,当非托管代码调用AddMediaGraphInfo()时,委托哈希计数(_delegateHash.count)现在是如何为0的
VS在我的开发机器上为我所做的,我是否应该在目标机器上识别COM/C++的dll?您如何在目标机器上部署和运行应用程序。您只是在可执行文件上复制,还是在创建安装程序?如果您正在创建安装程序,是否正在向RegSvr32注册AX文件
COM组件的问题是,它们必须在相关框的注册表中注册。在您的框中,您已经注册了此项,因此您不会有问题。但是,在目标框上,用户可以根据自己的意愿注册,也可以不注册。如果已设置安装程序,则必须“安装”AX文件,以便它在注册表中注册。否则,无论您如何部署AX文件,都无法找到AX文件。这是COM的缺点之一。您是在调试模式下编译的吗?VS debug mode redist DLL仅安装在装有VS的PC上,可能存在DLL问题。在发行版中尝试…谢谢J.N.我已经在发行版模式下构建了解决方案。虽然我仍然不能100%确定为什么它能在开发箱中工作,但是,由于这是一个从VisualStudio2005/2008构建的开源解决方案,我将其导入VS2010,因此我尝试将原始activex控件文件复制到应用程序的目录中,覆盖VS2010使用该解决方案构建的内容,重新注册它,现在它可以工作了。我认为这与VS 2010有关,它是使用更高版本的Windows SDK(7.1)或针对.NET 4的更高版本的MSBuild构建的,我知道.NET 4在处理与COM的互操作方面有一些根本性的变化。谢谢Gregory。我已经创建了一个安装程序,然后将其复制过来,并在部署到的框上手动运行regsvr32。
RegisterCallback(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ Contains Key: True Delegate Hash count: 1
InitializeDirectShow(): RegisterCallback == true, Url == DShowMediaBridge://d0ffd222-d023-483b-8fc7-4b4035ce3922
AddMediaGraphInfo(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ FilterGraph: 71122304 Contains Key: False Delegate Hash count: 0