AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Batchdatei mit ShellExecute nach Standby bzw. Ruhezustand?
Thema durchsuchen
Ansicht
Themen-Optionen

Batchdatei mit ShellExecute nach Standby bzw. Ruhezustand?

Ein Thema von BlackGuest · begonnen am 30. Jan 2009 · letzter Beitrag vom 31. Jan 2009
Antwort Antwort
BlackGuest

Registriert seit: 30. Jan 2009
52 Beiträge
 
Delphi XE7 Professional
 
#1

Batchdatei mit ShellExecute nach Standby bzw. Ruhezustand?

  Alt 30. Jan 2009, 21:09
Ich möchte mir ein kleines Programm schreiben, was mir nach dem Erwachen aus dem Standby bzw. Ruhezustand eine Batchdatei ausführt.

So weit bin ich bisher gekommen:

Delphi-Quellcode:
procedure TMainForm.WMPowerBroadcast(var Msg: TMessage);
 var Befehl: array[0..500] of char;
    oldpath,path,temp: String;
const
  PBT_APMQUERYSUSPEND = $0000;
  PBT_APMBATTERYLOW = $0009;
  PBT_APMQUERYSTANDBY = $0001;
  PBT_APMQUERYSUSPENDFAILED = $0002;
  PBT_APMQUERYSTANDBYFAILED = $0003;
  PBT_APMSUSPEND = $0004;
  PBT_APMSTANDBY = $0005;
  PBT_APMRESUMECRITICAL = $0006;
  PBT_APMRESUMESUSPEND = $0007;
  PBT_APMRESUMESTANDBY = $0008;
  PBTF_APMRESUMEFROMFAILURE = $00000001;
  PBT_APMPOWERSTATUSCHANGE = $000A;
  PBT_APMOEMEVENT = $000B;
begin
  case Msg.wParam of
    PBT_APMSTANDBY:
     begin
      if (StandByPrg<>'')and(Fileexists(StandByPrg)) then
       begin
  // MessageDlg('Go to Standby Mode', mtInformation,[mbOk], 0);
        oldPath:=GetCurrentDir;path:=extractFilePath(StandByPrg); chDir(path);
        temp:=extractFileName(StandByPrg); StrPCopy(Befehl,temp);
        ShellExecute(Handle,nil,befehl,'',nil,1);
        ChDir(oldPath);
       end;
     end;
    PBT_APMSUSPEND:
     begin
      if (SuspendPrg<>'')and(Fileexists(SuspendPrg)) then
       begin
 // MessageDlg('Go to Suspend Mode', mtInformation,[mbOk], 0);
        oldPath:=GetCurrentDir;path:=extractFilePath(SuspendPrg); chDir(path);
        temp:=extractFileName(SuspendPrg); StrPCopy(Befehl,temp);
        ShellExecute(Handle,nil,befehl,'',nil,1);
        ChDir(oldPath);
       end;
     end;
    PBT_APMRESUMESUSPEND:
     begin
      if (WUfromSuspendPrg<>'')and(Fileexists(WUfromSuspendPrg)) then
       begin
  // MessageDlg('Resume from Suspend Mode', mtInformation,[mbOk], 0);
        oldPath:=GetCurrentDir;path:=extractFilePath(WUfromSuspendPrg); chDir(path);
        temp:=extractFileName(WUfromSuspendPrg); StrPCopy(Befehl,temp);
        ShellExecute(Handle,nil,befehl,'',nil,1);
        ChDir(oldPath);
       end;
     end;
    PBT_APMRESUMESTANDBY:
     begin
      if (WUfromStandByPrg<>'')and(Fileexists(WUfromStandByPrg)) then
       begin
  // MessageDlg('Resume from Standby Mode', mtInformation,[mbOk], 0);
        oldPath:=GetCurrentDir;path:=extractFilePath(WUfromStandByPrg); chDir(path);
        temp:=extractFileName(WUfromStandByPrg); StrPCopy(Befehl,temp);
        ShellExecute(Handle,nil,befehl,'',nil,1);
        ChDir(oldPath);
       end;
     end;
  end;
end;
Der Vollständigkeit halber habe ich die Standby und Suspend Messages auch gleich mit eingebaut.
Das Programm soll also in den Pfad der Datei wechseln, die Datei ausführen und dann den alten Pfad wieder herstellen. Funktioniert aus diesem Zusammenhang genommen für sich auch so wie erwünscht. Nur nach dem Erwachen in Zusammenhang mit dem obigen Code nicht.
Ich habe teilweise unterschiedliche Fehlermeldungen bekommen. Einmal "application-defined exception (code 0xC0000006)" an nicht bestimmbarer Stelle und einmal "EInOutError 'E/A Fehler 1231' beim Ausführen von ShellExecute.

