CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - WMI - problem z różnymi komputerami

WMI - problem z różnymi komputerami

dział ogólny

WMI - problem z różnymi komputerami

Nowy postprzez Corvis » czwartek, 20 maja 2010, 09:01

Witam,

Potrzebuję wyciągnąć z WMI 2 informacje o płycie głównej oraz dysku. Problem jest taki, że w XP nie mogę odczytać numeru seryjnego dysku twardego.

Xp Płyta:

Caption: Płyta główna
CreationClassName: Win32_BaseBoard
Description: Płyta główna
HostingBoard: True
Manufacturer: Gigabyte Technology Co., Ltd.
Name: Płyta główna
PoweredOn: True
Product: G31M-S2C
SerialNumber:
Tag: Base Board
Version:

Xp Dysk:

BytesPerSector: 512
Capabilities: 3, 4
Caption: SAMSUNG HD503HI
ConfigManagerErrorCode: 0
ConfigManagerUserConfig: False
CreationClassName: Win32_DiskDrive
Description: Stacja dysków
DeviceID: \\.\PHYSICALDRIVE0
Index: 0
InterfaceType: IDE
Manufacturer: (Standardowe stacje dysków)
MediaLoaded: True
MediaType: Fixed hard disk media
Model: SAMSUNG HD503HI
Name: \\.\PHYSICALDRIVE0
Partitions: 3
PNPDeviceID: IDE\DISKSAMSUNG_HD503HI_________________________1AJ100E4\32534333394A5341303839303334202020202020
SCSIBus: 0
SCSILogicalUnit: 0
SCSIPort: 0
SCSITargetId: 0
SectorsPerTrack: 63
Signature: 427301239
Size: 500105249280
Status: OK
SystemCreationClassName: Win32_ComputerSystem
SystemName:
TotalCylinders: 60801
TotalHeads: 255
TotalSectors: 976768065
TotalTracks: 15504255
TracksPerCylinder: 255

Vista Płyta

Caption: Base Board
CreationClassName: Win32_BaseBoard
Description: Base Board
HostingBoard: True
HotSwappable: False
Manufacturer: Gigabyte Technology Co., Ltd.
Name: Base Board
PoweredOn: True
Product: G31M-S2C
Removable: False
Replaceable: True
RequiresDaughterBoard: False
SerialNumber:
Status: OK
Tag: Base Board
Version:

Vista Dysk

BytesPerSector: 512
Capabilities: 3, 4
CapabilityDescriptions: Random Access, Supports Writing
Caption: SAMSUNG HD503HI ATA Device
ConfigManagerErrorCode: 0
ConfigManagerUserConfig: False
CreationClassName: Win32_DiskDrive
Description: Stacja dysków
DeviceID: \\.\PHYSICALDRIVE0
FirmwareRevision: 1AJ100E4
Index: 0
InterfaceType: IDE
Manufacturer: (Standardowe stacje dysków)
MediaLoaded: True
MediaType: Fixed hard disk media
Model: SAMSUNG HD503HI ATA Device
Name: \\.\PHYSICALDRIVE0
Partitions: 2
PNPDeviceID: IDE\DISKSAMSUNG_HD503HI_________________________1AJ100E4\5&10E28988&0&0.0.0
SCSIBus: 0
SCSILogicalUnit: 0
SCSIPort: 0
SCSITargetId: 0
SectorsPerTrack: 63
SerialNumber: 32534333394a5341303839303033202020202020
Signature: 1349537903
Size: 500105249280
Status: OK
SystemCreationClassName: Win32_ComputerSystem
SystemName:
TotalCylinders: 60801
TotalHeads: 255
TotalSectors: 976768065
TotalTracks: 15504255
TracksPerCylinder: 255


Pogrubiłem informacje które mnie interesują. Od czego zależy to, że w jednym komputerze jest zwracane jedno w innym drugie ?? Czy są jakieś wspólne informacje dla wszystkich komputerów ???
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaSafari

Re: WMI - problem z różnymi komputerami

Nowy postprzez Cyfrowy Baron » czwartek, 20 maja 2010, 12:01

U mnie np. klasa Win32_BaseBoard nie zwraca żadnych informacji o płycie głównej, ale klasa Win32_MotherboardDevice już takie informacje podaje, ale niepełne, brak informacji o producencie. Podobnie jak u Ciebie nie udało mi się uzyskać numeru seryjnego dysku.
Przeglądałem pliki pomocy, ale niczego nie mogę znaleźć.

Podaję nieco zmieniony kod w stosunku do tego co jest dostępne w serwisie Cyfrowy Baron, dla środowiska C++Builder 2009 i 2010:

Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

#include <Wbemidl.h> // wymagana biblioteka
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

