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,到目前为

我正在基于VideoRenderElement项目构建一个网络摄像头应用程序(http://videorendererelement.codeplex.com/),它使用DirectShowLib和与非托管activex组件的互操作。我正在使用VisualStudio2010,但目标是.NET3.5(2.0CLR运行时)

我已经能够在我的开发机器上构建和运行这个应用程序,没有任何问题(甚至在VisualStudio之外)。然而,当我在目标机器上部署应用程序(Windows 7,.NET,到目前为止,C++重新分发到目前为止)时,应用程序崩溃了。我设置了另一个方法,将正在运行的应用程序记录到目标机器上的文本文件中。跟踪到一个关键区别,非托管代码在托管代码中调用该方法,只有前面定义的静态字段丢失。这只发生在目标机器上(我将代码部署到的机器)。下面是一些代码片段和我记录的内容。令人困惑的是,这个错误只发生在目标机器上。如果能为我指明正确的方向,我将不胜感激

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