Newsgroup: it.comp.lang.delphi
Titolo: Pasaggio win 7 pro 64 bit a win 10 pro 64 bit

Ciao a tutti,
   da anni per mappare i pc in rete ho usato queste due soluzioni (una o 
l'altra in diversi progetti) stavbili e funzionanti da xp a 7.
Ora, in win 10, queste due soluzioni non funzionano piu'.
Per non funzionano piu' si intende che, a discrezione di qualcuno (os), 
ho questi risultati: il pc si blocca, si ottengono degli errori con 
codici ed indirizzi sempre diversi, la lista del pc risulta vuota e/o 
non trova alcuna connessione in rete.
Ecco la funzione e procedura utilizzate.
 
1)
function FindAllComputers(Workgroup: string; WithIP: Boolean): TStringList;
var
   EnumHandle : THandle;
   WorkgroupRS : TNetResource;
   Buf : Array[1..500] of TNetResource;
   BufSize : cardinal;
   Entries : cardinal;
   Res : Integer;
   Computers : Tstringlist;
   Limit, I: Integer;
begin
   Limit := 0;
   Workgroup := Workgroup + #0;
   FillChar(WorkgroupRS, SizeOf(WorkgroupRS) , 0);
   With WorkgroupRS do
   begin
     dwScope := 2;
     dwType := 3;
     dwDisplayType := 1;
     dwUsage := 2;
     lpRemoteName := @Workgroup[1];
   end;
   WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0,
     @WorkgroupRS, EnumHandle); // RESOURCE_GLOBALNET
   Computers := TStringList.Create;
   repeat
     Entries := 1;
     BufSize := SizeOf(Buf);
     Res := WNetEnumResource(EnumHandle, Entries, @Buf[1], BufSize);
     if (Res = NO_ERROR) and (Entries = 1) then
     begin
       Computers.Add(StrPas(Buf[1].lpRemoteName));
     end;
     Inc(Limit);
   until (Res <> NO_ERROR) or (Limit > 100);
   WNetCloseEnum( EnumHandle );
   if WithIP then
   begin
     for I := 0 to Computers.Count-1 do
     Computers[I] := Computers[I] + ' ( ' + GetIP(Computers[I]) + ' )';
   end;
   Result := Computers;
end;
 
2)
procedure ScanNetworkResources(ResourceType, DisplayType: DWord; List: 
TStrings);
 
procedure ScanLevel(NetResource: PNetResource);
var
   Entries: DWord;
   NetResourceList: PNetResourceArray;
   i: Integer;
begin
   if CreateNetResourceList(ResourceType, NetResource, Entries, 
NetResourceList) then try
     for i := 0 to Integer(Entries) - 1 do
     begin
       if (DisplayType = RESOURCEDISPLAYTYPE_GENERIC) or
         (NetResourceList[i].dwDisplayType = DisplayType) then begin
         List.AddObject(NetResourceList[i].lpRemoteName,
                       Pointer(NetResourceList[i].dwDisplayType));
       end;
       if (NetResourceList[i].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then
         ScanLevel(@NetResourceList[i]);
     end;
   finally
     FreeMem(NetResourceList);
   end;
end;
begin
   ScanLevel(Nil);
end;
 
Dato che non riesco a trovare una correzzione, qualcuno riesce a darmi 
una mano di come mappare i pc in rete?
 
OS: Win 10 pro 64 bit
Delphi: 10.3.3
 
Grazie a tutti
 
Ciao
Daniele


Scuasate .... mancava questa funzione
 
function CreateNetResourceList(ResourceType: DWord;
                               NetResource: PNetResource;
                               out Entries: DWord;
                               out List: PNetResourceArray): Boolean;
var
   EnumHandle: THandle;
   BufSize: DWord;
   Res: DWord;
begin
   Result := False;
   List := Nil;
   Entries := 0;
   if WNetOpenEnum(RESOURCE_GLOBALNET,
                   ResourceType,
                   0,
                   NetResource,
                   EnumHandle) = NO_ERROR then begin
     try
       BufSize := $4000;  // 16 kByte
       GetMem(List, BufSize);
       try
         repeat
           Entries := DWord(-1);
           FillChar(List^, BufSize, 0);
           Res := WNetEnumResource(EnumHandle, Entries, List, BufSize);
           if Res = ERROR_MORE_DATA then
           begin
             ReAllocMem(List, BufSize);
           end;
         until Res <> ERROR_MORE_DATA;
         Result := Res = NO_ERROR;
         if not Result then
         begin
           FreeMem(List);
           List := Nil;
           Entries := 0;
         end;
       except
         FreeMem(List);
         raise;
       end;
     finally
       WNetCloseEnum(EnumHandle);
     end;
   end;
end;

Ciao.
 
Prima di tutto, la tua (puah!) proceddure dovrebbe essere un metodo.
Poi, per come la dichiari tu, rischi di fare casino.
 
Invece di:
 
FindAllComputers(Workgroup: string; WithIP: Boolean): TStringList;
 
La forma corretta è questa:
 
FindAllComputers(const Workgroup: string; const WithIP: Boolean, alist: TStringList): integer;
 
Delphi non ha il GC. Come l'hai scritta tu si fa casino sulla questione del "a chi spetta la responsabilità di dare un FreeAndNil quando l'istanza di TStringList non serve più".
Nella forma che ti ho suggerito io hai tutto a monte, insieme.
Come l'haiscritta tu, credi de in un posto e distruggerai in un altro.
In altre parole, perdi il controllo.
Alla lunga questi errori di base li PAGHI, e con pesanti interessi.
Per contro, in java o c#, ad esempio la sintassi è lecita: loro hanno il GC.
 
Tornando al tuo problema, a occhio la prima cosa che mi viene in mente è qualcosa legato alla sicurezza.  
Suggerimenti:
 
1) Spezzetta il codice su più blocchi try..except, avendo cura di gestire le eccezioni aggiungendo ai messaggi un qualcosa che ti faccia capire in quale punto si incazza. Questa cosa sembra ovvia ma in realtà non lo è....
Ho messo mano a del codice dove più  blocchi try..except davano gli stessi messaggi: vai a capire dove sta succedendo 'o burdello
 
