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.
- I am referencing the DLL in my solution.
- 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:
- 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, objCSVie开发者_Go百科werLateBound, 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.
- 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?
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... :-(
精彩评论