#pragma comment(lib, "wbemuuid.lib")

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
CoInitializeEx(0, COINIT_MULTITHREADED);
if(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0) != S_OK)
{
  ShowMessage("Błąd inicjowania interfejsu WMI");
  Button1->Enabled = false;
  Button2->Enabled = false;
  CoUninitialize();
}
}
//---------------------------------------------------------------------------
String TranslateWMI(String text)
{
String TableWMI[] =
{
  "Caption", "Name", "Description", "Manufacturer", "DeviceID",
  "Description", "SystemName", "SystemCreationClassName", "BIOSVersion", "Version",
  "ReleaseDate"
};

String TableTranslate[] =
{
  "Nagłówek", "Nazwa", "Typ urządzenia", "Producent", "Identyfikator wystąpienia urządzenia",
  "Opis", "Nazwa komputera", "Klasa systemu", "Wersja BIOS'u", "Wersja",
  "Wersja danych"
};

for(DWORD i = 0; i < ARRAYSIZE(TableWMI); i++)
{
  if(SameText(text, TableWMI[i])) return TableTranslate[i];
}
return text;
}
//---------------------------------------------------------------------------
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 = "root\\cimv2";

  if(pWbemLocator->ConnectServer(wsNamespace.w_str(), NULL, NULL, 0, NULL, 0, 0,
                                &pWbemServices) == S_OK)
  {
      HRESULT hres = CoSetProxyBlanket(
       pWbemServices,
       RPC_C_AUTHN_WINNT,
       RPC_C_AUTHZ_NONE,
       NULL,
       RPC_C_AUTHN_LEVEL_CALL,
       RPC_C_IMP_LEVEL_IMPERSONATE,
       NULL,
       EOAC_NONE
    );

    if(FAILED(hres))
    {
        ShowMessage("Could not set proxy blanket");
        pWbemServices->Release();
        pWbemLocator->Release();
        CoUninitialize();
        return;
    }

   IEnumWbemClassObject *pEnumClassObject = NULL;
   String wsWQL = "WQL",
   wsQuery = "Select * from " + wsClass;

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

     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(TranslateWMI(String(wsName)) + ": " + lValue); // tutaj podłączono tłumaczenie
        }
        VariantClear(&vValue);
        SysFreeString(wsName);
       }
      }
      if(pvNames) SafeArrayDestroy(pvNames);

     }
    }
    if(pClassObject) pClassObject->Release();
   }
   if(pEnumClassObject) pEnumClassObject->Release();
  }
  if(pWbemServices) pWbemServices->Release();
}
if(pWbemLocator) pWbemLocator->Release();

}
//---------------------------------------------------------------------------
char *WMIResources[] =
{
"Win32_1394Controller",
"Win32_BaseBoard",
"Win32_Battery",
"Win32_BIOS",
"Win32_Bus",
"Win32_CacheMemory",
"Win32_CurrentProbe",
"Win32_DesktopMonitor",
"Win32_DeviceMemoryAddress",
"Win32_DiskDrive",
"Win32_DisplayConfiguration",
"Win32_DisplayControllerConfiguration",
"Win32_DMAChannel",
"Win32_Fan",
"Win32_FloppyController",
"Win32_FloppyDrive",
"Win32_HeatPipe",
"Win32_IDEController",
"Win32_InfraredDevice",
"Win32_IRQResource",
"Win32_Keyboard",
"Win32_MemoryArray",
"Win32_MemoryDevice",
"Win32_MotherboardDevice",
"Win32_NetworkAdapter",
"Win32_NetworkAdapterConfiguration",
"Win32_OnBoardDevice",
"Win32_ParallelPort",
"Win32_PCMCIAController",
"Win32_PhysicalMemory",
"Win32_PhysicalMemoryArray",
"Win32_PnPEntity",
"Win32_PointingDevice",
"Win32_PortableBattery",
"Win32_PortConnector",
"Win32_PortResource",
"Win32_POTSModem",
"Win32_PowerManagementEvent",
"Win32_Printer",
"Win32_PrinterConfiguration",
"Win32_PrintJob",
"Win32_Processor",
"Win32_Refrigeration",
"Win32_SerialPort",
"Win32_SerialPortConfiguration",
"Win32_SMBIOSMemory",
"Win32_SoundDevice",
"Win32_SystemEnclosure",
"Win32_SystemMemoryResource",
"Win32_SystemSlot",
"Win32_TapeDrive",
"Win32_TemperatureProbe",
"Win32_UninterruptiblePowerSupply",
"Win32_USBController",
"Win32_VideoConfiguration",
"Win32_VideoController",
"Win32_VoltageProbe",
"Win32_CDROMDrive",
NULL
};
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
::SetCursor(LoadCursor(NULL, IDC_WAIT));

Button1->Enabled = false;
Button2->Enabled = false;

Memo1->Lines->Clear();
Memo1->Lines->Add("• =============== [Win32_BIOS] =================");
WMIInfo(Memo1->Lines, "Win32_MotherboardDevice");
Memo1->Lines->Add("");
WMIInfo(Memo1->Lines, "Win32_DiskDrive");

