Akkus erkennen & SYSTEM_POWER_STATUS vs.SYSTEM_BATTERY_S

Für allgemeine Fragen zur Programmierung mit PureBasic.
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Aha, durch vieeeeeeeeeeeeeel suchen, tagelang bin ich auf etwas gestoßen.
Auf der Seite
http://dotnet247.com/247reference/msgs/21/109256.aspx
stand folgendes.
After much hair pulling, I've figured it out.

Do not do this:
detailData.cbSize =Marshal.SizeOf(typeof
(Win32Methods.SP_DEVICE_INTERFACE_DETAIL_DATA));

Marshal.SizeOf returns a size of 8 for the struct which is
not what the setupapi is expecting. The setupapi expects
the original size of the struct. Looking at the header
files in the DDK, I calculated the size to be 5 for the
ANSI version of the function and 6 for the Unicode.

That's what was hanging me up. I forgot I was calling the
Unicode version.

Regards,
Kevin
Ich habe zwar keine Ahnung woher der Junge das hat und ich verstehe so gut wie nichts was da steht, konnte aber erkenne, das die Funktion wohl 5 oder 6 ZEichen erwartet. Nachdem ihr mich so schön über .s und .c aufgeklärt habt und ich dann mal wieder getestet habe, scheint es zu klappen, wenn ichi
devicePAth.c nehme.
zwar habe ich noch nicht genau rausgefunden, wie ich nun die Requierdsize genau ausrechnen soll, aber das teste ich später, morgen oder wenn ich mir einen neuen PC gekauft habe, dieser ich schon halb aus dem Fenster geflogen.

Hoffentlich habe ich mich jetzt nicht zu früh gefreut, denn ich schlafe schon zu 2/3.

was ich aber nicht verstehe ist, weshalb IDEV (der schleifenzähler) im originalcode auf der MSDN-Seite (und bei allen umsetzugen die ich gefunden habe)immer um 2 hochgezählt wird, habe das bei meinem Code noch nicht gemacht.

Ach bitte, sagt mal, hat jemand von euch ein Notebook? bei mir wird immer das selbe ausgegeben, egal wieviel akkus drinn sind und wenn ich dann auch noch IDEV++ mache, komme ich wieder nicht zur "Errormeldung 259". Gibt also noch viel zu lösen ;-)

[edit]habe ein bissl weiter versucht.
was könnte IOCTL_BATTERY_QUERY_INFORMATION und BATTERY_QUERY_INFORMATION_LEVEL InformationLevel sein, ist das etwas was ich mit Datasection erstellen muß oder mit enumeration einfach ne konstantenliste erstellen"?
Bei BATTERY_QUERY_INFORMATION_LEVEL hatte ich auf Grund einer Headerdatei gedacht es sind Konstantenwerte, in der Vorlage von MSDN steht

Code: Alles auswählen

bqi.InformationLevel = BatteryInformation
und ich habe keine Ahnung was das bedeuten soll.

Wenn ich das noch mit Eurer Hilfe rausbekomme / verstehe, dann bin ich langsam durch den größten Kram durch und kann mal einen kompletten Testcode angehen.
[/edit]

[edit=080220070816]ich bin endlich soweit,das ich einen Großteil verstanden und erste Erfolge habe:-) Ohne Eure Hilfe wäre das unmöglich. Besonderen dann an edel[/edit]

Gruß
Toshy
1. Win10
PB6.1
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

so, ich bin relativ weit gekommen. ich werde nun anfangen etwas ordnung in den Code zu bekommen und mir meine Routinen erstellen. Bin aber natürlich noch immer am testen um alles besserzu verstehen, noch klappt ja nicht alles.

Ich habe noch eine wichtige Frage in C++ steht zum Thema folgendes

Code: Alles auswählen

for (int idev = 0; idev < 100; idev++)
Ich hatte nun das "++" als "+2" interpretiert, wird hier die Schleife um einen Wert oder zwei hoch gezählt?
Ich denke laut Beispielvorlage auf MSDN um Zwei, aber es klappt bei mir nur, wenn ich um den WErt EINS erhöhe.

Gruß
Toshy
1. Win10
PB6.1
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Code: Alles auswählen

Define idev.l = 0

While idev < 100
  idev + 1
Wend
so ungefähr :wink:
oder so:

Code: Alles auswählen

Define idev.l
For idev = 0 To 100 - 1

Next idev
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

In c++ ist ein "var++" das gleiche (Zeiger ausgenommen) wie in pb "var + 1"
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Habe ein "Unicodeproblem" bei Folgendem(Codeauszug,gestückelt):

Code: Alles auswählen

Structure BATTERY_INFORMATION
  Capabilities.l
  Technology.c
  reserved.c[3]
  Chemistry.c[4]
  DesignedCapacity.l
  FullChargedCapacity.l
  DefaultAlert1.l
  DefaultAlert2.l
  CriticalBias.l
  CycleCount.l
EndStructure
 
 bi.BATTERY_INFORMATION ; http://msdn2.microsoft.com/en-us/library/aa372661.aspx

Debug "bi\Chemistry: " +  PeekS(@bi\Chemistry,5 )
BATTERY_INFORMATION: http://msdn2.microsoft.com/en-us/library/aa372661.aspx
Ich will nun die Daten von "Chemistry" anzeigen, das klappt nur leider nicht so wie es soll. Nutze ich beim kompelieren UNICODE werden unverständliche Zeichen ausgegeben, im ASCII modus läuft es korrekt.
Auch wenn ich testweise das Flag für den Unicode oder ASCII-Modus setzte geht es nicht im UNICODEmodus. Was könnte ich falsch machen?
1. Win10
PB6.1
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Toshy hat geschrieben:Habe ein "Unicodeproblem" bei Folgendem(Codeauszug,gestückelt):

Code: Alles auswählen

Structure BATTERY_INFORMATION
  Capabilities.l
  Technology.c
  reserved.c[3]
  Chemistry.c[4]
  DesignedCapacity.l
  FullChargedCapacity.l
  DefaultAlert1.l
  DefaultAlert2.l
  CriticalBias.l
  CycleCount.l
EndStructure
 
 bi.BATTERY_INFORMATION ; http://msdn2.microsoft.com/en-us/library/aa372661.aspx