Füge ich eine Pause ein oder lass den auskommentierten MessageDlg drin, funktioniert es.
Woran könnte das Problem liegen? Muss ich irgendwie warten, bis das Windows (XP Professional) wieder komplett hochgefahren ist?

Zweites Problem, egal ob ich den Rechner in den Standby oder in den Ruhezustand schicke, beim Erwachen hat Msg.wParam den Wert PBT_APMRESUMESUSPEND. Da stimmt doch auch irgend etwas nicht.

Falls noch irgendwas zum Code oder zum System fehlt bitte melden.

Gruß
BlackGuest

[Edit]
Der Fehler "application-defined exception (code 0xC0000006)" tritt beim Erwachen aus dem Ruhezustand auf. So wie es aussieht bevor Shellexecute ausgeführt wird. "EInOutError 'E/A Fehler 1231" kommt beim Erwachen aus dem Standby bei der ausführung von Shellexecute.
  Mit Zitat antworten Zitat
Benutzerbild von Mr_G
Mr_G

Registriert seit: 2. Sep 2004
Ort: Duisburg
468 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 30. Jan 2009, 21:58
Ersteinmal willkommen in der DP!
Zu deinem Code: PBT_APMSTANDBY und PBT_APMRESUMESTANDBY werden laut MSDN glaube ich nicht unterstützt (Warum auch immer...). Außerdem verstehe ich nicht ganz wieso du beim Eintritt in den Standby auch ein ShellExecute ausführst. Falls das beabsichtigt ist, was ich für seltsam halte (wenn ich in den Standby gehe will ich doch keine Programme starten ), solltest du vielleicht mal einen Blick auf MSDN-Library durchsuchenPBT_APMQUERYSUSPEND werfen. Damit hast du afaik 20 statt 2 Sekunden Zeit und kannst den Übergang zum Standby auch verhindern (Aber Vorsicht: Ab Vista ist das schon wieder raus...).
Zu deiner zweiten Frage: Laut MSDN war das meine ich schon richtig. Wie man nun erfahren könnte ob es sich um einen Standby oder Ruhezustand handelt weiß ich gar nicht.
Jan
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.330 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 30. Jan 2009, 22:05
Also ich verstehe nicht wozu du überhaupt das aktuelle Verzeichnis wechselst. Du kannst in ShellExecute doch einen kompletten Pfad in dem Dateinamen angeben und statt als Arbeitsverzeichnis für den neuen Prozess nil anzugeben, kannst du auch das richtige Verzeichnis angeben.

Zudem kannst du als Parameter auch direkt PChar(DeinString) angeben statt den komplizierten Weg über StrPCopy zu gehen.

So ist das jeweils nur die eine Zeile.

// EDIT:
Außerdem sollte der zweite Parameter 'open' sein, schließlich ist die auszuführende Operation nicht nil, also nix.

// EDIT2:
Vielleicht solltest du dir die Dokumentation noch einmal anschauen:
http://msdn.microsoft.com/en-us/library/bb762153.aspx
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
BlackGuest

Registriert seit: 30. Jan 2009
52 Beiträge
 
Delphi XE7 Professional
 
#4

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 30. Jan 2009, 22:21
Zitat:
Ersteinmal willkommen in der DP!
Danke!

Zitat:
Außerdem verstehe ich nicht ganz wieso du beim Eintritt in den Standby auch ein ShellExecute ausführst
Das ist nur der Vollständigkeit halber drin. Damit könnte man evtl. das Netzwerk deaktivieren etc..
Die Strings StandByPrg und SuspendPrg sind leer, Shellexecute wird hier also nicht ausgeführt. (hätte ich gleich dazuschreiben sollen)

Im Prinzip ist es mir eigentlich auch egal, ob der Rechner aus dem Suspend oder dem Standby kommt. Ausführen will ich momentan das Gleiche. Zum Hintergrund, es geht um mein Notebook. Hier zu Hause ist über HDMI ein externes WSXGA+ Display angeschlossen, im Büro habe ich nur ein Display mit 1024x768 Bildpunkten. Das Notebook wird eigentlich generell nur in den Ruhezustand versetzt. Dann uss ich natürlich jedes Mal die Auflösung ändern. Das will ich automatisieren, da es anscheinend keinen vernünftigen Desktop-Manager gibt, der das beherscht, ohne dass ich irgend etwas anklicken muss. Das Batchfile macht das auch schon ganz vernünftig, nur automatisch klappt es noch nicht.
Wenn es sauber funktioniert, dann werde ich wohl die Auflösung etc. direkt ändern.

@jaenicke
Danke für den Link. Irgendwie habe ich die Doku nicht mehr gefunden und von daher einfach was aus Beispielen genommen. Schaue mir das gleich an, teste das geänderte Programm und melde mich dann wieder.

Gruß
BlackGuest

