CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Lista użytkowników

Lista użytkowników

dział ogólny

Lista użytkowników

Nowy postprzez shycat » czwartek, 23 września 2010, 01:30

Witam, szukam i szukam info w necie jak wyswietlic liste uzytkownikow systemu... no i nigdzie nie moge znalezc zadnego kodu, ani zadnej odpowiedzi - moze zle szukam, nie wiem... mam tylko kod z serwisu CB do wyswietlania aktualnie zalogowanego uzytkownika:


Kod: Zaznacz cały
char User[_MAX_PATH];
DWORD size = sizeof(User);
if(GetUserName(User, &size));
  Label1->Caption = (AnsiString)User;


Ale nie wiem jak wyswietlic liste wszystkich uzytkownikow... Prosze o jakies rady. Pozdrawiam :)
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    Windows 7Firefox

enumerate user accounts c++

Nowy postprzez Cyfrowy Baron » czwartek, 23 września 2010, 09:11

Można do tego celu wykorzystać WMI:

KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <Wbemidl.h> // <- dołączyć bibliotekę
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

# pragma comment(lib, "wbemuuid.lib") // <- dołączyć bibliotekę

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 CoInitialize(NULL);
 if(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT,
    RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0) != S_OK)
 {
  ShowMessage("Błąd inicjowania interfejsu WMI");
 }
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1() // destruktor klasy formularza, trzeba dodać w pliku nagłówkowym w sekcji public:
{
 CoUninitialize();
}
//---------------------------------------------------------------------------
void WMIInfo(TStrings *lpList, String wsClass)
{
 IWbemLocator *pWbemLocator = NULL;
 if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL,
     CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
 {
  IWbemServices *pWbemServices = NULL;
  String wsNamespace = String("root\\cimv2");

  if(pWbemLocator->ConnectServer(wsNamespace.t_str(), NULL, NULL, NULL, 0, NULL,
     NULL, &pWbemServices) == S_OK)
  {
   IEnumWbemClassObject *pEnumClassObject = NULL;
   String wsWQL = "WQL",
   wsQuery = "Select * from " + wsClass;

   if(pWbemServices->ExecQuery(wsWQL.t_str(), wsQuery.t_str(), WBEM_FLAG_RETURN_IMMEDIATELY,
      NULL, &pEnumClassObject) == S_OK)
   {
    IWbemClassObject *pClassObject = NULL;
    ULONG uCount = 1, uReturned;
    if(pEnumClassObject->Reset() == S_OK)
    {
     int iEnumIdx = 0;

     while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
     {
      lpList->Add("");

      SAFEARRAY *pvNames = NULL;

        if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
      {
       long vbl, vbu;

       SafeArrayGetLBound(pvNames, 1, &vbl);
       SafeArrayGetUBound(pvNames, 1, &vbu);

       for(long idx = vbl; idx <= vbu; idx++)
       {
        long aidx = idx;
        wchar_t *wsName = 0;
        VARIANT vValue;
        VariantInit(&vValue);
        SafeArrayGetElement(pvNames, &aidx, &wsName);

        BSTR bs = SysAllocString(wsName);
        HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
        SysFreeString(bs);

        if(hRes == S_OK)
        {
         AnsiString lValue;
         Variant vVar = *(Variant*)&vValue;
         if(vVar.IsArray())
         {
          for(int i = vVar.ArrayLowBound(); i <= vVar.ArrayHighBound(); i++)
          {
           Variant vTmp = vVar.GetElement(i);

           if(!lValue.IsEmpty()) lValue += ", ";

           lValue += VarToStr(vTmp);
          }
         }
         else
         {
          lValue = VarToStr(vVar);
         }
         if(!lValue.IsEmpty())
          lpList->Add(String(wsName) + ": " + lValue);
        }
        VariantClear(&vValue);
        SysFreeString(wsName);
       }
      }
      if(pvNames) SafeArrayDestroy(pvNames);

      iEnumIdx++;
     }
    }
    if(pClassObject) pClassObject->Release();
   }
   if(pEnumClassObject) pEnumClassObject->Release();
  }
  if(pWbemServices) pWbemServices->Release();
 }
 if(pWbemLocator) pWbemLocator->Release();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 ::SetCursor(LoadCursor(NULL, IDC_WAIT));
 Button1->Enabled = false;

 ListBox1->Items->Clear();
 WMIInfo(ListBox1->Items, "Win32_UserAccount Where LocalAccount = True"); /* klucz: Win32_UserAccount */

 ::SetCursor(LoadCursor(NULL, NULL));
 Button1->Enabled = true;
}
 


