ASP.NET 和 COM 互操作

发布于 2024-12-05 03:58:55 字数 3024 浏览 0 评论 0原文

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

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

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

问题 1. 首先,我无法在 VS intelisence 中看到 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); 

后期绑定有效,但只有几个步骤,我可以通过 Open 方法,我可以从属性中获取值,但在最后一行,我收到一个错误 TargetInvocableException未被用户代码处理。我不知道这意味着什么。

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

请注意:我尝试通过 Javascript 块使用该组件。效果很好。

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

I am trying to use a COM component in my asp.net web application. In this Component I am passing the path of an image file stored in my server directory and this component is giving me an IPicture datatype in return.

Following are the steps that I am going through, I post my questions at each steps so that it remains specific.

  1. I am referencing the DLL in my solution.
  2. Early binding the DLL and instantiating the specific class and the interface.

Question 1. First up, I am not able to see all the methods and properties visible in the IL DASM in the VS intelisence. Only a few are available. why?

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.

Question 2: This is where the error occures: - when the code comes to this line, I receive an InvalidCast exception:

Screenshot of the error

  1. Calling the method that is supposed to work on the file and convert into an IPicture type variable:

In current scenario, this code does not execute.

I have tried in different ways to talk to this Component. I have tried latebinding.

following is the code which I am using for latebinding:

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 works, but only for a few steps, I can pass through the Open method, I can get the values from the properties, but in the last line, I receive an error that TargetInvocationException was unhandled by user code. I dont know what it means.

  1. Why is this error occuring?

Please note: I have tried using the component through Javascript block. It works fine.

Question 4: I have tried the same code snippets posted here in a winforms application. It works without any problem. this gets me thinking there is something wrong in my approach. Is there any special process needed to talk to a COM Component in an ASP.NET app?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事和酒 2024-12-12 03:58:55

更新:好的。我终于让这个 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:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

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

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

Update: OK. I have finally got this COM object to work, but some problem still remains. Some brilliant guy in some other forum(I dont remember now which one)asked me to check the ThreadingModel of the component, as it turns out it is set to Apartment. So I changed the code as following:

    ...
    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..
      }

Now this code works, but once in a while, I am getting a strange error while debugging, which states
AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

generally the app runs fine the first time I try to debug, but this error occures mostly on the second or third time I press f5 from my VS while the ASP.Net server is still running. and generally it goes away if I stop the server and run again. I think this problem is because of this new STA thread. Maybe I am not handling the new thread correctly. Or there is some other thing I should look into? Can someone point out whatshould I do under this circumstance?

Please Note: I dont know if this can be considered an answer or not, but I cant seem to edit my question here, and the comment has too short space... :-(

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文