Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
Je suis actuellement en charge du développement d'une évolution pour un client.
L'application récupère différents document sur un répertoire réseau en utilisant les identifiants de l'utilisateur qui se connecte à l'application.
Or pour des question de sécurité le client souhaite que l'accès au répertoire se fasse uniquement par l'application, donc il ne doit y avoir qu'un seul login/mdp qui se connecte au répertoire réseau, celui donné par l'application.
En l'état l'application utilise une OLEObject qui se connecte au Scripting.FileSystemObject.
Ce que je voudrais c'est ajouter le login et mdp avant que l'OLEObject fasse le FileExists afin que l'application n'utilise pas le login et mdp de l'utilisateur.
o1 = Create unv_OLEObject if o1.ConnectToNewObject("Scripting.FileSystemObject") <> 0 Then gnv_app.inv_error.of_message ( Upper(gnv_app.iapp_object.appname), & "Erreur : Impossible d'accéder au système de gestion de fichier.", Exclamation!) Destroy o1 Return -1 End If If o1.FileExists(ls_nomfic_src) = False Then gnv_app.inv_error.of_message ( Upper(gnv_app.iapp_object.appname), & "Erreur : Fichier source " + ls_nomfic_src + " introuvable !", Exclamation!) Destroy o1 Return -1 End If
J'ai cherché sur internet voir s'il y avait des solutions déjà proposé mais rien qui ne correspond à ce que j'attends.
Auriez vous une idée ou un conseil à me donner ?
Merci d'avance.
Hors ligne
Scripting.FileSystemObject ? Pouark
On doit pouvoir faire quelque chose avec la Net API native...
Hors ligne
Je veux bien te croire, mais comme je suis encore novice sur Powerbuilder et encore plus sur les OLEObject, je veux bien un exemple
Sachant que je n'ai fourni qu'un petit morceau de code, le reste de la fonction utilise des méthodes du Scripting.FileSystemObject.
Exemple : FolderExists, etc.
Et s'il était possible d'éviter de recoder l'ensemble de la fonction, j'en serais ravi :D
Hors ligne
Je vais regarder si je peux y arriver via l'API.
Mon pouark c'est plus par rapport à l'utilisation du Scripting.FileSystemObject (qui comme son nom l'indique est plutôt destiné à servir dans du scripting - typiquement depuis un script .vbs, mais aussi .vba avant qu'on ait accès aux assemblies windows dans des macros excel / word, et anciennement en ASP pré-.Net) alors qu'on peut doit pouvoir demander directement au système.
Hors ligne
seki a écrit:
Je vais regarder si je peux y arriver via l'API.
Je n'ai pas trouvé si on pouvait accéder directement à un fichier d'un share réseau, par contre ce qui est possible c'est de mapper temporairement le share avec login/mdp avec WNetUseConnection(), et de supprimer le mapping une fois le traitement fait avec WNetCancelConnection() .
J'ai wrappé cette api dans un petit user object avec 2 méthodes :
- map_drive (string as_uncpath, string as_user, string as_pwd)
- unmap_drive (string as_resource, boolean ab_force)
Et au passage on peut voir l'utilisation de l'irremplaçable OutputDebugString() renommée plus simplement DebugString(). Elle permet d'émettre des message de trace qui ne sont visible qu'avec un debugger (VS studio, OllyDbg, ...) ou le très utile DebugView.
Objet n_netuse.sru
$PBExportHeader$n_netuse.sru forward global type n_netuse from nonvisualobject end type type s_netresource from structure within n_netuse end type end forward type s_netresource from structure unsignedlong dwscope unsignedlong dwtype unsignedlong dwdisplaytype unsignedlong dwusage string lplocalname string lpremotename string lpcomment string lpprovider end type global type n_netuse from nonvisualobject autoinstantiate end type type prototypes Function ulong WNetUseConnection (ulong hwndOwner, REF s_netresource lpNetResource, ref string lpPassword, ref string lpUsername, ulong dwFlags, REF string lpAccessName, REF ulong lpBufferSize, REF ulong lpResult) library "mpr.dll" alias for "WNetUseConnectionA;ansi" Function ulong WNetCancelConnection (string lpName, boolean fForce) library "mpr.dll" alias for "WNetCancelConnectionW" subroutine DebugString(string msg) library "kernel32" alias for "OutputDebugStringW" end prototypes type variables Constant ulong NO_ERROR = 0 Constant ulong CONNECT_UPDATE_PROFILE = 1 Constant ulong CONNECT_INTERACTIVE = 8 Constant ulong CONNECT_PROMPT = 16 Constant ulong CONNECT_REDIRECT = 128 Constant ulong CONNECT_COMMANDLINE = 2048 Constant ulong CONNECT_CMD_SAVECRED = 4096 Constant ulong RESOURCETYPE_ANY = 0 Constant ulong RESOURCETYPE_DISK = 1 Constant ulong RESOURCETYPE_PRINT = 2 end variables forward prototypes public function string map_drive (string as_uncpath, string as_user, string as_pwd) public function boolean unmap_drive (string as_resource, boolean ab_force) end prototypes public function string map_drive (string as_uncpath, string as_user, string as_pwd);s_netresource lstr_netresource String ls_null String ls_buffer String ls_MappedDrive = "" uLong ll_bufferlen uLong ll_null uLong ll_ErrInfo uLong ll_success SetNull(ll_null) SetNull(ls_null) ls_buffer = Space(32) ll_bufferlen = Len(ls_buffer) lstr_netresource.dwType = RESOURCETYPE_DISK lstr_netresource.lpLocalName = ls_null lstr_netresource.lpRemoteName = as_uncpath lstr_netresource.lpProvider = ls_null ll_ErrInfo = WNetUseConnection(ll_null, lstr_netresource, as_pwd, as_user, CONNECT_REDIRECT, ls_buffer, ll_bufferlen, ll_success) IF ll_ErrInfo = NO_ERROR THEN debugstring("Mapped Drive Letter is " + ls_buffer) ls_MappedDrive = ls_buffer ELSE debugstring("Mapping Failed - Error is " + String(ll_ErrInfo)) END IF return ls_MappedDrive end function public function boolean unmap_drive (string as_resource, boolean ab_force); ulong lul_ret lul_ret = wnetcancelconnection(as_resource, ab_force) if lul_ret = NO_ERROR then debugstring(as_resource + " unmapped") else debugstring("failed to unmap " + as_resource) end if return lul_ret = NO_ERROR end function on n_netuse.create call super::create TriggerEvent( this, "constructor" ) end on on n_netuse.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
Exemple d'utilisation :
n_netuse net string ls_share = "\\server.domain.com\share" string ls_path = "some\path\to\files" string ls_user = "domainname\username" string ls_pwd = "s3cret" string ls_drive ls_drive = net.map_drive( ls_share + '\' + ls_path, ls_user, ls_pwd) //Le traitement à faire ici lb_files.dirlist(ls_share + '\' + ls_path + '\*.*' , 0) //juste un test pour lister les fichiers dans une dropdownlistbox messagebox("pause", "press a key") if net.unmap_drive(ls_drive, true) then //unmap is done else //unmap has failed end if
Ce code a été testé sur PB10.5 / XP côté client , et un serveur de fichiers Mac utilisant samba. Je n'ai pas de domaine windows sous la main pour tester avec un PDC... Mais je suis confiant
Hors ligne
seki a écrit:
Scripting.FileSystemObject [...] est plutôt destiné à servir dans du scripting
Bon, pour le défi , j'ai regardé cette solution, et ça peut fonctionner comme avec mon code WNetUseConnection : on peut connecter temporairement le share et le déconnecter.
Mais Scripting.FileSystemObject ne sait pas faire ça, il faut lui ajouter WScript.Network pour gérer le drive.
Exemple d'implémentation (mais je trouve ça moche je la poste parce que ça pourrait resservir dans vba par exemple) :
oleobject net, fso int ret string ls_share = "\\server.domain.com\share" string ls_path = "some\path\to\files" string ls_user = "domainname\username" string ls_pwd = "s3cret" net = create oleobject ret = net.ConnectToNewObject("WScript.Network") if ret <> 0 then messagebox("WScript.Network", "connect ole returned " + string(ret)) goto clean end if fso = create oleobject ret = fso.ConnectToNewObject("Scripting.FileSystemObject") if ret <> 0 then messagebox("Scripting.FileSystemObject", "connect ole returned " + string(ret)) goto clean end if //args = strLocalDrive, strRemoteShare, [persistent], [strUser], [strPassword] net.MapNetworkDrive("", ls_share, false, ls_user, ls_pwd) // some test oleobject d d = fso.GetFolder(ls_share + '\' + ls_path) int c c = d.files.count messagebox("fso file count", string(c)) //args = strName, [bForce], [bUpdateProfile] net.RemoveNetworkDrive(ls_share, true, false) clean: if isvalid(net) and not isnull(net) then destroy net if isvalid(fso) and not isnull(fso) then destroy fso
Hors ligne
Merci beaucoup pour le temps consacré :D
Je regarde ça et je te tiens au courant pour voir si ça fonctionne chez moi.
Hors ligne
Bonjour
je suis sur PB 12.6 et windows 7
la solution pb ne fonctionne pas dans mon cas (cf code ci dessous) où ls_path est le chemin du lecteur à connecter
soit il ramene un code erreur 53 (chemin inexistant) alors qu'il existe
que cela peut il être dis donc ?
merci d'avance
lstr_netresource.dwType = RESOURCETYPE_DISK lstr_netresource.lpLocalName = "W:" lstr_netresource.lpRemoteName = ls_path lstr_netresource.lpProvider = ls_null ll_ErrInfo = WNetUseConnection (ll_null, lstr_netresource, ls_pwd, ls_user, CONNECT_REDIRECT, ls_buffer, ll_bufferlen, ll_success) IF ll_ErrInfo = NO_ERROR THEN ls_MappedDrive = ls_buffer ELSE ls_MappedDrive = "["+string(ll_ErrInfo) +"]" // on retourne le code erreur END IF
Hors ligne