Automation-Methode nicht gefunden

30. September 2009 10:54

Hallo.

Folgendes Szenario (ähnlich wie Freddy es in seinem Blog vor einigen Monaten geschildert hat): Eine Datei soll vom RTC auf den Server transferiert werden. Dazu werden zwei Automation-Objekte verwendet, die die Datei base64 codieren bzw. decodieren.

Folgender Quellcode in NAV:

Code:
  // create necessary automations
  IF (ISCLEAR(Decoding)) THEN
    IF NOT (CREATE(Decoding, TRUE, FALSE)) THEN
      ERROR(txtAutomationInstanciationErr, 'Decoding');

  IF (ISCLEAR(Encoding)) THEN
    IF NOT (CREATE(Encoding, TRUE, TRUE)) THEN
      ERROR(txtAutomationInstanciationErr, 'Encoding');

  // open file via automation and store in base64String
  // what happens on error in 'Encoding.encodeFile'?
  base64String.ADDTEXT(Encoding.encodeFile(sourceFile));

  // Decode the base64 encoded file into the tmpFile
  ErrorCode :=  Decoding.decodeToFile(base64String, targetFile);


Auf dem Client wird die Automation Encoding erstellt, die für das Übersetzen in einen String zuständig ist, auf dem Server die, die den String wieder zurückübersetzt. Dazwischen wird der String in einen BigText übersetzt. Kompiliert wird das ganze problemlos.

Während der Laufzeit kommt es aber zu folgender Fehlermeldung:

Meldung für C/AL-Programmierer: Fehler beim Aufruf von Member 'decodeToFile': Die Methode "DropZone.Automations.Base64Decoding.decodeToFile' konnte nicht gefunden werden.

D.h. das Encoding funktioniert noch...

Das hier ist der .NET-Code (leicht gekürzt):
Code:
namespace DropZone.Automations
{

    [Guid("B1E4786B-F32E-481c-AF6C-4004D6E67864")]
    public interface IDecoding
    {
        [DispId(1)]
        int decodeToFile(StringBuilder base64String, string filename);
    }

    /// <summary>
    ///
    /// </summary>
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("2FB58F9C-9E3B-48b0-8841-4B105D434E67")]
    public class Base64Decoding : IDecoding
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="base64String"></param>
        /// <param name="filename"></param>
        /// <returns></returns>
        public int decodeToFile(StringBuilder base64String, string filename)
        {
            try
            {
                System.IO.Directory.CreateDirectory(filename.Substring(0,filename.LastIndexOf('\\')));
                System.IO.File.WriteAllBytes(filename, Convert.FromBase64String(base64String.ToString()));
                return 0;
            }
            #region ExceptionHandling
           [...]
            #endregion
        }
    }
}

Ich habe schon versucht, alle evtl. bestehenden älteren Versionen der dll zu entfernen, die dll in den GAC zu laden, diese Klasse in eine eigene Dll auszulagern. Alles ohne Erfolg.

Ich wäre sehr dankbar für weitere Vorschläge.

Re: Automation-Methode nicht gefunden

30. September 2009 11:20

Hallo PhilThome,

dein Quelltext ist leichter zu lesen und zu verstehen, wenn du ihn zwischen so genannte Code-Tags setzt. Insbesondere deine Formatierungen werden so auch beibehalten.

Daher bitten wir dich, vor und nach deinem Quelltext diese Code-Tags einzufügen. Beispiel:
(Ich habe dieses für dich bereits gemacht)

[code]Dein Quelltext[/code]

Gruß, Mikka
MSDynamics.de-Team

Re: Automation-Methode nicht gefunden

30. September 2009 11:41

Nun, ich bin kein .NET Profi.
Ich beschreibe dir aber gerne wie ich mein Problem gelöst habe (ich hatte ähnliches mit einer DLL, die mit einem Webservice Kommunizieren sollte).

Die DLL mußte ich mit regasm registrieren (nicht mit regsvr32) :!:
(der Aufruf sollte aus dem Verzeichnis in der die DLL liegt erfolgen, nicht aus dem verzeichnis wo die Datei "regasm.exe" liegt!)

Wichtig:
Wenn eine Komonente 1 x Registriert war und eine neue Verison installiert werden soll, immer vorher "Unregister" ausführen.

Nach dem Registrieren, musste ich zwei Explorerfenster nebeneinander öffnen und die tlb bzw dll Datei per "Drag & Drop" (nicht kopieren und einfügen!) vom einen Verzeichnis in das GAC-Verzeichnis (z.B. C:\WINNT\assembly) "ziehen" (alles andere hat keinen Erfolg gebracht!).

:greenarrow: Alles andere hat nicht funktioniert. Die DLL waren zwar registriert, jedoch nicht in Navision "sichtbar" (führte zu der Beschriebenen Fehlermeldung)

Anbei ein Skript zum Registieren de DLL.
Anmerkungen zum Script:
1. Die Dateiendung in .cmd ändern
2. Die Platzhalter [hier Dein Verzeichnis eintragen], [DeineDLL] und [DeinTLBName] gegen deine Werte tauschen
3. Möglicherweise variiert das Verzeichnis wo regasm liegt, ggf. anpassen
4. Navision, Excel Word und co. alle Schliessen zum Registrieren / Un-Registrieren

**Edit by Mikka**
Hab die Datei noch angehangen, die Fehlte noch!
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: Automation-Methode nicht gefunden

9. Oktober 2009 11:04

Hallo,

danke für den Hinweis mit dem GAC. Das werde ich ins Auge fassen, weil die Registrierung bzw. die Intanziierung von Automations in NAV nicht immer so sauber läuft, wie man das erwartet.

Die Ursache für den beschriebenen Fehler liegt jedoch an anderer Stelle. Nach einigem Rumprobieren ergab sich folgendes: Der NAV Server hat mittlerweile Schwierigkeiten mit der Erkennung eines StringBuilders als Parameter. Ersetzt man diesen durch ein Object und castet das in der Methode selbst in einen String funktioniert der Aufruf:

Code:
        public string decode(Object base64String, string filename)
        {
            try
            {
                System.IO.Directory.CreateDirectory(filename.Substring(0, filename.LastIndexOf('\\')));
                System.IO.File.WriteAllBytes(filename, Convert.FromBase64String(base64String as String));
                return "SUCCESS";
            }
            catch (Exception exc)
            {
                return exc.ToString();
            }


In dem Zusammenhang noch zu erwähnen: auch überladene Funktionen werden vom RTC nicht mehr korrekt verarbeitet.