probleme beim einbinden von netapi32.lib
-
juhu es funktioniert!!!!!! danke JeGr!!!!!
es taucht dann, nachdem er die rechner aufgelistet hat, zwar die meldung "Fehler bei der weiteren Auflistung!" auf, aber das ist mir egal. wenns nichts schimmes ist, kann ich die zeile aus dem code ja auch einfach entfernen oder??? ist ja eigentlich bloß eine info für den benutzer...
ach JeGr, wo findet man die windows sdk hilfe eigentlich??? die ist kommt nicht gleich bei der windows installation auf den computer rauf, oder? danke...
-
Bei mir ist die SDK Hilfe jedenfalls installiert.
Wenn du im BCB unter dem Menü Hilfe nachschaust, dann befindet sich dort ein entsprechender Eintrag.
Auf der Festplatte müsste es die folgende Datei sein:
C:\Programme\Gemeinsame Dateien\Borland Shared\MSHelp\guide.hlpWenn die nicht da ist, dann musst du halt nochmal bei der BCB-Installation nachschauen.
Ansonsten findest du das ganze auch Online unter: http://msdn.microsoft.com/library/default.asp
Die Meldung kannst du natürlich unterdrücken. Kannst statt dessen auch eine andere Fehlerbehandlung machen bzw. es auch einfach ignorieren.
Die Hauptsache ist doch, dass die Rechner erscheinen[ Dieser Beitrag wurde am 05.02.2003 um 08:15 Uhr von JeGr editiert. ]
-
@JeGr: schon ganz gut, nur noch ein paar anmerkungen
1. wozu brauchst Du das Handle der Anwendung und ein Handle auf nen Device Context?
[cpp]
BOOL WINAPI ListNetworkComputer(HWND hwnd, HDC hdc, LPNETRESOURCE lpnr)[/cpp]2. warum erst umständlich mit GlobalAlloc Speicher reservieren?
eine einfache Variablen deklaration reicht da vollkommen aus
if (RESOURCEUSAGE_CONTAINER == (NetResource[i].dwUsage & RESOURCEUSAGE_CONTAINER))
ist identisch mit:
if (NetResource[i].dwUsage & RESOURCEUSAGE_CONTAINER)
beispiel: dezimal: 2 == 3 & 2 binär: 010 == 011 & 010 -> 010 == 010 => true doppelt gemoppelt :) dezimal: 3 & 2 binär: 011 & 010 -> 010 => true
-
Danke für die Hinweise!
Das meiste ist hier aber nicht auf meinem Mist gewachsen.
Ich habe den Grossteil (vor allem das mit dem Speicher allokieren) aus der Windows SDK-Hilfe übernommen. Dort wurde das eben so gemacht.Ansonsten war ich froh, dass die Funktion soweit funktioniert hat und da hab ich mich nicht mehr darum gekümmert, das Ganze noch zu optimieren.
Aber falls hier jemand Zeit und sonst nichts bessers vor hat, dann darf er gerne die ganze Sache überarbeiten.
Vielleicht könnte man dies dann auch in die FAQ stellen
-
Ausserdem hat bei einer universellen Lösung eine Zeile wie Form1->RichEdit1->Lines->Add(RemoteName); auch nichts zu suchen. Statt dessen sollte zB. einfach ein Zeiger auf eine StringList als Funktionsparameter übergeben werden:
ListNetworkComputer(TStrings *ResList) { ... ResList->Add(NetResource->lpRemoteName); ... } ... ListNetworkComputer(Memo1->Lines);
Ihr merkt schon, ich suche wieder Freiwillige für einen hübschen FAQ-Beitrag.
-
N'abend.
hab den Code nochmal etwas abgeändert:
Wäre dieser nun FAQ-tauglich?!
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //=========================================================================== // Funktion ListNetworkComputer //--------------------------------------------------------------------------- // // Ermittelt die Rechnernamen im lokalen Netzwerk. // Ist Win9x kompatibel. //--------------------------------------------------------------------------- // // Parameter: // IN: - TStrings* ComputerList - Liste zum Speichern der Namen // - LPNETRESOURCE Root - Zeige auf NETRESOURCE-Strukur // (wenn NULL, dann werden alle verfügbaren // Ressourcen aufgelistet) // RETURN: BOOL - Flag, ob Funktion erfolgreich //--------------------------------------------------------------------------- // // Aufrufbeispiel: ListNetworkComputer(Memo1->Lines, NULL) // (Listet alle Rechnernamen im lokalen Netzerk in // einem Memo auf) //--------------------------------------------------------------------------- // // Erstellt 05/02/2003 by Jens Gross mit Borland C++ Builder 6 //=========================================================================== BOOL WINAPI ListNetworkComputer(TStrings* ComputerList, LPNETRESOURCE Root) { // Variablendeklaration HANDLE hEnum; // Handle von WNetOpenEnum DWORD Result; // Rückgabewert für WNetXXX DWORD Buffer = 16384; // 16K als Startgrösse DWORD Entries = 0xFFFFFFFF; // liste alle möglichen Einträge LPNETRESOURCE NetResource; // Pointer auf NETRESOURCE // (enthält die gelisteten Einträge) // führe WNetOpenEnum aus, um Auflistung der Netzwerkressourcen // zu beginnen und ermittle den Rückgabewert Result = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, Root, &hEnum); // wenn Rückgabewert Fehler if(Result != NO_ERROR) { // gib Flag zurück, dass Funktion fehlerhaft return FALSE; } // solange noch Daten vorhanden sind do { // allokiere Speicher für NETRESOURCE-Struktur NetResource = (LPNETRESOURCE)GlobalAlloc(GPTR, Buffer); // führe WNetEnumResource aus, um Auflistung fortzusetzen, // die mit WNetOpenEnum begonnen wurde und ermittle Rückgabewert Result = WNetEnumResource(hEnum, &Entries, NetResource, &Buffer); // wenn Rückgabewert in Ordnung if(Result == NO_ERROR) { // ermittle für alle ermittelten Einträge die Namen for(DWORD i=0; i<Entries; i++) { // wenn ermittelter Eintrag ein Container ist // (z.B. Domäne, Arbeitsgruppe etc) if(RESOURCEUSAGE_CONTAINER == (NetResource[i].dwUsage & RESOURCEUSAGE_CONTAINER)) { // wenn List-Funktion TRUE liefert if(ListNetworkComputer(ComputerList, &NetResource[i])) { // ermittle den Remotenamen AnsiString RemoteName = AnsiString(NetResource[i].lpRemoteName); // wenn Remotename vorhanden und der Name mit \\ beginnt // (\\ deshalb, damit nur Rechner aufgelistet werden und nicht // auch noch die Domänen, Arbeitsgruppen etc) if(RemoteName != "" && RemoteName.SubString(1,2) == "\\\\") { // schreibe Namen in Liste ComputerList->Add(RemoteName); } } } } } // wenn keine weiteren Daten mehr vorliegen else if(Result != ERROR_NO_MORE_ITEMS) { // beende die Schleife break; } } while(Result != ERROR_NO_MORE_ITEMS); // gib den allokierten Speicher wieder frei GlobalFree((HGLOBAL)NetResource); // führe WNetCloseEnum aus, um die Auflistung zu beenden // und ermittle den Rückgabewert Result = WNetCloseEnum(hEnum); // wenn Rückgabewert Fehler if(Result != NO_ERROR) { // gib Flag zurück, dass Funktion fehlerhaft return FALSE; } // gib Flag zurück, dass Funktion erfolgreich return TRUE; } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { // leere Inhalt von RichEdit RichEdit1->Clear(); // führe List-Funktion aus ListNetworkComputer(RichEdit1->Lines, NULL); } //---------------------------------------------------------------------------
-
kann man hier nicht die else if weglassen. das Result wird doch von der while-schleife abgeprüft!
// wenn keine weiteren Daten mehr vorliegen else if(Result != ERROR_NO_MORE_ITEMS) { // beende die Schleife break; } } while(Result != ERROR_NO_MORE_ITEMS);
naja und wie gesagt:
if (RESOURCEUSAGE_CONTAINER == (NetResource[i].dwUsage & RESOURCEUSAGE_CONTAINER)) // ist identisch mit if(NetResource[i].dwUsage & RESOURCEUSAGE_CONTAINER)
und statt SubString hätte ich vlei mit Pos geprüft (Integervergleich). obwohl... hm.. Pos() muss ja auch erst nach dem String suchen, ist also vielleicht rum wie numm.. ansonsten ab in die FAQ.
-
@Sunday: Meine Frage an dich steht immernoch!
-
Tag WebFritzi, danke hat mir super weitergeholfen.
-
Kein Problem, mach ich doch gerne für dich.