IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Instance Word appelée depuis un serveur Datasnap


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut Instance Word appelée depuis un serveur Datasnap
    Bonjour

    Pour un besoin en interne, j'ai créé sur mon Windows un serveur Datasnap pour convertir des documents.
    Il s'agit principalement de convertir un docx en pdf.

    Le serveur reçoit le contenu du fichier source en base64 (envoyé par un site en PHP sur une VM linux).
    Il le décode et l'enregistre sur disque dans %temp%.

    Puis, je crée une instance de Word, je lui fais ouvrir le fichier et j'utilise SaveAs pour le convertir en pdf.
    Je referme Word et je charge le document pour le renvoyer au script PHP appelant qui décode le tout et l’affiche ou l'enregistre.

    Tout ça fonctionne très bien à un détail près. Ça prend beaucoup trop de temps.
    J'ai chronométré les phases d'exécution et je trouve en moyenne:

    • Instance Word créée en: 2000 ms
    • Document chargé en: 547 ms
    • Conversion terminée en: 4735 ms


    Pour le code, il est des plus simples:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    function InnerConvertDocxToPDF(var ContentFileToConvert: string): Boolean;
    var
      Word: Word_TLB._Application;
      Document: Word_TLB._Document;
      Unknown: IUnknown;
      T: Cardinal;
    begin
     
      T := GetTickCount;
     
      if (GetActiveObject(Word_TLB.CLASS_WordApplication, nil, Unknown) = MK_E_UNAVAILABLE) then
        Word := Word_TLB.CoWordApplication.Create;
      Word.Visible := False;
     
      Log('Instance Word créée en: ' + (GetTickCount - T).ToString);
     
      try
        try
          T := GetTickCount;
          Document := Word.Documents.Open(ContentFileToConvert, EmptyParam, EmptyParam,
          EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
          EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
          EmptyParam);
          Log('Document chargé en: ' + (GetTickCount - T).ToString);
     
          ContentFileToConvert := ChangeFileExt(ContentFileToConvert, '.pdf');
     
          T := GetTickCount;
          Document.SaveAs2(ContentFileToConvert, Word_TLB.wdFormatPDF,
          EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
          EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
          EmptyParam, EmptyParam, EmptyParam);
          Log('Conversion terminée en: ' + (GetTickCount - T).ToString);
     
          Document.Close(EmptyParam,EmptyParam,EmptyParam);
          Result := True;
        except on E: Exception do
          Result := False;
        end;
     
      finally
        Word.Quit(False, EmptyParam, EmptyParam);
        Word := nil;
      end;
     
    end;
    J'ai essayé une solution consistant à créer le serveur au démarrage de l'appli mais chaque appel au "service WEB" étant threadé, ça ne fonctionne pas (ou tout au moins, je n'ai pas réussi).

    Est-ce que vous voyez une solution, qui me permettrait d'accélerer un peu le processus ?

    Evidemment, si je pouvais créer mon instance de word une fois pour toute, je gagnerais déjà 2 secondes à chaque fois, ce qui serait déjà un gros mieux

    En question subsidiaire, j'ai du rater un truc sur COM.
    Même si j'ai un word ouvert sur mon poste, GetActiveObject ne le trouve pas et en crée un autre.
    Est-ce normal ???

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 628
    Billets dans le blog
    65
    Par défaut
    Bonjour,

    pour ce qui est de word je ne sais pas je n'ai jamais été très acoquiné aux produits MS ni aux TLB_xxxxx
    s'il s'était agit d'OpenOffice j'aurais proposé d'utiliser des instances en tant variables de session (voire globale ?)

  3. #3
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut
    Je ne connaissais pas la manipulation des sessions avec datasnap et j'ai cherché un peu et trouvé :



    La solution est sans doute là. Je vais investiguer de ce côté.

    Merci

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    Pour l'instance de Word via GetActiveObject
    Un Word lancé par son raccourci aura grande chance d'être en 64Bits, et celui par un programme Delphi compilée en 32Bits, sa version c'est quoi 32 ou 64 ?

    J'ai déjà utilisé GetActiveObject en Delphi et en PHP (oui PHP peut lancer un COM), cela capturait parfaitement l'instance déjà lancée
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut
    Le server datasnap est sur mon poste Windows 8 64 bits avec Office365.

    Mais il pointe apparemment sur un word en 32 bits. Bizarre ....

    "C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE"

    Pour ce qui est l'appeler en PHP, j'y avais pensé aussi.
    Le but étant d'avoir juste ce convertisseur sur un poste Windows, je ne ne voyais pas l'intérêt d'installer un wamp juste pour ça.

    Mon code d'appel en php me pose aussi quelques problèmes mais j'en parlerai sur le forum adapté si je ne trouve pas la solution.
    (problème de thread pour les curieux)



    Je suis finalement passé en mode "server" plutôt que session et le problème est résolu.
    Je n'ai plus qu'une seule instance de Word et la même est récupérée à chaque fois.

    Merci pour le coup de main

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Récupérer l'URI appelée depuis le serveur
    Par Damax dans le forum C++
    Réponses: 6
    Dernier message: 20/07/2013, 23h03
  2. timeout appel depuis Java vers serveur avec omniORB
    Par jeromemartin dans le forum CORBA
    Réponses: 1
    Dernier message: 12/07/2011, 15h24
  3. [ASP.NET 3.5] Appeller une variable serveur depuis un fichier js
    Par User.Anonymous dans le forum ASP.NET
    Réponses: 2
    Dernier message: 28/09/2009, 12h24
  4. Réponses: 10
    Dernier message: 24/05/2007, 11h14
  5. VB Word : appel d'une macro depuis l'extérieur
    Par pezz dans le forum VBA Word
    Réponses: 2
    Dernier message: 24/02/2005, 10h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo