Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Pages: 1
Bonjour,
Nous utilisons aujourd'hui un OLE InternetExplorer.Application pour envoyer des fichiers HTML via powerbuilder (version 12.1).
Nous avons souvent des lenteurs sur notre serveur de production que nous avons du mal à expliquer (pb deproxy ?pb de internet explorer trop vieux ?).
Je voudrais essayer avec un autre navigateur, mais est-ce qu'on à un autre ole qui pourrait nous permettre de faire la même chose ? (le serveur de production est encore en windows 2003)
Merci d'avance,
Hors ligne
wazou1812 a écrit:
Bonjour,
Nous utilisons aujourd'hui un OLE InternetExplorer.Application pour envoyer des fichiers HTML via powerbuilder (version 12.1).
Nous avons souvent des lenteurs sur notre serveur de production que nous avons du mal à expliquer (pb deproxy ?pb de internet explorer trop vieux ?).
Je voudrais essayer avec un autre navigateur, mais est-ce qu'on à un autre ole qui pourrait nous permettre de faire la même chose ? (le serveur de production est encore en windows 2003)
Merci d'avance,
Bonjour,
Pour palier à ce problème, il serait peut être possible d'utiliser msxml2.xmlhttp ( ICI )
Est-ce que quelqu'un a déjà utilisé cela pour faire du transfert en https ?
Auriez-vous des exemples de codes ?
Merci d'avance,
Hors ligne
Salut, ta notion d'envoi via IE.Application (qui est plus un contrôle navigateur pour moi) est un peu floue.
Est-ce que ton envoi de fichier actuel passe par un champ "file" dans un formulaire html ?
Pourrais-tu décrire ce que tu veux faire au final ? (l'utilisation d'un contrôle ole n'est peut-être pas la meilleure solution)
Hors ligne
seki a écrit:
Salut, ta notion d'envoi via IE.Application (qui est plus un contrôle navigateur pour moi) est un peu floue.
Est-ce que ton envoi de fichier actuel passe par un champ "file" dans un formulaire html ?
Pourrais-tu décrire ce que tu veux faire au final ? (l'utilisation d'un contrôle ole n'est peut-être pas la meilleure solution)
Bonjour,
Voici par exemple ce que nous avons , du xml imbriqué dans du html.
Le tout fonctionne très bien sur nos postes de travail, mais pas sur notre serveur de production ou la partie envoi des fichiers est parfois très très long, sans explication.
Nous avons le même proxy sur nos postes que sur le serveur de production.
La seule chose qui change, c'est la version de IE.
if not isvalid(IE) then IE = CREATE OLEObject IE.ConnectToNewObject("InternetExplorer.Application") end if IE.left=200 IE.top=200 IE.height=400 IE.width=400 IE.menubar=0 IE.toolbar=1 IE.statusBar=0 IE.goHome //IE.visible=0 // non visible IE.visible=1 // visible DO WHILE IE.busy LOOP IE.document.Open IE.document.WriteLn("<HTML>") IE.document.WriteLn("<BODY>") IE.document.WriteLn("<form name='toto' enctype='multipart/form-data' action='https://toto.toto.com/service/transaction/cxml.asp' method='POST' ID='totoForm'>") IE.document.WriteLn("<input type='hidden' name='cXML-urlencoded' value=''></FORM>") IE.document.WriteLn("</BODY>") IE.document.WriteLn("</HTML>") IE.document.Close //on remplis le corps du fichier avec le contenu du fichier xml IE.document.Forms("totoForm").elements[0].value = i_PBDOM_DOCUMENT_SHIP.SaveDocumentIntoString() //et on soumet le fichier via internet explorer IE.document.Forms("totoForm").Submit() // attente que le fichier soit transféré. DO WHILE IE.Busy Yield () LOOP ////deconnection d'internet explorer IE.Quit() IE.DisconnectObject() DESTROY IE
Hors ligne
Mouais, plutôt que d'introduire une dépendance incertaine sur ton serveur envers IE en passant par un OLE, je te propose d'envoyer directement les données avec PB, sans IE.
Les 2 méthode GET et POST sont supportées via l'objet standard inet et les méthodes GetURL() et PostURL()
PostURL est (relativement) documenté mais j'ai passé un petit moment à chercher comment gérer le multipart...
Pour pouvoir recevoir la réponse du serveur, il faut dériver un objet (tout simple) de InternetResult et surcharger la méthode InternetData() juste pour sauver les données reçues. Tout le reste tient dans 1 méthode
Objet n_inet
forward global type n_inet from internetresult end type end forward global type n_inet from internetresult end type global n_inet n_inet type variables private: blob ibl_data end variables forward prototypes public function integer internetdata (blob data) public function string getstringdata () end prototypes public function integer internetdata (blob data); ibl_data = data return 1 end function public function string getstringdata (); return string(ibl_data, encodingansi!) end function on n_inet.create call super::create TriggerEvent( this, "constructor" ) end on on n_inet.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
La méthode qui envoie les données comme si elles provenaient d'un formulaire (il y a plus de commentaires que de code )
Blob lbl_content, lbl_request String ls_headers, ls_url, ls_request, ls_example String ls_bound, ls_boundid Long ll_leng Integer li_rc inet l_inet n_inet l_ir ls_url = "http://www.monserveur.com/mon/service.html" // <=== le paramètre "action" de ton form //quelque données de test, tu peux utiliser ici i_PBDOM_DOCUMENT_SHIP.SaveDocumentIntoString() ls_example = '<bidon><child id="1">some thing</child><child id="2">another thing</child></bidon>' //détermine la "borne" de données ls_boundid = "42cafebabe" //valeur arbitraire, ne doit juste pas être dans les data ls_bound = fill('-', 38 - len(ls_boundid)) + ls_boundid //38 = longeur testée avec chrome //on construit nos data pour 1 élément (1 champ de formulaire) //on peut répéter si on en veut plusieurs, on gardera la même borne //chaque borne est précédée de '--' et la dernière est suivie aussi de '--' //pour un champ de formulaire on utilise "name" ls_request = 'Content-Disposition: form-data; name="cXML-urlencoded"~r~n' // <=== ici c'est le champ caché de ton form //pour des fichiers on aurait en plus "filename" et "type" //ls_request = 'Content-Disposition: form-data; name="file_1"; filename="xxx.txt"~r~n' //ls_request += 'Content-Type: text/xml;~r~n' //déterminer un type mime ou utiliser application/octet-stream ls_request += "~r~n" //fin des entêtes de la part lbl_content = blob("--" + ls_bound + "~r~n" + ls_request, encodingansi!) & + blob(ls_example, encodingansi!) & + blob("~r~n--" + ls_bound + "--" + "~r~n", encodingansi!) //la dernière borne a un -- final //on construit les entêtes de la requête POST //dans le cas de la transmission de données pour du multipart //ce n'est PAS application/x-www-form-urlencoded comme le dit la doc ! //la taille indiquée est la taille de tout ce qui suit les entêtes de requête //(les parts et leur entêtes) ls_headers = "Content-Length: " + string(len(lbl_content)) + "~r~n" ls_headers += "Content-Type: multipart/form-data; boundary=" + ls_bound + "~r~n" ls_headers += "~r~n" //fin des headers l_inet = create inet l_ir = create n_inet //si on indique 0, le port est déterminé automatiquement : http=80, https=443 //si on indique autre chose ce sera ce port là li_rc = l_inet.PostURL( ls_url, lbl_content, ls_headers, 8080 /*0 = port fonction de l'url*/, l_ir) /* 1 Success -1 General error -2 Invalid URL -4 Cannot connect to the Internet -5 Unsupported secure (HTTPS) connection attempted -6 Internet request failed */ if li_rc = 1 then //OK //si on veut exploiter la réponse du serveur, c'est ici string ls_resp ls_resp = l_ir.getstringdata( ) //messagebox("POST result", ls_resp) //mle_resp.text = ls_resp else //Paf! - Signaler un problème //messagebox("POST result", "PostURL returned " + string(li_rc)) //mle_resp.text = "PostURL returned " + string(li_rc) end if destroy l_ir destroy l_inet
Attention à l'utilisation des "~r~n" : il n'y en a pas en trop, il faut délimiter les lignes de la requête et parfois sauter des lignes pour délimiter les données comme le ferait un navigateur.
Hopant que ça helpe...
Hors ligne
Bonjour Seki,
Un grand merci pour tes recherches, mais les 2 traitements qui utilisent IE aujourd'hui sont en HTTPS et donc (sauf erreur de ma part) non supporté par les 2 méthodes que tu préconises, snif .
Merci quand même,
Et si tu as d'autres propositions, je prend,
Merci
Hors ligne
J'ai été bloqué par la gestion https pour geturl post url.
J'ai donc bricolé une dll com C# pour tout ça.
Si l'usage d'une dll com ne te rebute pas, je verrais pour fournir la dll et un exemple d'usage dans pb.
PS : serveur 2003 est supporté par la DLL car j'ai pu compilé sous .NET 4.0, qui est la plus base version du framework .NET contenant les objets dont j'avais besoin.
Dernière modification par Van (25-03-2015 09:44:04)
Hors ligne
wazou1812 a écrit:
Un grand merci pour tes recherches, mais les 2 traitements qui utilisent IE aujourd'hui sont en HTTPS et donc (sauf erreur de ma part) non supporté par les 2 méthodes que tu préconises, snif .
Arf, je n'avais pas de https sous la main pour tester mais effectivement on se prend le code -5 (Unsupported secure (HTTPS) connection attempted).
Bon, au moins ce fut l'occasion de creuser quelques points fort intéressants (comment fonctionne POST + multipart, mise en place d'un servlet de test sur un Tomcat pour afficher ce qui est envoyé par posturl(), ...), donc je ne regrette pas
wazou1812 a écrit:
Et si tu as d'autres propositions, je prend,
Ben là, tout prêt, non
Hors ligne
Van a écrit:
J'ai été bloqué par la gestion https pour geturl post url.
J'ai donc bricolé une dll com C# pour tout ça.
Si l'usage d'une dll com ne te rebute pas, je verrais pour fournir la dll et un exemple d'usage dans pb.
PS : serveur 2003 est supporté par la DLL car j'ai pu compilé sous .NET 4.0, qui est la plus base version du framework .NET contenant les objets dont j'avais besoin.
Bonjour,
Je ne sais pas si l'usage d'une dll sera acceptée par ma boite, mais je veux bien que tu me la procure afin de pouvoir argumenter avec cette possibilité.
J'avais également posé la question au support Sybase qui m'a répondu
Je pourrais vous conseiller d'utiliser des controles ActiveX pour répondre à vos besoins: http://www.dart.com/web-activex-wininet-library-api.aspx http://www.dart.com/ctl_web.aspx N'ayant jamais développé avec ces objets, je vous invite vivement à utiliser la communauté PowerBuilder ( http://scn.sap.com/community/developer-center/powerbuilder ) pour savoir si d'autres solutions s'offrent à vous.
ça vous dit quelque chose ces ActiveX, pour moi c'est un peu l'inconnu.
Merci d'avance,
Hors ligne
wazou1812 a écrit:
Je ne sais pas si l'usage d'une dll sera acceptée par ma boite, mais je veux bien que tu me la procure afin de pouvoir argumenter avec cette possibilité.
La dll et son source sont sur mon github.
C'est encore loin d'être parfait étant donné que je n'avais plus toucher au C# depuis 2007 . Mais ça tourne bien pour mon projet. (D'ailleur si quelqu'un voit une portion (voir la totalité qui sait ^^") de code qui le chiffone, n'hésitez pas à me faire signe)
Pour le coup elle s'appel ws_declaration_sociale.dll (et son copain le ws_declaration_sociale.tlb pour que la DLL soit en COM) car c'était un nom que l'on m'a imposé et je n'ai pas pris le temps d'en faire une version avec un nom générique pour mon dépot sur github.
Mais rien n'empêche de le changer et de regénérer le tout.
Pour ce qui est d'un exemple d'utilisation je vais voir pour t'en fournir un dans le journée. Mais tu as déjà le source qui te permettra de te faire une idée de son fonctionnement
Dernière modification par Van (26-03-2015 13:21:57)
Hors ligne
Van a écrit:
wazou1812 a écrit:
Je ne sais pas si l'usage d'une dll sera acceptée par ma boite, mais je veux bien que tu me la procure afin de pouvoir argumenter avec cette possibilité.
La dll et son source sont sur mon github.
C'est encore loin d'être parfait étant donné que je n'avais plus toucher au C# depuis 2007 . Mais ça tourne bien pour mon projet. (D'ailleur si quelqu'un voit une portion (voir la totalité qui sait ^^") de code qui le chiffone, n'hésitez pas à me faire signe)
Pour le coup elle s'appel ws_declaration_sociale.dll (et son copain le ws_declaration_sociale.tlb pour que la DLL soit en COM) car c'était un nom que l'on m'a imposé et je n'ai pas pris le temps d'en faire une version avec un nom générique pour mon dépot sur github.
Mais rien n'empêche de le changer et de regénérer le tout.
Pour ce qui est d'un exemple d'utilisation je vais voir pour t'en fournir un dans le journée. Mais tu as déjà le source qui te permettra de te faire une idée de son fonctionnement
Bonjour,
Un grand merci,
Je vais regarder tout ça, et je suis toujours preneuse d'un bon exemple PB.
Merci
Hors ligne
Je ne sais pas si ça correspond à ce que tu veux mais on ne sait jamais
J'ai déjà utilisé Msxml2.ServerXMLHTTP pour communiquer avec des serveurs en https (l'exemple est pour du SOAP mais c'est la même chose)
loo_xmlhttp = CREATE oleobject loo_xmlhttp.connecttoNewObject("Msxml2.ServerXMLHTTP.4.0") loo_xmlhttp.open("POST",ls_post_url,false) if lb_multipart then loo_xmlhttp.setRequestHeader('Content-Type','multipart/related; type="text/xml"; start="<rootpart@soapui.org>"; boundary="' + ls_boundary + '"') else loo_xmlhttp.setRequestHeader('Content-Type','text/xml') end if loo_xmlhttp.setRequestHeader('SOAPAction',this.is_base_URL + this.is_relative_SOAP + ls_service + "/" + ls_action) ls_code_envoi = "" if lb_multipart then // Mettre le premier séparateur de multipart // Mettre l'entête partie XML ls_code_envoi += & '--' + ls_boundary + & char(13) + char(10) + & 'Content-Type: text/xml; charset=UTF-8' + & char(13) + char(10) + & 'Content-Transfer-Encoding: 8bit' + & char(13) + char(10) + & 'Content-ID: <rootpart@soapui.org>' + & char(13) + char(10) + & char(13) + char(10) end if // mettre le xml ls_code_envoi += ls_xml if lb_multipart then ls_code_envoi += char(13) + char(10) for li_cpt = 1 to li_end if f_clipped(lstrm_pj[li_cpt].ls_type) <> '' then ls_nom_fic = f_getFileName(lstrm_pj[li_cpt].ls_chemin) ls_nom_fic = f_replace_accent(ls_nom_fic) ls_ext = f_getExt(lstrm_pj[li_cpt].ls_chemin) if upper(ls_ext) = 'PDF' then ls_ct = "application/pdf" else ls_ct = "image/jpeg" end if // mettre un séparateur // mettre l'entête ls_code_envoi += & '--' + ls_boundary + & char(13) + char(10) + & 'Content-Type: ' + ls_ct + '; name=' + ls_nom_fic + '.' + ls_ext + & char(13) + char(10) + & 'Content-Transfer-Encoding: base64' + & char(13) + char(10) + & 'Content-ID: <' + ls_nom_fic + '.' + ls_ext + '>' + & char(13) + char(10) + & 'Content-Disposition: attachment; name="' + ls_nom_fic + '.' + ls_ext + '"; filename="' + ls_nom_fic + '.' + ls_ext + '"' + & char(13) + char(10) + & char(13) + char(10) // mettre le binaire ls_code_envoi += of_fichier_vers_base64(lstrm_pj[li_cpt].ls_chemin) + char(10) + char(13) + char(10) end if next // mettre le marqueur de fin multipart ls_code_envoi += '--' + ls_boundary + '--' + char(10) + char(13) + char(10) + char(13) + char(10) else end if loo_xmlhttp.send(ls_code_envoi) lsm_reponse[1] = string(loo_xmlhttp.status) lsm_reponse[2] = string(loo_xmlhttp.statusText) lsm_reponse[3] = string(loo_xmlhttp.responseText) lsm_reponse[4] = string(loo_xmlhttp.responseXML.XML) if lsm_reponse[1] = '200' then // on est OK else // Afficher les messages end if DESTROY loo_xmlhttp
en espérant que ça serve à quelqu'un
Hors ligne
J'avais vu ça dans les archives : ça passe aussi par un objet OLE, mais c'est à mon avis une meilleure solution de se lier avec msxml qui doit être déployé sur tous les systèmes microsoft (en précisant en plus une version) qu'avec un navigateur web avec un fonctionnement beaucoup plus aléatoire selon les versions.
Hors ligne
bonjour,
Merci pour vos retours.
Par rapport à ma solution qui était en production depuis plusieurs années, j'ai mis des traces pour savoir a quel moment l'envoi du fichier est devenu très long, et c'est donc l'instruction submit qui pose problème.
Ce que je ne sais pas, c'est qu'est ce qui a pu perturber Internet Explorer pour que la soumission ne fonctionne plus ?
Et bien sur, nous ne maitrisons pas la partie réseau du client pour savoir ce qu'il se passe, mais sur le serveur posant problème, si je doubleclique sur le fichier html que mon appli PB a constitué et essayé d'envoyer pendant plus de 5 minutes, le fichier est envoyé immédiatement.
C'est quand même bizarre ? Ce qui pourrait me faire dire que la partie réseau du client n'est pas responsable ? A moins que le réseau detecte que le fichier un envoyé par une application ?
Vos lumières me seront surement utiles,
Merci d'avance,
Hors ligne
J'ai tenter msxml mais je ne pouvais pas envoyé de flux text/plain, je récupéré une erreur 500 et le prestataire chez qui j'envoyais mes données me disait ne rien pouvoir exploité car ça lui exploser dans les main.
Donc je suis partie sur l'écriture de la DLL C# car j'était assez persuadé que ça ne bougerai pas chez eux si le problème venait de leur côté.
Pour un exemple de code légérement épuré de code ou de nom que je ne peux pas donner.
Pour la variable de plateforme elle me sert à géré des URL et des actions différentes selon vers qui j'envoi mes données.
public function long uf_traitement_webservices (string as_methode_http, string as_url, string as_donnees_envoyees, string as_header[], ref long al_code_http, ref string as_donnees_retour, ref string as_type_retour); long ll_upperbound_header, ll_index_header, ll_retour, ll_retour_fct = 0 any la_retour string ls_type_envoi, ls_certificat, ls_certificat_ini, ls_password_certificat = '' as_methode_http = upper(f_coalesce({as_methode_http, ''})) if not f_in(as_methode_http, "GET,POST,PUT,DELETE") then is_complement_erreur = as_methode_http il_erreur = 1 return -1 end if as_url = f_coalesce({as_url, ''}) if as_url = '' then il_erreur = 2 return -1 end if //connexion à la DLL oleobject lole_ws lole_ws = create oleobject try la_retour = lole_ws.connectToNewObject("ws_declaration_sociale.main") catch (runtimeerror e ) end try //traitement du retour de connexion si différent de 0 alors la connexion a échouée if la_retour <> 0 then il_erreur = 7 end if if il_erreur = 0 then try //on vérifié dans le fichier ini s'il y a besoin d'un certificat ou un traitement particulier sur le certificat serveur en fonction de la plateforme cible et on le met en place if is_index_certificat_developpement <> "" and ib_test_editeur and il_plateforme_cible = 2 then ls_certificat_ini = profilestring(gs_fichier_ini, "TEST",is_index_certificat_developpement, "") ls_certificat = f_get_dictionary_string(ls_certificat_ini, "CERT") ls_password_certificat = f_get_dictionary_string(ls_certificat_ini, "PASS") lole_ws.SetClientCertificate(ls_certificat, ls_password_certificat) elseif il_plateforme_cible = 1 or il_plateforme_cible = 3 then ls_certificat_ini = profilestring(gs_fichier_ini, "Cert-NE","trusAllCertificatePolicy", "") if ls_certificat_ini <> "" then lole_ws.setTrusAllCertificatePolicy(ls_certificat_ini ) end if end if catch (runtimeerror e1 ) //traitement des erreur pour les certificats il_erreur = 4 is_complement_erreur = "Problème lors de la mise en place de certificat client ou de la stratégie lors d'erreur de certificat serveur" end try if il_erreur = 0 then //envoi de la requête http(s) try al_code_http = lole_ws.reqHttp(as_url, as_methode_http, as_header, as_donnees_envoyees) catch (runtimeerror e2 ) //traitement d'erreur de l'envoir de requête il_erreur = 4 is_complement_erreur = "Erreur lors de la requete HTTP(S)" end try end if if il_erreur = 0 then //traitement du retour try as_donnees_retour = string(lole_ws.GetRequestResponse()) catch(runtimeerror e3 ) il_erreur = 4 is_complement_erreur = "Erreur lors de la récupération du message retour du WebServices" end try //as_type_retour = string(lole_srvHTTP.getResponseHeader("Content-Type") ) //messagebox(stringal_code_http), as_donnees_retour) end if end if //déconnexion et destruction de l'objet OLE if isvalid (lole_ws) then ll_retour = lole_ws.disconnectobject( ) if isvalid (lole_ws) then destroy lole_ws //si il_erreur et différent de 0 alros on retourne -1 pour un traitement éventuel par l'appelant if il_erreur <> 0 then return -1 return 1 end function
Dernière modification par Van (01-04-2015 09:28:34)
Hors ligne
Pages: 1