2) lancia il tuo exe non da delphi con il debug. 
Quindi, vai nella cartella ma non fare doppio click.
Pulsante di destra , esegui come amministratore e vedi cosa succede.
 
A.
 
 

Alberto, sempre un maestro !
 
"Alberto Salvati"  ha scritto nel messaggio 
news:de3ae781-1b09-412d...@googlegroups.com...


Ciao Alberto,
   grazie per la risposta ....
Stavo facendo mente locale ... non sarebbe ora che, alla fine di questa 
emergenza sanitaria, ci troviamo al Duomo per un caffe' ?? (Se non 
sbaglio lavori a Milano vero?).
 
Tornando a noi, come sempre ti ringrazio per i tuoi preziosi consigli.
il codice l'ho appena modificato cosi' da essere, decisamente, piu' 
pulito e sotto controllo.
 
Tornando al problema.
Non e' una banalita', nel senso che da un lato puo' essere banale e 
dall'altro un po meno.
Nel fine settimana ho approfondito il caso ed e' uscito che questo tipo 
di problema non e' nuovo ma ben conosciuto e discusso.
Tutto e' opera di Win 10 pro e non.
Fino alla versione 1803 prima build (non ricordo il numero) tutto ok, i 
pc in rete si vedono.
Dalla seconda buid in avanti no.
Questo perche' per motivi di sicurezza hanno disabilitato il protocollo 
SMB/CIFS.
Una volta riabilitato, ecco ripristinata la lista dei pc in rete.
 
Qui uno dei link dove spiega come fare
 
https://www.nicolinolodo.it/windows-10-non-si-vedono-piu-i-computer-della-rete/
 
 
Ci sono, comunque, delle eccezioni.
Per esempio in ufficio ho la versione 18362.657 e questa soluzione funziona.
A casa ho la 1803.19xx (e' la terza o quarta build) e questa soluzione 
non funziona !!
 
Infine, in uno dei tanti articoli che ho letto si parla di una imminente 
versione di win 10 che rimuovera' il protocollo SMB/CIFS v1 per 
introdurre il SMB/CIFS v2 dove sara possibile condidivere il pc in rete 
non come pc ma come disco (unita' di rete, gli esempi facevano Z:).
 
Quindi, ovviamente chi ha questa necessita', per lo sviluppo di "domani" 
per i sistemi operativi con win 10 <1803 la procedura va bene.
Con win 10 >1803 prima di lanciare la procedura verificare che il 
protocollo sia attivo.
Quando non sara' piu' disponibile .... bho !! vedremo !!
 
Mi scuso se ci sono inesattezze o qualcosa e' poco chiaro, ma era 
doveroso riportare quanto sopra.
 
Grazie ancora.
 
Ciao
Daniele
