C++Builder Logo
Enumerating network resources Obtenir la liste des PC reliés à un réseau

If you want to enumerate all resources connected to your network, you have to use these functions from the windows API :
WNetOpenEnum()
WNetEnumResource()
WNetCloseEnum()
With this code, you're able to obtain a list of all computers connected and/or a list of all shared folders and printers.

The function EnumNetRes() performs all the task. It's a recursive function (it calls itself).

Pour obtenir la liste de toutes les ressources connectées sur votre réseau, vous devez utiliser les fonctions de l'APIsuivantes :
WNetOpenEnum()
WNetEnumResource()
WNetCloseEnum()
Ce code vous permet d'obtenir la liste de tous les PC reliés au réseau, mais aussi  les dossiers partagés et les imprimantes partagées.

Tout le travail est fait dans la fonction EnumNetRes() qui est une fonction récursive (elle s'appelle elle-même).

Put this declarations in the private section of your header file (Unit.h) : Placez cette déclaration dans le fichier d'entête de votre projet (Unit.h) dans la section private:
 

void __fastcall EnumNetRes(NETRESOURCE* nr);

   
Put this code in the OnClick event of a button. The button is there to launch the enumeration : Placez ce code dans l'événement OnClick d'un bouton. Celui-ci ne sert qu'à lancer la fonction qui réalise l'énumération :
 

void __fastcall TForm1::Button1Click(TObject *Sender) 

  EnumNetRes(NULL); 
}


Now, place this code in your .cpp file. The results is added to a ListBox so don't forget to put one on your form. Placez, maintenant, le code suivant dans le fichier .cpp.
Le résultat s'affiche dans une ListBox. N'oubliez donc pas d'en placer une sur votre forme.

void __fastcall TForm1::EnumNetRes(NETRESOURCE* nr) 

  HANDLE hEnum; 
  //NetResource=NULL : we want to enumerate all resources 
  if(WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY, 
      RESOURCEUSAGE_CONTAINER|RESOURCEUSAGE_CONNECTABLE 
      ,nr,&hEnum)!=NO_ERROR) 
  { 
    // Error (access denied for instance) 
    return
    //If we don't want to continue the enumeration, 
    //throw an exception 
    //RaiseLastWin32Error(); 
  } 
  //Enum all resources 
  DWORD Count=-1; 
  DWORD BufferSize=0; 
  DWORD ReturnVal=0; 
  //Allocate space for the NetResource array 
  NETRESOURCE *NetRes=(NETRESOURCE*)new char[1024]; 
  ZeroMemory(NetRes,sizeof(NETRESOURCE)); 
  for(;;) 
  { 
    ReturnVal=WNetEnumResource(hEnum,&Count,NetRes,&BufferSize); 
    if(ReturnVal==ERROR_MORE_DATA)  //we set the size of NetRes 
    { 
      //we set the size of NetRes if there is more data 
      Count=-1; 
      delete[] NetRes; 
      NetRes=(NETRESOURCE*)new char[BufferSize]; 
      ZeroMemory(NetRes,sizeof(NETRESOURCE)); 
      ReturnVal=WNetEnumResource(hEnum,&Count,NetRes,&BufferSize); 
    } 
    if(ReturnVal!=NO_ERROR)break
    // Add the resource to the ListBox 
    for (unsigned int i=0;i<Count;i++) 
    { 
      ListBox1->Items->Add(NetRes[i].lpRemoteName); 
      //This line may be necessary 
      //Application->ProcessMessages(); 
      if((NetRes[i].dwUsage & RESOURCEUSAGE_CONTAINER)==RESOURCEUSAGE_CONTAINER) 
          EnumNetRes(&NetRes[i]); 
    } 
    if(ReturnVal==ERROR_NO_MORE_ITEMS) 
    { 
      //the enumeration is completed 
      delete[] NetRes; 
      WNetCloseEnum(hEnum); 
      //RaiseLastWin32Error(); 
    } 
  } 
  delete[] NetRes; 
  WNetCloseEnum(hEnum); 


This is a lengthy process. On my computer, it takes several minutes to enumerate all resources (about 50 computers and a lot of shared folders and printers). Because your application will hang during the enumeration, it could be attractive to place this code in a thread. L'énumération de toutes les ressources est lente, sur mon PC, cela prend plusieurs minutes ( environ 50 PC et tout un tas de dossiers et d'imprimantes partagées).
Comme, votre application semblera bloquée pendant l'exécution de la fonction, il peut être intéressant de placer le code dans un thread.