Kluczem do pobrania przez WMI informacji o użytkownikach jest klasa: "Win32_UserAccount Where LocalAccount = True". Wyliczone zostaną wszystkie konta, nawet te nieaktywne. Jeżeli chcesz wyliczyć tylko aktywne, czyli włączone to użyj klucza: "Win32_UserAccount Where Status != \"Degraded\"" lub "Win32_UserAccount Where Status = \"OK\"".

Ten kod zwróci do listy typy TStrings (tutaj do ListBox1) szczegółowe informacje o kontach użytkowników lokalnych. Jeżeli potrzebujesz tylko informacji podstawowych, czyli tylko nazwy kont, to z funkcji WMIInfo usuń ten fragment kodu:

KOD cpp:     UKRYJ  
lpList->Add("");

oraz zamień ten fragment kodu:

KOD cpp:     UKRYJ  
         if(!lValue.IsEmpty())
          lpList->Add(String(wsName) + ": " + lValue);

na taki kod:

KOD cpp:     UKRYJ  
         if(!lValue.IsEmpty() && String(wsName) == "Name")
          lpList->Add(lValue);

Ponieważ korzystam ze środowiska C++Builder 2010, to u mnie typem domyślnym jest wchar_t, dlatego przy konwersji z UnicodeString na wchar_t używam metody t_str(). U Ciebie typem domyślnym jest char i AnsiString, dlatego musisz użyć metody c_str(), czyli zmień sobie to w powyższym kodzie. Jeżeli z c_str() nie zadziała, to musisz użyć typu WideString i tak to jest opisane w serwisie Cyfrowy Baron w dziale: porady -> API -> Odczytywanie informacji o zasobach komputera za pomocą protokołu WMI.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
shycat
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Lista użytkowników

Nowy postprzez shycat » czwartek, 23 września 2010, 09:58

Dzieki Cyfrowy Baronie, sama pewnie bym na to nie wpadla :D Pozdrawiam.
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    Windows 7Firefox

Re: Lista użytkowników

Nowy postprzez shycat » czwartek, 23 września 2010, 10:11

Troche nie moge sie teraz polapac w typach zmiennych, zmienilam kawalek kodu na:

Kod: Zaznacz cały
  if(pWbemLocator->ConnectServer(wsNamespace.[b]c_str()[/b], NULL, NULL, NULL, 0, NULL,
     NULL, &pWbemServices) == S_OK)
  {


i dostaje błędy:

Kod: Zaznacz cały
[C++ Error] Unit1.cpp(37): E2034 Cannot convert 'char *' to 'wchar_t *'
[C++ Error] Unit1.cpp(37): E2342 Type mismatch in parameter 'strNetworkResource' (wanted 'wchar_t * const', got 'char *')
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    Windows 7Firefox

Re: Lista użytkowników

Nowy postprzez Cyfrowy Baron » czwartek, 23 września 2010, 10:32

Dlatego podałem odnośnik do odpowiedniej porady w serwisie Cyfrowy Baron, gdyż z tego co pamiętam, w starszych wersjach środowiska należy posługiwać się typem WideString. W tej poradzie jest pokazane jak należy konwertować typ AnsiString (String) na WideString.



Kilka uwag:

W tagu [code] nie można używać innych tagów, tak jak to zrobiłaś z tagiem [b].
Zamiast tagu [code] używaj tagu [cpp], który lepiej koloruje kod.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Lista użytkowników

Nowy postprzez shycat » czwartek, 23 września 2010, 10:51

ok, dałam rade, dzieki :)
Avatar użytkownika
shycat
Homos antropiczny
Homos antropiczny
 
Posty: 51
Dołączył(a): środa, 20 sierpnia 2008, 12:37
Lokalizacja: Śląsk
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder 2006, Delphi 7
Gadu Gadu: 26712716
    Windows 7Firefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 47 gości

cron