::SetCursor(LoadCursor(NULL, NULL));

Button1->Enabled = true;
Button2->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
::SetCursor(LoadCursor(NULL, IDC_WAIT));

Button1->Enabled = false;
Button2->Enabled = false;

Memo1->Lines->Clear();
for(int i = 0; WMIResources[i]; i++)
{
  Memo1->Lines->Add("• =============== [" + String(WMIResources[i]) + "] =================");
  WMIInfo(Memo1->Lines, WMIResources[i]);
  Memo1->Lines->Add("");
}

::SetCursor(LoadCursor(NULL, NULL));

Button1->Enabled = true;
Button2->Enabled = true;
}
//---------------------------------------------------------------------------
__fastcall  TForm1::~TForm1() // destruktor klasy formularza
{
CoUninitialize();
}
//---------------------------------------------------------------------------
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: WMI - problem z różnymi komputerami

Nowy postprzez Corvis » czwartek, 20 maja 2010, 12:10

Dzięki,

Potrezbuje tego do zrobienia klucza ID_KOMPUTERA.

Może słyszałeś o gotowych komponentach do tego ???

pozdrawiam
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaSafari

Re: WMI - problem z różnymi komputerami

Nowy postprzez Cyfrowy Baron » czwartek, 20 maja 2010, 12:38

Tutaj http://www.magsys.co.uk/delphi/magwmi.asp jakowyś jest. Nie sprawdzałem go jeszcze.

A tutaj link bezpośrednio do pobrania: http://www.magsys.co.uk/download/software/magwmi52.zip
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: WMI - problem z różnymi komputerami

Nowy postprzez Cyfrowy Baron » czwartek, 20 maja 2010, 12:56

Tutaj http://pastebin.com/2FYZS1KN jest kod, który powinien pomóc. Wymaga jednak przeanalizowania i dostosowania do własnych potrzeb. Przyjże mu się w wolnej chwili.
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: WMI - problem z różnymi komputerami

Nowy postprzez starjacker0 » środa, 21 lipca 2010, 09:22

Jak z tego otrzymać tylko jeden element zamiast całej listy, np.: Serial Number dysku lub Size dysku, bez tych Captionów, czyli bez wyrażenia Serial Number: lub Size:, po prostu samą wartość?
Avatar użytkownika
starjacker0
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): wtorek, 20 lipca 2010, 11:37
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7 64-bit
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Firefox

Re: WMI - problem z różnymi komputerami

Nowy postprzez Cyfrowy Baron » środa, 21 lipca 2010, 10:35

Jeżeli chodzi o kod zamieszczony ► patrz serwis: Cyfrowy Baron to gdybyś go przeanalizował zobaczyłbyś iż wszystko jest ładowane do listy Memo w pętli:

KOD cpp:     UKRYJ  
for(long  idx = vbl; idx <= vbu; idx++)
{

Pętla przeszukuje wszystkie rekordy danej klasy i jeżeli rekord nie jest pusty:

KOD cpp:     UKRYJ  
if(!lValue.IsEmpty())
  lpList->Add(TranslateWMI(String(wsName)) + ": " + lValue); // tutaj podłączono tłumaczenie

To dodaje go do listy. Warunkiem dodania elementu do listy jest to by rekord nie był pusty. Możesz dodać kolejny warunek, czyli jeżeli rekord nie jest pusty i rekord zawiera to co Ciebie interesuje to zwracasz wynik:
KOD cpp:     UKRYJ  
if( !lValue.IsEmpty() && wsName == "SerialNumber") return lValue;


Oczywiście warunek w !lValue.IsEmpty() lepiej pominąć, gdyż chodzi o to by funkcja sprawdziła dany rekord a nie to czy jest on pusty. Mozna też ewentualnie tak:

Kod: Zaznacz cały
if( wsName == "SerialNumber" )
{
 if( lValue.IsEmpty() ) return "0";
 return lValue;
}
 

Funkcja przedstawiona ► patrz serwis: Cyfrowy Baron nie zwraca numeru dysku w systemie Windows XP, wymaga dopracowania.
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: WMI - problem z różnymi komputerami

Nowy postprzez starjacker0 » sobota, 24 lipca 2010, 10:04

Niestety dodanie tego:
Kod: Zaznacz cały
&& wsName == "SerialNumber"

lub zamiast tego Size, Status itp. nie pomaga. Zwraca mi tylko puste linie.
Bestią jestem, by się bestią nie stać
Avatar użytkownika
starjacker0
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): wtorek, 20 lipca 2010, 11:37
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7 64-bit
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Firefox

Re: WMI - problem z różnymi komputerami

Nowy postprzez Cyfrowy Baron » sobota, 24 lipca 2010, 13:44