Debug "bi\Chemistry: " +  PeekS(@bi\Chemistry,5 )
BATTERY_INFORMATION: http://msdn2.microsoft.com/en-us/library/aa372661.aspx
Ich will nun die Daten von "Chemistry" anzeigen, das klappt nur leider nicht so wie es soll. Nutze ich beim kompelieren UNICODE werden unverständliche Zeichen ausgegeben, im ASCII modus läuft es korrekt.
Auch wenn ich testweise das Flag für den Unicode oder ASCII-Modus setzte geht es nicht im UNICODEmodus. Was könnte ich falsch machen?
[edit=130220072202]
Das UnicodeProblem habe ich bisher noch nicht gelöst, aber ich habe noch ein weiteres Problem gefunden. Für die Abfrage von BATTERY_QUERY_INFORMATION habe ich ein Macro erstellt, das die Daten ausliest, welche einen NULLterminiertenUnicodestring zurückliefern. Es klappt auch z.B. mit BatteryUniqueID und BatteryManufactureName
( http://msdn2.microsoft.com/en-gb/library/aa372667.aspx )
Aber bei der BatterySerialNumber erhalte ich den Fehler "87" (#ERROR_INVALID_PARAMETER = $57 ) zurück.
Da alles andere Unverändert bleibt, wie kann deviceIOcontrol() durch getlasterror einen solchen Fehler ausgeben?
Wie gesagt, alle anderen Aufrufe der gleichen Art laufen. Tausche ich beim Macroaufruf einfach nur BatterySerialNumber durch BatterySerialNumber aus, klappt es. Kann es sei, das die MSDN-Datenbank eine Fehlerhafte beschreibung hat? Wäre aus meiner sicht nicht das erste mal (wenn ich das Ergebnis des PB-Codes sehe). die Struktur BATTERY_INFORMATION ist auf MSDN wohl falsch.
Ach ja, weder der Aufruf noch der Inhalt der Daten AUßER der Angabe des Informationlevel ändern sich innerhalb der Daten, außerdem kam es zu selben Verhalten, als ich anstatt eines Macros die Codes einfach als Kopie einfügte.

Ich werde hier in kürze mal das Macro posten. Wird aber natürlich nicht lauffähig sein.
[/edit]
[edit=140220071612]
So hier nun mal der Macrocode

Code: Alles auswählen


Macro macro_bqi_GetUniCodePointerData(ILN)
  SizeOfBQI_#ILN = 1
  Debug "SizeOfBQI_" + Macro_DQ#ILN#Macro_DQ + "= " + Str(SizeOfBQI_#ILN)
  dwOut = 0
  bqi\InformationLevel = #ILN
  Debug " bqi\InformationLevel= " + Str(bqi\InformationLevel)
  ll_EnumeratingBatteryDevices()\BQI_#ILN = _AllocateMemory(SizeOfBQI_#ILN * 2 + 2)
  Debug "ll_EnumeratingBatteryDevices()\BQI_" + DQ#ILN#DQ + "= " + Str(ll_EnumeratingBatteryDevices()\BQI_#ILN)
  Repeat
    ReturnDeviceIoControl2 = DeviceIoControl_(hBattery, #IOCTL_BATTERY_QUERY_INFORMATION, @bqi, SizeOf(bqi), ll_EnumeratingBatteryDevices()\BQI_#ILN, SizeOfBQI_#ILN * 2 + 2, @dwOut, #Null)
    ReturnGetLastErrorDeviceIoControl2 = GetLastError_()
    setlasterror_(0)
    If dwOut = 0 And (ReturnGetLastErrorDeviceIoControl2 = #ERROR_INSUFFICIENT_BUFFER Or ReturnGetLastErrorDeviceIoControl2 = #ERROR_MORE_DATA)
      SizeOfBQI_#ILN + 1
      ll_EnumeratingBatteryDevices()\BQI_#ILN = _ReAllocateMemory(ll_EnumeratingBatteryDevices()\BQI_#ILN, SizeOfBQI_#ILN * 2 + 2)
    EndIf
  Until (dwOut <> 0 And ReturnGetLastErrorDeviceIoControl2 <> #ERROR_MORE_DATA And ReturnGetLastErrorDeviceIoControl2 <> #ERROR_INSUFFICIENT_BUFFER) Or (ReturnGetLastErrorDeviceIoControl2 And ReturnGetLastErrorDeviceIoControl2 <> #ERROR_INSUFFICIENT_BUFFER And ReturnGetLastErrorDeviceIoControl2 <> #ERROR_MORE_DATA)
  Debug " NEXT"
  If ReturnGetLastErrorDeviceIoControl2 <> 0
    ll_EnumeratingBatteryDevices()\BQI_#ILN#_ERROR = ReturnGetLastErrorDeviceIoControl2
    Debug "ERROR -> BQI_" + DQ#ILN#DQ + "_ERROR: " + Str(ll_EnumeratingBatteryDevices()\BQI_#ILN#_ERROR)
  EndIf
EndMacro
macro_bqi_GetUniCodePointerData(BatteryUniqueID)
macro_bqi_GetUniCodePointerData(BatteryManufactureName)
macro_bqi_GetUniCodePointerData(BatterySerialNumber)

Die Debugausgabe dazu sieht so aus
[17:17:11] SizeOfBQI_BatteryUniqueID= 1
[17:17:11] bqi\InformationLevel= 7
[17:17:11] ll_EnumeratingBatteryDevices()\BQI_BatteryUniqueID= 9183080
[17:17:11] Next
[17:17:11] SizeOfBQI_BatteryManufactureName= 1
[17:17:11] bqi\InformationLevel= 6
[17:17:11] ll_EnumeratingBatteryDevices()\BQI_BatteryManufactureName= 9183144
[17:17:11] Next
[17:17:11] SizeOfBQI_BatterySerialNumber= 1
[17:17:11] bqi\InformationLevel= 8
[17:17:11] ll_EnumeratingBatteryDevices()\BQI_BatterySerialNumber= 9183176
[17:17:11] Next
[17:17:11] Error -> BQI_BatterySerialNumber_ERROR: 87

Unter http://msdn2.microsoft.com/en-gb/library/aa372667.aspx steht aber daß beides das selbe zurück gibt, einen UnicodeStringpointer. Und da man beides gleich übergibt, sollte das doch klappen.
mit BatteryManufactureName klappt es auch.

Ach ja, es kann gut sein, das die Batterie einiges nicht unterstützt, auch die Seriennummer evtl. nicht (müßte bei dieser Batterie so sein die ich nutze), aber dann sollte laut MS ERROR_INVALID_FUNCTION zurückgegeben werden, also Wert 1 und nicht 87.


[/edit]
1. Win10
PB6.1
Antworten