【问题标题】:ASP.NET and COM interopASP.NET 和 COM 互操作
【发布时间】:2011-11-18 20:58:11
【问题描述】:

我正在尝试在我的 asp.net Web 应用程序中使用 COM 组件。在这个组件中,我传递了存储在我的服务器目录中的图像文件的路径,并且这个组件给了我一个 IPicture 数据类型作为回报。

以下是我正在经历的步骤,我会在每个步骤中发布我的问题,以便它保持具体。

  1. 我在我的解决方案中引用了 DLL。
  2. 提前绑定 DLL 并实例化特定的类和接口。

问题 1. 首先,我无法在 VS 智能中看到 IL DASM 中可见的所有方法和属性。只有少数可用。为什么?

ViewerClass cview = null; // ViewerClass is the class from the COM Component
Viewer Icsview = null; // Viewer is one of the interfaces that ViewerClass has.
cview = new ViewerClass();

if (cview is Viewer)
{
    Icsview = (Viewer)cview;
    Icsview.Open(filePath, 0, 0); // filePath is a string, passing the path of the file present in my local directory.

问题 2:这是发生错误的地方:- 当代码到达这一行时,我收到一个 InvalidCast 异常:

  1. 调用应该对文件起作用并转换为 IPicture 类型变量的方法:

在当前场景下,这段代码不会执行。

我尝试过用不同的方式与这个组件对话。我试过后期绑定。

以下是我用于后期绑定的代码:

object objCSViewerLateBound;
Type objTypeCSViewer;
object[] arrayInput = new object[3];
arrayInput[0] = filePath;
arrayInput[1] = 0;
arrayInput[2] = 0;
objTypeCSViewer = Type.GetTypeFromCLSID(new Guid("{89251546-3F1C-430D-BA77-F86572FA4EF6}"));
objCSViewerLateBound = Activator.CreateInstance(objTypeCSViewer);
objTypeCSViewer.InvokeMember("Open", BindingFlags.Default | BindingFlags.InvokeMethod, null, objCSViewerLateBound, arrayInput);
// getting the values from the properties
double viewMaxX = (double)objTypeCSViewer.InvokeMember("ViewMaxX", BindingFlags.Default | BindingFlags.GetProperty, null, objCSViewerLateBound, new object[] { });
double viewMaxY = (double)objTypeCSViewer.InvokeMember("ViewMaxY", BindingFlags.Default | BindingFlags.GetProperty, null, objCSViewerLateBound, new object[] { });
double viewMinX = (double)objTypeCSViewer.InvokeMember("ViewMinX", BindingFlags.Default | BindingFlags.GetProperty, null, objCSViewerLateBound, new object[] { });
double viewMinY = (double)objTypeCSViewer.InvokeMember("ViewMinY", BindingFlags.Default | BindingFlags.GetProperty, null, objCSViewerLateBound, new object[] { });
// geting the image height and width
int imagewidth, imageheight, pictype;
imagewidth = 1280; imageheight = 800; pictype = 1;
object[] previewDetails = new object[7];
previewDetails[0] = viewMinX;
previewDetails[1] = viewMinY;
previewDetails[2] = viewMaxX;
previewDetails[3] = viewMaxY;
previewDetails[4] = imagewidth;
previewDetails[5] = imageheight;
previewDetails[6] = pictype;
IPicture pict = (IPicture)objTypeCSViewer.InvokeMember("Preview", BindingFlags.Default | BindingFlags.GetProperty, null, objCSViewerLateBound, previewDetails); 

latebinding 可以工作,但只需几个步骤,我就可以通过 Open 方法,我可以从属性中获取值,但在最后一行,我收到一个错误,即 TargetInvocationException 未被用户代码处理。不知道是什么意思。

  1. 为什么会出现这个错误?

请注意:我已尝试通过 Javascript 块使用该组件。它工作正常。

问题 4: 我已经尝试过在 winforms 应用程序中发布的相同代码 sn-ps。它可以正常工作。这让我觉得我的方法有问题。与 ASP.NET 应用程序中的 COM 组件通信是否需要任何特殊过程?

【问题讨论】:

    标签: c# asp.net com interop


    【解决方案1】:

    更新:好的。我终于让这个 COM 对象工作了,但仍然存在一些问题。其他论坛中的某个聪明人(我现在不记得是哪一个了)让我检查组件的 ThreadingModel,结果发现它设置为 Apartment。所以我将代码更改如下:

        ...
        using System.Threading;
    
        namespace...
        protected void Button1_Click(object sender, EventArgs e)
         {
           Thread thread = new Thread(new ThreadStart(STAOperation));
           thread.SetApartmentState(ApartmentState.STA);
           thread.Start();
           thread.Join();
    
         }
         public void STAOperation()
          {
            CSViewerRL.ViewerClass csv = new ViewerClass();
            csv.Open(filePath, 0, 0);//strange error
            //other codes..
          }
    

    现在这段代码可以工作了,但有时我在调试时遇到一个奇怪的错误,它指出 AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。

    通常应用程序在我第一次尝试调试时运行良好,但此错误主要发生在我第二次或第三次在 ASP.Net 服务器仍在运行时从我的 VS 按 f5 时。如果我停止服务器并再次运行,它通常会消失。我认为这个问题是因为这个新的 STA 线程。也许我没有正确处理新线程。还是我应该研究其他一些事情?有人能指出在这种情况下我应该怎么做吗?

    请注意:我不知道这是否可以被视为一个答案,但我似乎无法在这里编辑我的问题,并且评论空间太短...... :-(

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      • 2011-07-02
      • 2010-12-14
      相关资源
      最近更新 更多