W Windows XP wersja 32 bitowa, gdyż aktualnie tylko do tego mam dostęp, udało mi się sprawdzić numer seryjny dysku. Przy czym mam jeden dysk więc będzie to dla tego jednego, przy dwóch mogą być problemy tego typu, że funkcja zwróci wartości ostatniego wyliczonego dysku HDD. By sprawdzić ID dysku (Caption) należy przekazać do funkcji WMIInfo klasę Win32_DiskDrive, jednak by otrzymać numer seryjny dysku należy przekazać klasę Win32_PhysicalMedia.

KOD cpp:     UKRYJ  
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <Wbemidl.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

# pragma comment(lib, "wbemuuid.lib") // w BCB 2010 - zbędne


TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 CoInitializeEx(0, COINIT_MULTITHREADED);

if(CoInitializeSecurity( NULL, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_PKT/*RPC_C_AUTHN_LEVEL_DEFAULT*/,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL ) != S_OK)
 {
  ShowMessage("Błąd inicjowania interfejsu WMI");
  Button1->Enabled = false;
 }
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1() // destruktor klasy formularza
{
 CoUninitialize();
}
//---------------------------------------------------------------------------
String WMIInfo(String wsClass, String wsType)
{
 String Result = "brak wartości";

 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 = L"ROOT\\CIMV2";

  if(pWbemLocator->ConnectServer( wsNamespace.w_str(), NULL, NULL, NULL, 0, NULL,
     NULL, &pWbemServices) == S_OK)
  {
    if (CoSetProxyBlanket(
                   pWbemServices,
                   RPC_C_AUTHN_WINNT,
                   RPC_C_AUTHZ_NONE,
                   NULL,
                   RPC_C_AUTHN_LEVEL_CALL,
                   RPC_C_IMP_LEVEL_IMPERSONATE,
                   NULL,
                   EOAC_NONE
               ) != S_OK)
    {
      return "błąd Proxy";
    }

   IEnumWbemClassObject *pEnumClassObject = NULL;
   String wsWQL = "WQL", wsQuery = "SELECT * FROM " + wsClass;

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

     while(pEnumClassObject->Next( WBEM_INFINITE, uCount, &pClassObject, &uReturned)
            == S_OK)
     {
      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( String(wsName).LowerCase() == wsType.LowerCase() )
        {
         if( lValue.IsEmpty() ) Result =  "brak wartości";
         else Result = lValue;
        }
       }
        VariantClear(&vValue);
        SysFreeString(wsName);
       }
      }
      if(pvNames) SafeArrayDestroy(pvNames);

     }
    }
    if(pClassObject) pClassObject->Release();
   }


   if(pEnumClassObject) pEnumClassObject->Release();
  }
  if(pWbemServices) pWbemServices->Release();
 }
 if(pWbemLocator) pWbemLocator->Release();

 return Result.Trim();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 ::SetCursor(LoadCursor(NULL, IDC_WAIT));

 Button1->Enabled = false;

 Memo1->Lines->Clear();

 Memo1->Lines->Add(WMIInfo("Win32_DiskDrive", "Caption"));
 Memo1->Lines->Add(WMIInfo("Win32_PhysicalMedia", "SerialNumber"));

 ::SetCursor(LoadCursor(NULL, NULL));

 Button1->Enabled = true;
}


Jak wspomniałem funkcja zwróci dane o ostatnim wyliczonym dysku HDD. Można odwołać się do konkretnego dysku, czyli np. do pierwszego podając wartość:

dla klasy Win32_DiskDrive: "Win32_DiskDrive WHERE Index = 0" gdzie Index = 0 to numer dysku HDD, 0 = pierwszy
dla klasy Win32_PhysicalMedia "Win32_PhysicalMedia WHERE Tag='\\\\.\\PHYSICALDRIVE0'" gdzie \\\\.\\PHYSICALDRIVE0 to Tag oznaczający pierwszy dysk HDD, ale to nie zwróci wartości i nie wiem dlaczego...

Index to element klasy Win32_DiskDrive podobnie jak Caption:
KOD cpp:     UKRYJ  
class Win32_DiskDrive : CIM_DiskDrive
{
  uint16 Availability;
  uint32 BytesPerSector;
  uint16 Capabilities[];
  string CapabilityDescriptions[];
  string Caption;                                // <-- TUTAJ
  string CompressionMethod;
  uint32 ConfigManagerErrorCode;
  boolean ConfigManagerUserConfig;
  string CreationClassName;
  uint64 DefaultBlockSize;
  string Description;
  string DeviceID;
  boolean ErrorCleared;
  string ErrorDescription;
  string ErrorMethodology;
  string FirmwareRevision;
  uint32 Index;                                 // <-- TUTAJ
  datetime InstallDate;
  string InterfaceType;
  uint32 LastErrorCode;
  string Manufacturer;
  uint64 MaxBlockSize;
  uint64 MaxMediaSize;
  boolean MediaLoaded;
  string MediaType;
  uint64 MinBlockSize;
  string Model;
  string Name;
  boolean NeedsCleaning;
  uint32 NumberOfMediaSupported;
  uint32 Partitions;
  string PNPDeviceID;
  uint16 PowerManagementCapabilities[];
  boolean PowerManagementSupported;
  uint32 SCSIBus;
  uint16 SCSILogicalUnit;
  uint16 SCSIPort;
  uint16 SCSITargetId;
  uint32 SectorsPerTrack;
  string SerialNumber;
  uint32 Signature;
  uint64 Size;
  string Status;
  uint16 StatusInfo;
  string SystemCreationClassName;
  string SystemName;
  uint64 TotalCylinders;
  uint32 TotalHeads;
  uint64 TotalSectors;
  uint64 TotalTracks;
  uint32 TracksPerCylinder;
};
 


Tag to element klasy Win32_PhysicalMedia podobnie jak element SerialNumber:
KOD cpp:     UKRYJ  
class Win32_PhysicalMedia : CIM_PhysicalMedia
{
  string Caption;
  string Description;
  datetime InstallDate;
  string Name;
  string Status;
  string CreationClassName;
  string Manufacturer;
  string Model;
  string SKU;
  string SerialNumber = NULL;  // <-- TUTAJ
  string Tag = NULL;                // <-- TUTAJ
  string Version;
  string PartNumber;
  string OtherIdentifyingInfo;
  boolean PoweredOn;
  boolean Removable;
  boolean Replaceable;
  boolean HotSwappable;
  uint64 Capacity;
  uint16 MediaType;
  string MediaDescription;
  boolean WriteProtectOn;
  boolean CleanerMedia;
};
 


Teoretycznie więc wartość "Win32_PhysicalMedia WHERE Tag='\\\\.\\PHYSICALDRIVE0'" powinna zwrócić numer seryjny pierwszego dysku, gdyż:

KOD cpp:     UKRYJ  
 Memo1->Lines->Add(WMIInfo("Win32_PhysicalMedia", "Tag"));


dla jednego dysku w komputerze zwróci właśnie \\.\PHYSICALDRIVE0.

To tyle jeżeli chodzi o WMI, ten temat jest mi słabo znany, nie posiadam żadnej wiedzy o tym jak działa ta funkcja w systemach innych niż WinXP.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
starjacker0
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: WMI - problem z różnymi komputerami

Nowy postprzez starjacker0 » niedziela, 25 lipca 2010, 10:08

Jeżeli zmienie tak, jak podales, to pokazuje nazwe dysku, ale w przypadku SerialNumber brak wartosci.
Wiec zrobiłem cos takiego:
w button1 dalem tan kod:
Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{
::SetCursor(LoadCursor(NULL, IDC_WAIT));

Button1->Enabled = false;

Memo1->Lines->Clear();

Memo1->Lines->Add(WMIInfo("Win32_DiskDrive WHERE Index = 0", "SerialNumber"));

::SetCursor(LoadCursor(NULL, NULL));

Button1->Enabled = true;
}


I to dziala pod Win7 64-bit (o ile numer seryjny fizycznego dysku sklada sie z 40 znaków).
Bestią jestem, by się bestią nie stać
Avatar użytkownika
starjacker0
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): wtorek, 20 lipca 2010, 11:37
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7 64-bit
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Firefox

Re: WMI - problem z różnymi komputerami

Nowy postprzez Cyfrowy Baron » niedziela, 25 lipca 2010, 10:39

No i właśnie w tym problem, że w Windows XP jest z WMI coś nie tak, gdyż podany kod nie zwróci żadnych informacji.
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: WMI - problem z różnymi komputerami

Nowy postprzez starjacker0 » niedziela, 25 lipca 2010, 11:09

To mozna napisac funkcje sprawdzajaca system i po wykryciu danego systemu uzywac konkretnego kodu. Tak mi sie wydaje.
Bestią jestem, by się bestią nie stać
Avatar użytkownika
starjacker0
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): wtorek, 20 lipca 2010, 11:37
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7 64-bit
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Firefox

Re: WMI - problem z różnymi komputerami

Nowy postprzez starjacker0 » poniedziałek, 13 września 2010, 18:29

Kod mojej biblioteki:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#include <Wbemidl.h>
#pragma hdrstop

#pragma argsused
//---------------------------------------------------------------------------

