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

Langage Delphi Discussion :

Erreur MAPI, composant TMAPIMail (smComponent)


Sujet :

Langage Delphi

  1. #1
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut Erreur MAPI, composant TMAPIMail (smComponent)
    Bonjour,

    Nouveau poste (W10) à installer hier et problème : un programme qui jusque-là fonctionnait correctement sur tous les autres postes n'arrive pas à envoyer les mails par MAPI !
    Au départ je me suis dit : "problème programme de mail avec aucune adresse par défaut" mais non, ce n'est pas la cause pour preuve un autre programme qui lui aussi envoi des mails par MAPI fonctionne, idem un nouveau programme de test basique aussi
    Plus dingue encore, j'ai utilisé l'unité de ce test basique dans le programme récalcitrant et le test basique ne fonctionne pas non plus

    Environnement programme D3, donc programme 32 bits, cible un poste Windows10 64 bits, le composant utilisé pour l'IMAP est un composant de smComponent TMAPIMail. Oui, c'est de la maintenance. L'erreur MAPI renvoyée est toujours un nombre positif mais jamais la même

    Vu les tests, difficile de mettre en cause le fait que ce soit un programme D3, que ce soit du 32 bits ou même le lecteur mail par défaut (Thunderbird) je donne ma langue au chat quant à la cause.

    Pour pallier cette erreur rapidement j'aimerais pouvoir envoyer les informations (destinataires, piecejointe, corps du message) à un autre programme (lancé par shellexecute ou autre) mais je n'ai pas la moindre idée de piste pour réaliser ça une idée ?

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    MAPI est une très vieille API qui est limitée et présente souvent des défaillances...son seul intérêt (quand elle fonctionne) c'est qu'il n'existe pas d'alternative simple pour tous les logiciels

    ceci dit, j'utilise maintenant une autre approche, tu composes ton mail, par exemple avec TidMessage, et au lieu d'utiliser TidSMTP pour l'envoyer, tu l'enregistres dans un fichier .eml sur lequel tu fais un ShellExecute.

    De plus, si tu ajoutes une entête X-Unsent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      idMessage1.ExtraHeaders.Add('X-Unsent: 1');
      IdMessage1.SaveToFile('test.eml');
    cela indique au client mail de l'ouvrir directement pour l'envoyer...sauf que évidemment Thunderbird ne gère pas cet attribut, sauf à ajouter une extension https://github.com/lieser/X-Unsent

    le gros avantage de cette approche c'est que ton mail peut contenir virtuellement n'importe quoi, du HTML, des pièces jointes, des tableaux en fait tout ce que peux contenir un mail...alors que MAPI c'est du texte brut avec éventuellement des pièces jointes

  3. #3
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    MAPI est une très vieille API qui est limitée et présente souvent des défaillances...
    Ben le programme l'est aussi, vieux. L'étrange est dans la défaillance unique avec ce programme mais pas avec un autre tout aussi vieux

    Intéressante ton approche mais qui dit Tidxxxxxx dit post Delphi 3 donc, inutilisable dans mon cas du moins à première vue.

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Ça avance, dans le sens où, maintenant j'ai une erreur "acceptable" :
    User cancelled request
    même si je n'en comprends pas la raison

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Peut-être qu'une sous-couche du TMAPIMail (smComponents, c'est comme du même éditeur smExport ou smImport : scalabium, car ça je pratique)

    Cela utilise une couche IP en dessous qui peut être pertubé par une autre lib IP dans le même programme (genre comme le GStack de Indy commun à plusieurs classes)
    Ou cela encapsule juste
    MAPISendMail, MapiLogOn

    Je vais surement m'intéresser par curiosité à MAPIReadMail prochainement

  6. #6
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Bonjour,
    @ShaiLetTroll a priori c'est juste une encapsulation des commandes que tu cites.
    J'ai donc essayé également de passé en direct avec MAPI : même effet, toujours un "user cancelled request" alors que l'unité dans un programme indépendant fonctionne
    La seule différence semble résider dans le fait que dans le programme indépendant la forme est la seule unité et que dans celui qui me pose soucis c'est une forme modale.
    Moult essais ce weekend ne m'ont pas permis de voir en quoi le fait qu'elle soit modale change la donne (sachant que tous les autres postes de l'entreprise s'en accommode à quelques différences près)

    Comme il s'agit d'un programme que je ne peux pas migrer (du moins dans l'immédiat) je songe passer par une commande ShellExecute d'un programme spécifique (puisque, isolé, l'envoi fonctionne) en lui passant les paramètres nécessaires : une adresse mail, le nom du fichier à ajouter en pièce jointe (<< ce qui fait que je ne peux utiliser emailto).


    Pour bien faire il faudra aussi que je mette en paramètre le texte du message mais ça je n'ai jamais tenté, est-il possible de passer un TStringList comme paramètre ?

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Avec un CreateProcess et un WM_DATA, tu peux envoyer une grosse chaine comme le Body
    La cmd doit être limite
    un LNK c'est 260
    ShellExecuteW c'est 2Ko et CreateProcess c'est 32Ko (cf lpCommandLine)

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    cet échange t'apporter peut-être des lumières

    https://forums.embarcadero.com/messa...ssageID=677226

  9. #9
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Si l'on met de côté le corps du message, créer un programme séparé (utilisable avec un ShellExecute) s'est avéré être l'option "payante".

    Toujours en utilisant l'unité SendMail des SMComponents
    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
    48
    49
    50
    51
    52
     
    unit EnvoiConfirmationU;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      MAPI, SendMail;
     
    type
      TFormMAPI = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      FormMAPI: TFormMAPI;
     
    implementation
     
    {$R *.DFM}
     
    procedure TFormMAPI.FormCreate(Sender: TObject);
    const BreakLine = #13+#10;
    begin
      with TMAPIMail.Create(Self) do
       begin
         Subject:='CONFIRMATION DE COMMANDE ';
         if ParamCount>=1 then Subject:=Subject+ParamStr(1);
         if ParamCount>=2 then Recipients.Append(ParamStr(2));
         if ParamCount>=3 then Attachments.Add(ParamStr(3));
         Body:='Chère cliente, cher client,'+BreakLine+BreakLine+
               'Nous vous remercions pour cette commande dont vous trouverez ci-joint la confirmation.'+BreakLine+
               'Merci de bien vouloir la vérifier et de nous informer, sous huitaine, de tout point non conforme.'+BreakLine+
               BreakLine+'Bien cordialement.'+BreakLine+BreakLine+BreakLine;
         Body:=Body+      
               'Dear customer,'+BreakLine+BreakLine+
               'We thank you for this order. Please see it attached.'+BreakLine+
               'Please check all the info and inform us if there is any mistake.'+BreakLine+BreakLine+
               'Best regards.'+BreakLine+'²';
         Send;
         if LastError<>SUCCESS_SUCCESS
           then MessageDlg('² MAPI Envoi non réussi'+#13+#10+'Erreur :'+MAPIErrorDescription(LastError), mtError, [mbOK], 0);
         Free;
       end;
       Application.Terminate;
    end;
     
    end.
    Une première compilation posait le même problème alors qu'un programme test précédent fonctionnait. En regardant la taille des deux exécutables une vingtaine de K contre 217 pour le programme test, j'en ai déduit que j'avais compilé avec les paquets. Une seconde compilation sans les paquets et le programme fonctionne.

    Malgré cette nouvelle piste, une tentative de re-compilation du programme principal n'a rien donné, je me suis donc résolu à mettre un ShellExecute qui lui déclenche bien le MAPI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure TCdeForm.TestMAPI1Click(Sender: TObject);
    begin
     ShellExecute(Handle, Pchar('open'),
                  pchar(ExtractFilePath(ParamStr(0))+'EnvoiConfirmation.exe'),
                  Pchar('Test'+' '+'mon.adresse@maboutMail.com'),
                  nil,
                  SW_HIDE);
    end;
    dans mon programme, l'unité d'envoi du PDF, j'ai simplement changé le traitement de l'erreur

    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
     
     aMapi:=TMapiMail.Create(Self);
     try
      aMapi.Subject:='CONFIRMATION DE COMMANDE '+SAnnee.text+'-'+SNumero.Text;
      aMapi.Attachments.Add(PReport1.FileName);
      aMapi.body:=MsgTexte.text;
      aMapi.Recipients.Append(MailClient.Text);
      amapi.Send;
      if aMapi.LastError<>EMAIL_OK
       then begin
        // changement 03/02/2020
        ShellExecute(Handle, Pchar('open'),
                      pchar(ExtractFilePath(ParamStr(0))+'EnvoiConfirmation.exe'),
                      Pchar('"'+aMapi.Subject+'" '+MailClient.text+' "'+PReport1.FileName+'"'),
                      nil,
                      SW_HIDE);
     
       end;
     finally
       aMapi.Free;
     end;
    @Paul, Merci, déjà trouvée, je n'avais pas fait suite sur cette discussion, étant donné que mon programme est en D3 (donc pas d'unicode à l'horizon)

    Pour ce qui est du corps, plutôt que de passer un TStringList, je vais passer un nom de fichier texte (un 4° paramètre) plus simple pour de de vieux programmes et ainsi je n'aurais pas de problèmes de taille de paramètres.
    Je considère donc le sujet comme résolu (même si la cause reste "trouble")

  10. #10
    Membre actif Avatar de oneDev
    Homme Profil pro
    dilettant
    Inscrit en
    Mars 2019
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : dilettant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2019
    Messages : 214
    Points : 223
    Points
    223
    Par défaut
    J'ai déjà eu ce problème. Cela venait d'une mise à jour Windows qui avait supprimé 2 clé dans le registre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    REG ADD "HKLM\SOFTWARE\Microsoft\Windows Messaging Subsystem" /V MAPI /T REG_SZ /D "1"
    REG ADD "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows Messaging Subsystem" /V MAPI /T REG_SZ /D "1"

  11. #11
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    Intéressant, il va falloir que je mette la main sur le poste pour vérifier si les clés existent
    cependant je te ferais remarquer que:
    - sur cette même machine, un programme indépendant avec le même composant (a priori compilé sans les paquets) , n'a aucun souci d'exécution.
    - un second programme indépendant (celui que j'utilise comme palliatif), compilé avec paquets ne fonctionnait pas mais, compilé sans les paquets fonctionne.

  12. #12
    Membre actif Avatar de oneDev
    Homme Profil pro
    dilettant
    Inscrit en
    Mars 2019
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : dilettant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2019
    Messages : 214
    Points : 223
    Points
    223
    Par défaut
    Cela ne semble effectivement pas être le même problème.
    Mais, j'ai tellement galéré à trouver d'où venait mon problème, que je préfère le partager ici.

  13. #13
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 119
    Points : 41 252
    Points
    41 252
    Billets dans le blog
    63
    Par défaut
    @oneDev C'est tout à ton honneur.
    Je n'ai pas encore eu accès au poste "coupable" je ne peux donc pour l'instant confirmer que les clés registres y sont, j'y ferais un petit tour entre 12h et 14h via logmein.
    Cependant, maintenant que le "dérivatif" fonctionne, je ne pourrais tester si l'ajout des deux clés aurait résolu le problème.

    [EDIT] effectivement ces deux clés n'existent pas sur le poste (neuf)

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 03/03/2011, 10h42
  2. [Lazarus] [Win XP][TCOMPORT] Erreur SIGFPE composant ComTerminal
    Par prc_600 dans le forum Lazarus
    Réponses: 3
    Dernier message: 27/07/2009, 20h35
  3. Message d'erreur: Un composant ActiveX ne peut pas créer un objet
    Par amnass dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 22/05/2009, 07h12
  4. Erreur du composant WebPart
    Par develop2007 dans le forum SharePoint
    Réponses: 1
    Dernier message: 03/08/2008, 22h50
  5. Traitement erreur IdSocketError Composant Indy
    Par goldkey dans le forum Composants VCL
    Réponses: 1
    Dernier message: 05/06/2005, 12h11

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