Using ATL COM in NAV2009

havhav Member Posts: 299
edited 2008-11-28 in NAV Three Tier
Hi All,

I have my add-on integrated with NAV5.0 W1. The add-on is created using ATL COM component(unmanaged code). I am now trying to upgrade to NAV2009.

The add-on works fine with NAV2009 Classic Client but not with Role Tailored Client.

The transformation process is carried out successfully. But when i run Role Tailored Client and try to access the integrated functionality, it crashes by closing the server connection.

I have tried various alternatives but no luck.

Does any one have an idea as to why Role Tailored Client fails to call the COM interface functions?

Eg:-

Codeunit : ApplicationManagement

CompanyOpen()

{ ..............

WMI.Init() //WMI --> Variable of type WM Interface

}

Codeunit: WM Interface

Init()

{ ............

CREATE(WM) //WM --> Automation variable of type ATL COM

WM.Initialize(...) //Initialize() --> COM Interface function

........

}

Thanks,

Hemant
Regards,
Hemant
MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)

Comments

  • stomdahlstomdahl Member, Microsoft Employee Posts: 12
    Hi Hemant,
    Does the AL code fails to create the automation object, or is it the actual method call that terminates the connection?
    Maybe you could take a look in the application eventlog for more information.

    What does the method signature for the WM.Initialize(...) method looks like. Any optional arguments?

    Thanks,
    Stefan
  • havhav Member Posts: 299
    Hi Stefan,
    Thanks for your help.

    Earlier it threw error for creating automation variable. So i copied COM dll to NAS or RTC and registered it.
    Then after i didn't receive this error.
    Hence i assume that the automation variable is created properly.

    I think it crashes when it calls the interface function of the COM dll.

    My application log shows two errors:
    1. A runtime exception was detected. Details follow.
    Message: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

    2. Type: Microsoft.Dynamics.Nav.Types.NavConnectionLostException
    Message: The connection to the server has been lost. The application will close.

    It seems that the connection is lost during function call.

    In the method call WM.Initialize(...) , the ... indicates list of arguments which i have not mentioned.

    Regards,
    Hemant
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • stomdahlstomdahl Member, Microsoft Employee Posts: 12
    Hi Hemant,
    I sounds to me like your automation object is communicating with another server somewhere? Maybe across firewalls? Are you using certificates?
    Maybe you could give some details on your scenario, and the method signature would also be nice to have.
    Thanks,
    Stefan
  • ara3nara3n Member Posts: 9,255
    edited 2008-10-03
    Are you running the service tier and client on same box, different box? have you registered the COM component on both boxes if they are different?

    Create (automationobjectm,boolean) has a new parameter in 2009

    Create (automationobject,boolean,boolean); True instantiates it at the client.
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • stomdahlstomdahl Member, Microsoft Employee Posts: 12
    The method takes 3 arguments: Create (automationobject,newServer,clientTier);

    So: Create (automationobject, True, True); instantiates it at the client tier.
  • havhav Member Posts: 299
    The automation object does communicate with a hardware device which is connected on a separate server. The server IP is shared with WPC. Although, Classic client runs properly.

    The method Init() is as below

    IF ISCLEAR(WM) THEN //WM COM instance does not exist
    BEGIN

    //Read Preference setup for the current company
    GetPreferences();

    //Set global variables required to initialize WM
    DataFolder := WMPreference.DataFolder; //WM data directory
    User := USERID; //Navision current User name
    SupervisorPassword := WMPreference.SupervisorPassword; //WM Supervisor user's password
    LanguageCode := GetWMLangDir(); //WM resource language directory

    //Create a mew WM COM instance
    OK := CREATE(WM, TRUE);
    IF OK = FALSE THEN ERROR(TEXT000, 'WM');

    //Initialize and login WM with current Navision user and language
    WM.Initialise(DataFolder, User, SupervisorPassword, LanguageCode); Retval := WM.ErrorCode;

    IF Retval <> 0 THEN //WM initialization failed
    BEGIN
    CLEAR(WM); //Destroy WM COM instance
    ERROR(TEXT008); //Display error message and terminate
    END;
    END;

    Note that i have used TRUE in CREATE() fn.

    The fn. Initialise() is a COM interface fn. It initializes & logins into another application WM which is our home product. It uses h/w security during login.

    I am using the service and client tiers on same box.
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • ara3nara3n Member Posts: 9,255
    You need to change CREATE(WM, TRUE);

    to CREATE(WM, TRUE,TRUE);
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • havhav Member Posts: 299
    Changing CREATE(WM, TRUE) to CREATE(WM,TRUE, TRUE) results into compile time error saying CREATE() accepts max. 2 arguments.
    Note that i am using NAV2009 CTP3 version.
    Has this fn. changed in Marketing Beta.
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • kinekine Member Posts: 12,562
    Yes, it changed. Marketing Beta is CTP4 with many new things...
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • havhav Member Posts: 299
    From the above i understand that automation for WM add-on is not possible with NAV2009 CTP3. I think this must be case with other automation as well.

    I have yet not looked at NAV2009 Marketing Beta. I still need to download.

    In a nutshell, i will have to redo my integration with Beta. :)

    Thanks for all your support,
    Hemant
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • WaldoWaldo Member Posts: 3,412
    Indeed.
    I was struggling with WaldoNavPad myself in CTP3, logged the case and got confirmed from MS that it was not possible (yet). In CTP4 - no problem! :)

    Eric Wauters
    MVP - Microsoft Dynamics NAV
    My blog
  • havhav Member Posts: 299
    Hey, i am facing the same problem again while integrating my add-on with NAV2009 release version.

    I am unable to use CREATE() fn. with 3 arguments. The C/SIDE reference guide of NAV2009 help shows
    Ok :=] CREATE(Automation [,NewServer])
    I am not sure where to look for CREATE() fn. with 3 arg's.
    Further i referred "NAV5_0_Implementations_Recommendations.pdf' which states below details reg. COM:
    Both Clients support Automation. All COM interaction will take place at Service Tier. IF the COM is a dll integrating other application then it can run on Classic Client but it will not run on RTC because of Service-Tier architecture.
    In order to run this dll on RTC, the integration needs to be redesigned by converting
    it to Webservice. The Client can call the webservice.


    Does this mean that i have to transform my COM dll to a Webservice?

    Pls resolve.

    Thanks,
    Hemant
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • kinekine Member Posts: 12,562
    No, it means that in most cases you will need to find another way for solution (and one way is to use WebServices...). But all depends on what you are doing with this DLL...
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • WaldoWaldo Member Posts: 3,412
    Indeed, it all depends on the DLL. The WaldoNavPad for example works perfectly on NAV2009 :).

    If you're integrating, you might be wanting to use web services ...

    Eric Wauters
    MVP - Microsoft Dynamics NAV
    My blog
  • freddy.dkfreddy.dk Member, Microsoft Employee Posts: 360
    Both Clients support Automation. All COM interaction will take place at Service Tier. IF the COM is a dll integrating other application then it can run on Classic Client but it will not run on RTC because of Service-Tier architecture.
    In order to run this dll on RTC, the integration needs to be redesigned by converting
    it to Webservice. The Client can call the webservice.
    This sounds like the recommendation we made before we (after CTP3) decided to support Client Side COM, and it isn't true anymore.

    In NAV 2009 OCX'es will always be loaded on the client tier and COM objects can be loaded on service or client tier based on a 3rd parameter.

    You are right that the documentation in NAV_ADG.CHM for CREATE isn't updated - but all the people on this thread who are referring to a 3rd parameter is right - just use it.

    I am not sure however that your problem is related to Client Side COM. I think the timeout and the NavServerConnection are related to the ServiceTier crashing and then the client fails with a timeout and a connection lost (I have seen that a number of times).

    A question you need to ask yourself - is the datafolder on the Client machine or on the Service Tier (do all clients need this installed or will you run it centrally).
    If you run it centrally - then you need these directories to be located under the Service Tier directory somewhere - as the Service Tier normally won't have permissions to write in any directory on the server.

    What are the data and language folder names?

    (BTW - you can a sample on my blog on how to use Client side COM - but it really is just the 3rd parameter = TRUE).
    Freddy Kristiansen
    Group Program Manager, Client
    Microsoft Dynamics NAV
    http://blogs.msdn.com/freddyk

    The information in this post is provided "AS IS" with no warranties, and confers no rights. This post does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion.
  • havhav Member Posts: 299
    I tried using the 3rd parameter as TRUE in CREATE(). It compiled without error.
    However when i tried running RTC it threw a big error box at startup. Refer attached "Error1.GIF" file.
    It seems that the error is generated for my codeunit containing Init() fn. (refer my earlier post in this thread) which is called at NAV login.
    I tried opening 'Codeunit9012912.cs' file and analysed the lines for which the error is displayed.
    Eg:- Line 1472 contains below code:
    // Description := ITEM.Description + ' ' + FORMAT(ITEM.Width, 0, 1) + 'x' + FORMAT(ITEM.Height, 0, 1); description = new NavText(100, iTEM.InvokePropertyGet<String>(@Description)+@ +NavFormatEvaluateHelper.Format(iTEM.InvokePropertyGet<Double>(@Width), 0, 1)+@x+NavFormatEvaluateHelper.Format(iTEM.InvokePropertyGet<Double>(@Height), 0, 1));
    The col. 92, 123 etc of the above code line refers to FORMAT() fn. that is being used.

    If you look at the commented code above then the variable Description is assigned a concatenated string comprising of three fields viz, Description, Width and Height of the ITEM COM.

    Has the FORMAT() fn. got changed in NAV2009?

    Regards,
    Hemant
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • freddy.dkfreddy.dk Member, Microsoft Employee Posts: 360
    It looks like you ran into a bug :(

    I just tried this myself and this
    result := FORMAT(FkCOMtest.test,0,1);
    
    fails with the same error you got.

    and this
    d := FkCOMtest.test;
    result := FORMAT(d,0,1);
    
    works, where d is a local variable of type decimal.

    The compiled C# code for the new construct looks like:

    // d := FkCOMtest.test;
    d = ALCompiler.ToDecimal(PFkCOMtest.InvokePropertyGet<Double>(@test));
    // result := FORMAT(d,0,1);
    result = new NavText(30, NavFormatEvaluateHelper.Format(ALCompiler.ToNavValue(d), 0, 1));

    So I guess the compiler needs to insert a ALCompiler.ToDecimal() around a double from COM components.
    I will file this as a bug - in the meantime, you will need to use this workaround.
    Freddy Kristiansen
    Group Program Manager, Client
    Microsoft Dynamics NAV
    http://blogs.msdn.com/freddyk

    The information in this post is provided "AS IS" with no warranties, and confers no rights. This post does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion.
  • havhav Member Posts: 299
    I tried your workaround and finally all errors vanished :)
    Thanks a lot.

    Infact i had to use this workaround at all places where a COM property of type double and short is used. Note that there is a bug for short data type also.

    One more bug that i found was with CurrForm.ACTIVATE. During Form Transformation it got replaced with CurrPage.ACTIVATE. I had to comment this since ACTIVATE is not a member of CurrPage.

    Well, now when i run RTC, it flags a message "The Server has requested to run xxxxxxx class on your Client." at startup. The message has three options:
    1. Allow this time, but ask again.
    2. Always allow.
    3. Never allow.

    If i press Cancel on this dialog, it gives error "The automation variable could not be created". Note that this error is displayed from my code when it fails to create the automation object. So far its fine.
    However if i select option 1 above and press OK, it crashes with standard debug exception dialog. If i click Debug on this dialog, nothing happens.
    It does not even open the debugger!

    One thing is sure that the automation object is created and the interface function WM.Initialize() is getting called at startup. This i can assure you since a dummy dialog which i show (not display) in this function is seen before the crash.

    I think some non-supportive feature is causing the problem in RTC eventhough the same works fine in Classic client.

    Is any of the below not supported in RTC?
    a. Showing ATL dummy dialog.
    b. Reading local hardware device to pass security lock of Third party application.
    c. Displaying splash screen of Third party application.
    d. Connecting to SQL db. of Third party application.
    Note that all above are the steps executed when WM.Initialize() is called at startup.

    I am not sure what is causing problem untill i debug.

    Do you know how to debug in RTC?

    Regards,
    Hemant
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • freddy.dkfreddy.dk Member, Microsoft Employee Posts: 360
    Thanks for the comment about short - I will include that in the bug (and ask them to include a test for all the supported data types).

    None of the things you describe shouldn't be allowed in a Client Side COM object.
    In a Server Side COM object (running as a service) - you cannot display any UI - it will probably throw an exception - but since you get the exception dialog I am assuming that you are running Client Side.

    My colleague Claus Lundstrøm posted a blog on how to debug the Service Tier some time ago

    http://blogs.msdn.com/clausl/archive/2008/10/14/debugging-in-nav-2009.aspx

    Note that in your case you are not trying to debug application code - you are trying to debug your COM object.
    I am assuming that your COM object is written in C# or VB.net (I haven't tried this with anything byt C# myself)
    The way to do this is to load the solution (your COM object) into Visual Studio and then select Tools -> Attach to process - and attach your debugger to the running Role Tailored Client (Microsoft.Dynamics.Nav.Client.exe - not the service tier as you would do when debugging application code) - set a breakpoint in your WM.Initialize and run your code in the Role Tailored Client - then your debugger should catch it (even though the COM object isn't loaded at the time you attach to the process).

    Is this confusing?

    Maybe I should do a couple of video recordings of how to debug the various things and post those on my blog?

    Note that you need a VS Professional (Express cannot attach to process).
    Freddy Kristiansen
    Group Program Manager, Client
    Microsoft Dynamics NAV
    http://blogs.msdn.com/freddyk

    The information in this post is provided "AS IS" with no warranties, and confers no rights. This post does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion.
  • havhav Member Posts: 299
    Thanks for your response.
    I still need your support/guidance in concluding the upgrade of my integration to NAV2009.

    The inputs that i can give you related to integration is:
    1. The integration is provided using COM dll which serves as a bridge between third party application and NAV.
    2. The COM dll is written using VC++ having additional dependencies of the third party application modules.
    3. The integration in NAV provides link to invoke third party application specific UI via COM and perform processing on both sides. The application specific UI is either a dialog or notebook or some batch process output.
    4. The third party application is written using C, C++, VC++, C# etc.

    The integration works fine on NAV2009 Classic client after upgrading from NAV5.0 W1 SP1.
    It crashes on NAV2009 Role Tailored Client even after using the 3rd argument as TRUE with CREATE() fn.

    The querries that i am thinking of in order to migrate to NAV2009 is
    --> Will the existing integration work on RTC?
    --> Does any workaround exists wherein i can manipulate and avoid redesigning of COM?
    --> Is Webservice a substitute to my COM integration?

    So far i have a feeling that i have to replace COM with WebService but still i think that i will not be able to invoke any third party application UI from a service.

    Please guide me and let me know how should i resolve this.

    Regards,
    Hemant
    Regards,
    Hemant
    MCTS (MB7-841 : NAV 2009 C/SIDE Solution Development)
  • freddy.dkfreddy.dk Member, Microsoft Employee Posts: 360
    Will the existing integration work on RTC?
    Does any workaround exists wherein i can manipulate and avoid redesigning of COM?
    Hard to say, what happens - whether you run into a bug or a limitation or something you can change in the App. I have seen COM components, which was trying to overlay windows in the Client - that will of course not work, as the Client is totally rewritten, but the majority of things should work.
    Is Webservice a substitute to my COM integration?
    It doesn't sound like it - in Web Services, the consumer is in control and the Web Service listener is inactive until you connect to it and start doing things. It sounds like you want to call out from NAV.
    Freddy Kristiansen
    Group Program Manager, Client
    Microsoft Dynamics NAV
    http://blogs.msdn.com/freddyk

    The information in this post is provided "AS IS" with no warranties, and confers no rights. This post does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion.
Sign In or Register to comment.