String WMIInfo(String wsClass, String wsType)
{
 String Result = "brak wartości";

 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 = L"ROOT\\CIMV2";

  if(pWbemLocator->ConnectServer( wsNamespace.w_str(), NULL, NULL, NULL, 0, NULL,
     NULL, &pWbemServices) == S_OK)
  {
    if (CoSetProxyBlanket(
                   pWbemServices,
                   RPC_C_AUTHN_WINNT,
                   RPC_C_AUTHZ_NONE,
                   NULL,
                   RPC_C_AUTHN_LEVEL_CALL,
                   RPC_C_IMP_LEVEL_IMPERSONATE,
                   NULL,
                   EOAC_NONE
               ) != S_OK)
    {
      return "błąd Proxy";
    }

   IEnumWbemClassObject *pEnumClassObject = NULL;
   String wsWQL = "WQL", wsQuery = "SELECT * FROM " + wsClass;

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

     while(pEnumClassObject->Next( WBEM_INFINITE, uCount, &pClassObject, &uReturned)
            == S_OK)
     {
      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( String(wsName).LowerCase() == wsType.LowerCase() )
        {
         if( lValue.IsEmpty() ) Result =  "brak wartości";
         else Result = lValue;
        }
       }
        VariantClear(&vValue);
        SysFreeString(wsName);
       }
      }
      if(pvNames) SafeArrayDestroy(pvNames);

     }
    }
    if(pClassObject) pClassObject->Release();
   }


   if(pEnumClassObject) pEnumClassObject->Release();
  }
  if(pWbemServices) pWbemServices->Release();
 }
 if(pWbemLocator) pWbemLocator->Release();

 return Result.Trim();
}
//---------------------------------------------------------------------------
char *WMIResources[] =
{
"Win32_1394Controller",
"Win32_BaseBoard",
"Win32_Battery",
"Win32_BIOS",
"Win32_Bus",
"Win32_CacheMemory",
"Win32_CurrentProbe",
"Win32_DesktopMonitor",
"Win32_DeviceMemoryAddress",
"Win32_DiskDrive",
"Win32_DisplayConfiguration",
"Win32_DisplayControllerConfiguration",
"Win32_DMAChannel",
"Win32_Fan",
"Win32_FloppyController",
"Win32_FloppyDrive",
"Win32_HeatPipe",
"Win32_IDEController",
"Win32_InfraredDevice",
"Win32_IRQResource",
"Win32_Keyboard",
"Win32_MemoryArray",
"Win32_MemoryDevice",
"Win32_MotherboardDevice",
"Win32_NetworkAdapter",
"Win32_NetworkAdapterConfiguration",
"Win32_OnBoardDevice",
"Win32_ParallelPort",
"Win32_PCMCIAController",
"Win32_PhysicalMemory",
"Win32_PhysicalMemoryArray",
"Win32_PnPEntity",
"Win32_PointingDevice",
"Win32_PortableBattery",
"Win32_PortConnector",
"Win32_PortResource",
"Win32_POTSModem",
"Win32_PowerManagementEvent",
"Win32_Printer",
"Win32_PrinterConfiguration",
"Win32_PrintJob",
"Win32_Processor",
"Win32_Refrigeration",
"Win32_SerialPort",
"Win32_SerialPortConfiguration",
"Win32_SMBIOSMemory",
"Win32_SoundDevice",
"Win32_SystemEnclosure",
"Win32_SystemMemoryResource",
"Win32_SystemSlot",
"Win32_TapeDrive",
"Win32_TemperatureProbe",
"Win32_UninterruptiblePowerSupply",
"Win32_USBController",
"Win32_VideoConfiguration",
"Win32_VideoController",
"Win32_VoltageProbe",
"Win32_CDROMDrive",
NULL
};

extern "C" __declspec(dllexport)char* __fastcall HDD_SN_0(int MajV1, int MinV1) {    //pobiera numer seryjny dysku twardego zależnie od wersji systemu: int MajV1 - główny numer systemu (np. 5 dla WinXp), int MinV1 - podrzędny numer systemu, po kropce (np. 1 dla WinXP)
int MV1 = MajV1;
int MiV1 = MinV1;
 CoInitializeEx(0, COINIT_MULTITHREADED);

if(CoInitializeSecurity( NULL, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_PKT/*RPC_C_AUTHN_LEVEL_DEFAULT*/,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL ) != S_OK)
 {
  ShowMessage("Błąd inicjowania interfejsu WMI");
 }

::SetCursor(LoadCursor(NULL, IDC_WAIT));
AnsiString SN0;
if (MV1 == 6) {
    if (MiV1 >= 0) {
        SN0 = WMIInfo("Win32_DiskDrive WHERE Index = 0", "SerialNumber");
    }
}
 ::SetCursor(LoadCursor(NULL, NULL));

  CoUninitialize();

char *SeNu0;
SeNu0 = SN0.c_str();

  CoUninitialize();

return SeNu0;
}

extern "C" __declspec(dllexport)void Un1(void)    {  //zamknięcie interfejsu WMI
  CoUninitialize();
}