PS: Danke für die überschnellen Antworten. Da kommt man ja mit schreiben gar nicht nach .
  Mit Zitat antworten Zitat
BlackGuest

Registriert seit: 30. Jan 2009
52 Beiträge
 
Delphi XE7 Professional
 
#5

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 30. Jan 2009, 22:57
So, ich habe den Qelltext mal abgeändert.

aktueller Stand:
Delphi-Quellcode:
procedure TMainForm.WMPowerBroadcast(var Msg: TMessage);
 var path: String;
const
  PBT_APMQUERYSUSPEND = $0000;
  PBT_APMBATTERYLOW = $0009;
  PBT_APMQUERYSTANDBY = $0001;
  PBT_APMQUERYSUSPENDFAILED = $0002;
  PBT_APMQUERYSTANDBYFAILED = $0003;
  PBT_APMSUSPEND = $0004;
  PBT_APMSTANDBY = $0005;
  PBT_APMRESUMECRITICAL = $0006;
  PBT_APMRESUMESUSPEND = $0007;
  PBT_APMRESUMESTANDBY = $0008;
  PBTF_APMRESUMEFROMFAILURE = $00000001;
  PBT_APMPOWERSTATUSCHANGE = $000A;
  PBT_APMOEMEVENT = $000B;
begin
  if Msg.wParam=PBT_APMRESUMESUSPEND then
    if (WUfromSuspendPrg<>'')and(Fileexists(WUfromSuspendPrg)) then
     begin
// MessageDlg('Resume from Suspend Mode', mtInformation,[mbOk], 0);
      path:=extractFilePath(WUfromSuspendPrg);
      ShellExecute(Handle,'open',PChar(WUfromSuspendPrg),'',PChar(Path),1);
     end;
end;
Beim Erwachen aus dem Standby passier gar nichts. ShellExecute sollte zwar abgearbeitet werden aber es passiert nichts. Lasse ich den MessageDlg drin, wird das Batchfile nach dem OK sauber abgearbeitet.
Beim Erwachen aus dem Ruhezustand bekomme ich wieder eine Zugriffsverletzung ('access violation at...".

Scheint also doch so zu sein, dass der Aufruf irgendwie zu früh erfolgt.

Gruß
BlackGuest
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.330 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 31. Jan 2009, 00:07
Hmm, unter Vista funktioniert das Ausführen einer Batchdatei an der Stelle. XP habe ich gerade nicht da, das werde ich gleich in einer VM testen.

Hast du einmal versucht den Fehler mit try..except abzufangen? Dann könntest du einmal schauen, ob der Fehler genau bei ShellExecute auftritt indem du nur das ins try..except packst.

Da das Tool ja nur für dich sein soll, warte doch einfach z.B. 2 Sekunden oder so, das kannst du ja testen wann es dann geht.

Wenn du nur die Auflösung ändern willst, warum machst du das denn per Batchdatei? Mit Delphi könntest du gleich überprüfen, ob es funktioniert hat usw.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
BlackGuest

Registriert seit: 30. Jan 2009
52 Beiträge
 
Delphi XE7 Professional
 
#7

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 31. Jan 2009, 00:20
Zitat:
Wenn du nur die Auflösung ändern willst, warum machst du das denn per Batchdatei? Mit Delphi könntest du gleich überprüfen, ob es funktioniert hat usw.
Ja, da arbeite ich mich gerade durch. Wird dann wohl auch so werden.

Aber wie dem so ist, wenn was nicht funktioniert, dann will ich wissen warum und wie man das in den Griff bekommt.
Ja, den Fehler verursacht ShellExecute. Habe ich gerade mal ausprobiert.

Gruß
BlackGuest
  Mit Zitat antworten Zitat
BlackGuest

Registriert seit: 30. Jan 2009
52 Beiträge
 
Delphi XE7 Professional
 
#8

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 31. Jan 2009, 00:58
Habe noch mal etwas rumgespielt. Nicht ShellExecute verursacht den Fehler sondern das Programm, welches ich über die Batchdatei aufrufe. Das ändert auch die Auflösung. Dabei scheint kurz nach dem Wakeup irgend etwas schief zu gehen.

Also an der falschen Stelle gesucht.

OK, denn mache ich mich mal selbst an die Implementierung.

Danke für eure schnelle Hilfe.

Gruß
BlackGuest
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.330 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Batchdatei mit ShellExecute nach Standby bzw. Ruhezustan

  Alt 31. Jan 2009, 01:40
Zitat von BlackGuest:
Nicht ShellExecute verursacht den Fehler sondern das Programm, welches ich über die Batchdatei aufrufe.
Das dachte ich mir.

Deshalb kam ja auch mein Vorschlag es direkt in Delphi zu machen. Wie das geht steht hier:
http://www.swissdelphicenter.ch/de/showcode.php?id=158
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz