2011-09-16 108 views
0

我想在我的asp.net web應用程序中使用COM組件。在這個組件中,我傳遞存儲在我的服務器目錄中的圖像文件的路徑,並且此組件返回給我一個IPicture數據類型。ASP.NET和COM互操作

以下是我正在經歷的步驟,我在每個步驟發佈我的問題,以使其保持特定。

  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:這是錯誤occures: - 當代碼來這條線,我收到InvalidCast異常:

Screenshot of the error

  • 調用應該在文件上工作的方法並將其轉換爲IPicture類型變量:
  • In cur租用方案,此代碼不會執行。

    我嘗試過用不同的方式與此組件進行對話。我嘗試了晚結。

    以下是我使用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作品,但只有幾步,我可以通過Open方法,我可以從屬性的值,但在最後一行中,我收到一個錯誤,指出TargetInvocationException未被用戶代碼處理。我不知道它是什麼意思。

    1. 爲什麼會出現此錯誤?

    請注意:我嘗試過使用通過Javascript塊的組件。它工作正常。

    問題4:我已經嘗試了在winforms應用程序中發佈的相同代碼片段。它工作沒有任何問題。這讓我覺得我的方法有問題。在ASP.NET應用程序中討論COM組件需要什麼特殊過程?

    回答

    0

    更新:好的。我終於得到了這個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線程。也許我沒有正確處理新的線程。或者我應該研究一些其他的東西?有人能指出在這種情況下我該做什麼?

    請注意:我不知道這是否可以被認爲是一個答案或沒有,但我似乎無法在此編輯我的問題,和註釋有太多短空... :-(