Mam kilka problemow:
1) interfejs WMI nie chce byc zamkniety, jezeli nie wywolam funkcji:
extern "C" __declspec(dllexport)void Un1(void) { //zamknięcie interfejsu WMI

2) najwazniejszym problemem jest to, ze gdy klikne w mojej aplikacji Otwórz lub Zapisz, czyli wywolam to okno dialogowe, a nastepnie (po zamknieciu juz okna odczytu/zapisu) wywolam funkcje odczytujaca serial HDD z mojej biblioteki, to pojawia sie ShowMessage z tego fragmentu kodu:
KOD cpp:     UKRYJ  
if(CoInitializeSecurity( NULL, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_PKT/*RPC_C_AUTHN_LEVEL_DEFAULT*/,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL ) != S_OK)
 {
  ShowMessage("Błąd inicjowania interfejsu WMI"); <- to się pojawia
 }
nastepnie gdy chce cos wczytac lub zapisac, to juz te okna dialogowe od tego nie pojawiaja sie.
Z kolei, gdy nie wczytam niczego i nie zapisze nic, to wywolanie funkcji odczytujacej serial HDD z mojej biblioteki przebiega bezproblemowo (bez zadnego komunikatu), ale niestety pozniej tez przestaja dzialac okna dialogowe od odczytu i zapisu plikow.

Prosze o pomoc w rozwiazaniu problemu.
Bestią jestem, by się bestią nie stać
Avatar użytkownika
starjacker0
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): wtorek, 20 lipca 2010, 11:37
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7 64-bit
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Firefox

Re: WMI - problem z różnymi komputerami

Nowy postprzez polymorphism » poniedziałek, 13 września 2010, 21:03

  • Czemu dwa razy wywołujesz CoUninitialize wewnątrz funkcji HDD_SN_0? Ta funkcja powinna być wywołana tyle razy, ile CoInitializeEx, gdy zwróci S_OK lub S_FALSE.
  • CoInitializeSecurity zwraca różne wartości błędów, dobrze by było, gdybyś podał wartość, którą zwraca w przypadku błędu. Podejrzewam, że zwraca RPC_E_TOO_LATE, ale kto wie... Swoją drogą ciekawy warunek, z którego poza messageboxem nic nie wynika.
  • Masz błąd, poważny:
    KOD cpp:     UKRYJ  
            AnsiString SN0;

            ...

            char *SeNu0;
            SeNu0 = SN0.c_str();

            return SeNu0;
    }
     

    Zwracasz wskaźnik na pamięć, która po wyjściu z tej funkcji formalnie nie istnieje. Obiekt SN0 jest niszczony przed opuszczeniem funkcji.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: WMI - problem z różnymi komputerami

Nowy postprzez starjacker0 » wtorek, 14 września 2010, 09:14

Kod biblioteki strjckrWMI.dll, po poprawkach:
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#include <Wbemidl.h>
#pragma hdrstop

#pragma argsused
//---------------------------------------------------------------------------

String WMIInfo(String wsClass, String wsType)
{
String Result = "brak wartości";

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 = L"ROOT\\CIMV2";

  if(pWbemLocator->ConnectServer( wsNamespace.w_str(), NULL, NULL, NULL, 0, NULL,
     NULL, &pWbemServices) == S_OK)
  {
    if (CoSetProxyBlanket(
                   pWbemServices,
                   RPC_C_AUTHN_WINNT,
                   RPC_C_AUTHZ_NONE,
                   NULL,
                   RPC_C_AUTHN_LEVEL_CALL,
                   RPC_C_IMP_LEVEL_IMPERSONATE,
                   NULL,
                   EOAC_NONE
               ) != S_OK)
    {
      return "błąd Proxy";
    }

   IEnumWbemClassObject *pEnumClassObject = NULL;
   String wsWQL = "WQL", wsQuery = "SELECT * FROM " + wsClass;

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

     while(pEnumClassObject->Next( WBEM_INFINITE, uCount, &pClassObject, &uReturned)
            == S_OK)
     {
      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( String(wsName).LowerCase() == wsType.LowerCase() )
        {
         if( lValue.IsEmpty() ) Result =  "brak wartości";
         else Result = lValue;
        }
       }
        VariantClear(&vValue);
        SysFreeString(wsName);
       }
      }
      if(pvNames) SafeArrayDestroy(pvNames);

     }
    }
    if(pClassObject) pClassObject->Release();
   }


   if(pEnumClassObject) pEnumClassObject->Release();
  }
  if(pWbemServices) pWbemServices->Release();
}
if(pWbemLocator) pWbemLocator->Release();

