Search code examples
c#.netimanage

Opening a document from Imanage in Word 2016


I am attempting to open an Imanage document, in MS Word, within a temporary test application (for debugging) to later copy over into an ActiveX control project. The error that is popping up is:

Exception thrown at 0x7618851A (msvcrt.dll) in w3wp.exe: 0xC0000005: Access >violation reading location 0x09801000.

If there is a handler for this exception, the program may be safely continued.

The error occurs when running the cmd.Execute line and I am unsure as to why I am getting the error.

    using IManage;
    using IMANEXTLib;
    using System;        

        namespace WebApplication3
        {
            public partial class WebForm2 : System.Web.UI.Page
            {
                IManDatabase imanagedatabase;
                IManDMS myDMS = new ManDMSClass();
        
                protected void Page_Load(object sender, EventArgs e)
                {
                    openImanageDoc("docNumber", "versionNumber", "server", "database", ReadOnly);
                }
                public void imanageLogin(string server, string database)
                {
                    try
                    {
                        IManSession session = myDMS.Sessions.Add(server);
                        IManWorkArea oWorkArea = session.WorkArea;
                        session.TrustedLogin();
        
                        foreach (IManDatabase dbase in session.Databases)
                        {
                            if (dbase.Name == database)
                            {
                                imanagedatabase = dbase;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
        
                public void openImanageDoc(string docNo, string versionNo, string server, string database, bool isReadOnly = true)
                {
                    IManDocument doc;
                    try
                    {
                        imanageLogin(server, database);
                        int iDocNo = int.Parse(docNo);
                        int iVersion = int.Parse(versionNo);
                        doc = imanagedatabase.GetDocument(iDocNo, iVersion);
                        openNRTDocument(ref doc, isReadOnly);
                        imanagedatabase.Session.Logout();
                        myDMS.Close();
                    }
                    catch (Exception Ex)
                    {
                        imanagedatabase.Session.Logout();
                        throw Ex;
                    }
                    finally
                    {
                        imanagedatabase = null;
                        myDMS = null;
        
                    }
                }
        
        
                public void openNRTDocument(ref IManDocument nrtDocument, Boolean isReadonly)
                {
                    OpenCmd cmd = new OpenCmd();
                    ContextItems objContextItems = new ContextItems();
        
        
                    objContextItems.Add("NRTDMS", myDMS);
                    objContextItems.Add("SelectedNRTDocuments", new[] { (NRTDocument)nrtDocument.LatestVersion });
                    objContextItems.Add("IManExt.OpenCmd.Integration", false);
                    objContextItems.Add("IManExt.OpenCmd.NoCmdUI", true);
        
                    cmd.Initialize(objContextItems);
                    cmd.Update();
                    cmd.Execute();
        
                }
            }
        }

Due to the nature of the error, I am presuming it is a configuration issue rather than a code error although I could be completely wrong as I am very new to programming.

I have found out that w3wp.exe is an IIS worker process created by the app pool but other than that I have no idea what the numeric code represents. Any help or advice is greatly appreciated.


Solution

  • The error is being raised by the OpenCmd instance because it is most likely trying to access resources such as local registry settings. It's not possible to do that in a web application, unless you host your code in a proprietary technology like ActiveX (which is specific to Internet Explorer)

    Actually, it is not appropriate for you to use OpenCmd here. Those type of commands (iManage "ICommand" implementations) are intended to be used in regular Windows applications that have either the iManage FileSite or DeskSite client installed. These commands are all part of the so-called Extensibility COM libraries (iManExt.dll, iManExt2.dll, etc) and should not be used in web applications, or at least used with caution as they may inappropriately attempt to access the registry, as you've discovered, or perhaps even display input Win32 dialogs.

    For a web app you should instead just limit yourself to the low-level iManage COM library (IManage.dll). This is in fact what iManage themselves do with their own WorkSite Web application

    Probably what you should do is replace your openNRTDocument method with something like this:

    // create a temporary file on your web server..
    var filePath = Path.GetTempFileName();
    // fetch a copy of the iManage document and save to the temporary file location
    doc.GetCopy(filePath, imGetCopyOptions.imNativeFormat);
    

    In an MVC web application you would then just return a FileContentResult, something like this:

    // read entire document as a byte array
    var docContent = File.ReadAllBytes(filePath);
    // delete temporary copy of file
    File.Delete(filePath);
    // return byte stream to web client
    return File(stream, MediaTypeNames.Application.Octet, fileName);
    

    In a Web Forms application you could do something like this:

    // set content disposition as appropriate - here example is for Word DOCX files
    Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    // write file to HTTP content output stream
    Response.WriteFile(filePath);
    Response.End();