return Result.Trim();
}
//---------------------------------------------------------------------------
char *WMIResources[] =
{
"Win32_1394Controller",
"Win32_BaseBoard",
"Win32_Battery",
"Win32_BIOS",
"Win32_Bus",
"Win32_CacheMemory",
"Win32_CurrentProbe",
"Win32_DesktopMonitor",
"Win32_DeviceMemoryAddress",
"Win32_DiskDrive",
"Win32_DisplayConfiguration",
"Win32_DisplayControllerConfiguration",
"Win32_DMAChannel",
"Win32_Fan",
"Win32_FloppyController",
"Win32_FloppyDrive",
"Win32_HeatPipe",
"Win32_IDEController",
"Win32_InfraredDevice",
"Win32_IRQResource",
"Win32_Keyboard",
"Win32_MemoryArray",
"Win32_MemoryDevice",
"Win32_MotherboardDevice",
"Win32_NetworkAdapter",
"Win32_NetworkAdapterConfiguration",
"Win32_OnBoardDevice",
"Win32_ParallelPort",
"Win32_PCMCIAController",
"Win32_PhysicalMemory",
"Win32_PhysicalMemoryArray",
"Win32_PnPEntity",
"Win32_PointingDevice",
"Win32_PortableBattery",
"Win32_PortConnector",
"Win32_PortResource",
"Win32_POTSModem",
"Win32_PowerManagementEvent",
"Win32_Printer",
"Win32_PrinterConfiguration",
"Win32_PrintJob",
"Win32_Processor",
"Win32_Refrigeration",
"Win32_SerialPort",
"Win32_SerialPortConfiguration",
"Win32_SMBIOSMemory",
"Win32_SoundDevice",
"Win32_SystemEnclosure",
"Win32_SystemMemoryResource",
"Win32_SystemSlot",
"Win32_TapeDrive",
"Win32_TemperatureProbe",
"Win32_UninterruptiblePowerSupply",
"Win32_USBController",
"Win32_VideoConfiguration",
"Win32_VideoController",
"Win32_VoltageProbe",
"Win32_CDROMDrive",
NULL
};

extern "C" __declspec(dllexport)AnsiString __fastcall HDD_SN_0(int MajV1, int MinV1) {    //pobiera numer seryjny dysku twardego zależnie od wersji systemu: int MajV1 - główny numer systemu (np. 5 dla WinXp), int MinV1 - podrzędny numer systemu, po kropce (np. 1 dla WinXP)
int MV1 = MajV1;
int MiV1 = MinV1;
CoInitializeEx(0, COINIT_MULTITHREADED);

if(CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT/*RPC_C_AUTHN_LEVEL_DEFAULT*/, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ) != S_OK)
{
  ShowMessage("Błąd inicjowania interfejsu WMI");
}

  CoUninitialize();

::SetCursor(LoadCursor(NULL, IDC_WAIT));
AnsiString SN0;
if (MV1 == 6) {
    if (MiV1 >= 0) {
        SN0 = WMIInfo("Win32_DiskDrive WHERE Index = 0", "SerialNumber");
    }
}
::SetCursor(LoadCursor(NULL, NULL));

return SN0;
}

extern "C" __declspec(dllexport)void Un1(void)    {  //zamknięcie interfejsu WMI
  CoUninitialize();
}


Kod aplikacji wywołujacy te funkcje (w OnClick na Menu "Rejestracja":
Kod: Zaznacz cały
int Fn1 = SystemVer1(); //funkcja pobierająca Major Version systemu (z innej biblioteki)
int Sn2 = SystemVer2(); //funkcja pobierająca Minor Version systemu (z innej biblioteki)
AnsiString Snu1 = HDD_SN_0(Fn1, Sn2); //wywołanie funkcji z powyższej biblioteki (strjckrWMI.dll) do pobrania seriala HDD
AnsiString asaq = Form1->Caption; //pobranie nazwy aplikacji
rej1(asaq); //wywołanie funkcji, która wpisze nazwę aplikacji do formularza z innej biblioteki
rej4(); //pobranie informacji z rejestru o różnych elementach komputera (np. procesor) z innej biblioteki
ace:
if (Snu1 != NULL) {
    rej5(Snu1); //wpisanie serial HDD do formularza z innej biblioteki
}
else    {
    goto ace;
}


Jak widac, tylko raz odwoluje sie do biblioteki strjckrWMI.dll. Sprawdzilem warianty bez tej biblioteki (czyli bez sprawdzania SN HDD) oraz tylko z nia i widze, ze problemy z bledem interfejsu WMI oraz dialogiem do odczytu/zapisu sprawia tylko biblioteka strjckrWMI.dll.

Co do pobrania rodzaju błedu: przejrzalem MSDN a i tak nie zdolalem tego zrobic. Jak dla mnie WMI jest malo zrozumiale, a powyzszy kod sklecilem na podstawie wczesniejszych postow Cyfrowego Barona.
Bestią jestem, by się bestią nie stać
Avatar użytkownika
starjacker0
Bladawiec
Bladawiec
 
Posty: 11
Dołączył(a): wtorek, 20 lipca 2010, 11:37
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows 7 64-bit
Kompilator: C++ Builder 2010
Gadu Gadu: 0
    Windows 7Firefox

Następna strona

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 4 gości