muckel1986
Goto Top

Wechselndes Hintergrundbild mit einem BATCH-Script realisieren?

Wechselndes Hintergrundbild mit BATCH-Script?

Hallo zusammen,

bei meinem Windows XP würde ich gerne das Hintergrundbild wechseln lassen - eben nach einer gewissen Zeitspanne.

Es gibt dazu zwar Programme, doch ich möchte dafür nicht noch eine Anwendung aufspielen, die ich ansonsten nicht benötige. Habe eh schon ein Batch-Script, welche bei dem System-Start lädt und für mich ein paar Arbeiten automatisch durchführt, daher würde ich jenes gerne erweitern.

Die Frage ist nur, wie ich das nun anstelle?

Wie ich im Batch zu einem Verzeichnis gehe und eine Datei aufrufe weiß ich. Doch nicht, wie ich das nun für meinen Zweck abändern kann.

Vielleicht hat ja jemand von euch eine Idee?

LG Tobias

Content-ID: 170199

Url: https://administrator.de/forum/wechselndes-hintergrundbild-mit-einem-batch-script-realisieren-170199.html

Ausgedruckt am: 23.12.2024 um 00:12 Uhr

DerWoWusste
DerWoWusste 23.07.2011 um 16:49:20 Uhr
Goto Top
Hi.

Es gibt da ein Kommandozeilentool, das hilft, aber ich habe es nicht zu Hause.
Kann Dir Montag weiterhelfen.
Muckel1986
Muckel1986 23.07.2011 um 19:48:14 Uhr
Goto Top
Hallo,

das wäre sehr nett. Denn ich habe bis lang nur eine Möglichkeit gefunden, mit der man auf die Registry zugreift:
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Control Panel\Desktop]
"Wallpaper"="D:\Bilder\Hintergruende\bild-01.jpg"  
Dies in eine Datei mit der Endung *.reg abspeichern und man könnte es dann via BATCH oder vbs-Script aufrufen - dich ich möchte nicht alle paar Minuten die Registry verändern - da weiß ich nicht, ob das so gut ist.

Es gibt zwar auch ein paar Programme die das erledigen, doch die haben bislang immer Funktionen die viel zu Umfangreich sind oder sie gehen zu Lasten des Systems. (Das eine, welches eigentlich ganz okay war, hat immer neben dem Bild die Hauptfarbe des Bildes angezeigt - das sah auch nicht gut aus.)

Wäre Dir daher sehr dankbar. Vilt. hast Du ja schonmal den Namen - oder ist das von Dir?

Lieben Gruß Tobias
Friemler
Friemler 24.07.2011 um 17:54:26 Uhr
Goto Top
Hallo Tobias,

eine weitere Möglichkeit, um das ganze ohne Batchdatei zu realisieren (ständig im Hintergrund laufende Batchdateien erzeugen eine hohe Prozessorlast), wäre IrfanView. Das ist ein Bildbetrachter/-konverter/-manipulator für sehr viele Grafikformate (teilweise Plugins nötig, die auch auf der Homepage erhältlich sind), lässt sich über die Kommandozeile verwenden, hat aber auch Batchkonvertierung/-umbenennung über die GUI eingebaut, bietet die Möglichkeit, Diashows zu erstellen und auf CD zu brennen und vieles mehr; ein rundum nützliches und kostenloses Programm, gehört bei mir zu den Standardprogrammen für Neuinstallationen.

Für Dich interessant ist die Möglichkeit, eine Diashow zu erstellen (Anzeigezeit für ein Bild ist über das Programm einstellbar) und als SCR-Datei (Bildschirmschoner-Datei) zu speichern. Diese Datei ins System32-Verzeichnis kopieren und Du kannst Deine selbst erstellte Diashow über den normalen Windows-Dialog für Bildschirmschoner auswählen.

Gruß
Friemler
rubberman
rubberman 24.07.2011 um 18:03:47 Uhr
Goto Top
Hallo Tobias,

solltest Du partout nichts finden, biete ich an ein kleines Kommandozeilentool in C++ zu schreiben.

Grüße
rubberman
Muckel1986
Muckel1986 24.07.2011 um 18:11:50 Uhr
Goto Top
Hallo @Friemler,

danke für Deinen Tipp! Kenne IrfanView und auch die Diashow. Die Funktion jene abzuspeichern kannte ich bis lang nicht.

Das wäre natürlich eine Möglichkeit, die ich nutzen könnte. Kommt dann aber ein Foto hinzu, müsste ich eine neue Datei erstellen und jene wieder rum abspeichern. Und das ist eigentlich nicht, was ich möchte.
Muckel1986
Muckel1986 24.07.2011 um 18:32:32 Uhr
Goto Top
Hallo @rubberman,

mit C++ habe ich mich noch nicht auseinander gesetzt und weiß daher nicht, wie viel Arbeit das wäre.

Was ich suche ist einfach eine Möglichkeit, dass sich das Hintergrundbild des Desktop nach einer Zeit X ändert und dann ein weiteres Bild aus einem Verzeichnis lädt.

Programme gibt es ja viele. Doch teilweise hatten sie nicht die Möglichkeit das Bild zu strecken oder zu zentrieren und eines, was dies konnte, hat dann die Hintergrundfarbe geändert und zwar in jene, die im Bild am häufigsten vorhanden war. Das sah teilweise sehr komisch aus.

In der Ausbildung habe ich ein kleines Batch-Script erstellt, was einen PING zu zwei Webseiten schicken sollte und wenn jener nicht erfolgreich war in eine csv-Datei schreiben sollte. So sollte dokumentiert werden, wann die Internetverbindung erfolgreich war und wann nicht.

Dazu habe ich unter
C:\Dokumente und Einstellungen\All Users\Startmenü\Programme\Autostart
eine *.vbs Datei abgelegt. Jene hat die *.bat Datei aufgerufen. Das hatte ich mit diesem Inhalt gemacht:
Set WshShell = WScript.CreateObject("WScript.Shell")  
WshShell.Run "pruefung.bat",0,True  
Die Batch-Datei hatte dann den PING ausgeführt und das Ergebnis in die Datei geschrieben:
@ECHO OFF
cd C:\
md C:\pruefung
: anfang
wscript wait3.vbs
echo. >> C:\pruefung\listecookie.txt
echo Cookie Sicherung vom: %date% um %time% >> C:\pruefung\listecookie.txt
echo. >> C:\pruefung\listecookie.txt
dir "%USERPROFILE%\Cookies" >> C:\pruefung\listecookie.txt  
cls
REM hier kam dann der kram fuer die CSV-Datei
goto anfang
Dazu gab es noch die Datei wait3.vbs, mit der ich die Wiederholungsrate des Scripts in Millisekungen definieren konnte:
wscript.sleep(3000)

Das dadurch das System langsamer wurde, konnte ich nicht bemerken.

Daher dachte ich nun, dass ich dieses Script bei mir abändern könnte...

Wenn das in C++ einfacher ist, wäre dies sehr nett, doch ich möchte nicht, dass Du dir Arbeit dadurch machst.

LG Tobias
Friemler
Friemler 24.07.2011 um 18:38:18 Uhr
Goto Top
Zitat von @Muckel1986:
Das dadurch das System langsamer wurde, konnte ich nicht bemerken.

Dann musst Du einfach mal den Taskmanager öffnen und Dir die Registerkarte "Leistung" ansehen. Wenn Du nichts rechenintensives am Rechner machst, fällt die hohe Prozessorlast nicht auf.

Gruß
Friemler
Muckel1986
Muckel1986 24.07.2011 um 20:22:46 Uhr
Goto Top
Guten Abend,

das habe ich damals nicht getan. Denn der "Auftrag" war eben nur, das besagte Script zu basteln und die Lösung via Batch Datei kam von meinem Ausbilder. Die vbs-Datei für das Einbinden im Autostartverzeichnis kam auch von ihm. Es ist zum kotzen, dass man eine Ausbildung zum IT-Systemelektroniker abschließt, die in einem vor Post geschriebene Lösung als "super gut" Bezeichnet wird und man daher dann denkt, dass auch tatsächlich alles in Ordnung ist.

Es war zwar "nur" eine Reha-Ausbildung, doch die Prüfung wurde ganz normal vor der IHK abgelegt. Doch gut war sie nicht und 99% habe ich mir selbst angeeignet. Unser Ausbilder ein Nachrichtentechniker und ging mit dem Ende unserers Lehrjahres auch in Rente. Vielleicht lag es auch daran und an der neuen Situation der "Schulungs-Mittel-Verteilung", das er wohl weniger Interesse hatte.

Habe zur Zeit das Programm von johnsadventures.com in Benutzung, doch da stört mich sehr massiv, dass es eben die "am höufigsten vorkommende Farbe" als Hintergrundfarbe setzt. Ich würde lieber eine von mir gewählte Farbe behalten.

Gut ist dafür, dass ich eben ein Verzeichnis auswählen kann und er die Bilder berücksichtigt, die in dem Verzeichnis sind. Auch wenn man welche hinzufügt oder entfernt, nachdem man das Programm konfiguriert hat.

LG Tobias
rubberman
rubberman 24.07.2011 um 23:17:21 Uhr
Goto Top
Hallo Tobias,

das ist zwar schon etwas spezieller, aber machbar (<100 Zeilen Code). Könnte eine gute Fingerübung sein, um mein vor sich hin rostendes C++ wieder ein wenig aus der Versenkung zu holen. Schöne Feierabendsbeschäftigung (abhängig vom Wetter face-wink).

Fasse mal zusammen: Du suchst ein Kommandozeilentool, dem du das Verzeichnis mit deinen Bildern, den Wallpaperstyle und die Zykluszeit als Argumente übergeben kannst.

Falls so OK, werde ich mich morgen mal daran versuchen.

Grüße
rubberman
Muckel1986
Muckel1986 25.07.2011 um 13:19:31 Uhr
Goto Top
Hallo rubberman,

genau soetwas suche ich:

  • Angeben eines Verzeichnis, in dem sich Bilder (*.jpg, *.png) befinden
  • Ausgabe der Bilder als Hintergrundbild
  • Angabe einer Zeit (z.B. alls 10 Minuten, jede Stunde, etc), nach der das Hintergrundbild geändert wird.
  • Bilder sollten dabei Zentriert werden.
  • Angabe einer Hintergrundfarbe für den Bereich, wo dann kein Bild ist (da kann aber auch die in Windows eingestellte bleiben)

Konnte dies nun aber auch mit dem Programm umsetzten - denn da gab es ein sprachliche "Schwierigkeit". Er hat die Hintergrundfarbe mit Rahmenfarbe bezeichnet, da sie ja teilweise wie ein Rahmen ist.

Daher wäre es nicht mehr unbedingt notwendig. Bei dem Programm ist es nur so, dass es direkt mit Windows Startet. Doch das ist auch in Ordnung.

Mit meine Batch-Script rufe ich halt noch eine Datei zu drei bestimmten Uhrzeiten auf, da ich dann meine Schmerzskala bestimmen muss. Daher dachte ich einfach, dass man damit dann auch das mit dem Hintergrund lösen kann. Doch dann kann ich auch das sein lassen und die Datei über einen Task aufrufen lassen.

Die Frage wäre vilt. noch, wie C++ das löst. Also ob das auch einfach den Registry Eintrag ändert?

Lieben Gruß
Tobias
rubberman
rubberman 25.07.2011 um 21:26:06 Uhr
Goto Top
Hallo Tobias,

ich denke ich habe es etwa so hinbekommen, wie du wolltest.
// wallpaper.cpp

#define WINVER 0x0501
#define _WIN32_WINNT 0x0501

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <wininet.h>
#include <shlobj.h>
#include <errno.h>


void help()
{
  printf("Changes The Desktop Wallpaper.\n\nWALLPAPER Directory Style Wait\nWALLPAPER /?\n\n  Directory       Path And Folder Name The Wallpaper Files Are Placed.\n  Style           0 = Center; 1 = Tile; 2 = Stretch.\n  Wait            Seconds To Wait Before Next Changing.\n  /?              Displays This Help.\n\n  RETURN CODES:\n  3   Syntax Error\n  2   Folder Not Found\n  1   Process Failed\n\n");  
}


int changeWP(WCHAR *filename, DWORD dwstyle)
{
  IActiveDesktop *pActiveDesktop = NULL;
  ::CoInitialize(NULL);
  if (FAILED(CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (LPVOID*) &pActiveDesktop))) return 1;
  if (FAILED(pActiveDesktop->SetWallpaper(filename, 0))) return 1;
  WALLPAPEROPT wpo;
  wpo.dwSize = sizeof(wpo);
  wpo.dwStyle = dwstyle;
  if (FAILED(pActiveDesktop->SetWallpaperOptions(&wpo, NULL))) return 1;
  if (FAILED(pActiveDesktop->ApplyChanges(AD_APPLY_ALL))) return 1;
  pActiveDesktop->Release();
  ::CoUninitialize();
  return 0;
}


int _tmain(int argc, _TCHAR *argv)
{
  if (argc < 2) {help(); return 3;}
  if ((_tcscmp(argv[1], _T("/?")) == 0) && (argc == 2)) {help(); return 0;}  
  if (argc != 4) {help(); return 3;}

  _TCHAR *endptr = NULL;
  long lStyle = _tcstol(argv[2], &endptr, 10);
  if (errno == ERANGE) {help(); return 3;}
  if (_tcscmp(endptr, _T("\0")) != 0) {help(); return 3;}  
  if ((lStyle < 0) || (lStyle > 2)) {help(); return 3;}

  long lWait = _tcstol(argv[3], &endptr, 10);
  if (errno == ERANGE) {help(); return 3;}
  if (_tcscmp(endptr, _T("\0")) != 0) {help(); return 3;}  
  if (lWait < 0) {help(); return 3;}

  WCHAR path[1024];
  swprintf_s(path, 1024, L"\\\\?\\%s", argv[1]);  
  if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES) return 2;

  WCHAR dpath[1024], fpath[1024];
  HANDLE fHandle;
  WIN32_FIND_DATA wfd;
  swprintf_s(dpath, 1024, L"%s\\*", path);  

  while (1)
  {
    fHandle = FindFirstFileW(dpath, &wfd);
    do
    {
      if (!((wfd.cFileName=='.') && ((wfd.cFileName[1]=='.' && wfd.cFileName[2]==0) || wfd.cFileName[1]==0)))  
      {
        if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, wfd.cFileName, -1, _T("desktop.ini"), -1) != 2) && (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, wfd.cFileName, -1, _T("thumbs.db"), -1) != 2))  
        {
          swprintf_s(fpath, 1024, L"%s\\%s", argv[1], wfd.cFileName);  
          if (changeWP(fpath, (DWORD)lStyle)) return 1;
          Sleep((DWORD)lWait * 1000);
        }
      }
    }
    while (FindNextFileW(fHandle, &wfd));
    FindClose(fHandle);
  }
  return 0;
}
Der Code ist C++/CLI, also compilerspezifisch für Microsoft VC.


Zitat von @Muckel1986:
Hallo rubberman,

genau soetwas suche ich:

  • Angeben eines Verzeichnis, in dem sich Bilder (*.jpg, *.png) befinden
  • Ausgabe der Bilder als Hintergrundbild
  • Angabe einer Zeit (z.B. alls 10 Minuten, jede Stunde, etc), nach der das Hintergrundbild geändert wird.
  • Bilder sollten dabei Zentriert werden.
  • Angabe einer Hintergrundfarbe für den Bereich, wo dann kein Bild ist (da kann aber auch die in Windows eingestellte
bleiben)

So sieht dann meine Umsetzung aus:
Changes The Desktop Wallpaper.

WALLPAPER Directory Style Wait
WALLPAPER /?

  Directory       Path And Folder Name The Wallpaper Files Are Placed.
  Style           0 = Center; 1 = Tile; 2 = Stretch.
  Wait            Seconds To Wait Before Next Changing.
  /?              Displays This Help.

  RETURN CODES:
  3   Syntax Error
  2   Folder Not Found
  1   Process Failed
Beispiel:
Wallpaper "C:\images" 0 60
... wechselt das Wallpaper mit allen Dateien in "C:\images", zentriert und im Minutentakt.
Übrigens wird versucht jede Datei in diesem Verzeichnis als Wallpaper zu verwenden (mit Ausnahme der Systemdateien desktop.ini und thumbs.db). Also möglichst nur Bilder ins Verzeichnis legen.

Zitat von @Muckel1986:
Die Frage wäre vilt. noch, wie C++ das löst. Also ob das auch einfach den Registry Eintrag ändert?

Gute Frage. Mein Programm nutzt die Methoden des Active Desktop, so als würdest du per Rechtsklick auf den Desktop das Wallpaper ändern. Was davon Registryeinträge sind und was nicht, habe ich mir noch nicht genauer angesehen. Ich möchte auch gar nicht wissen, wieviele Änderungen der Registry im Laufe einer Windowssitzung vorgenommen werden. Da sollten ein paar mehr oder weniger nicht ins Gewicht fallen. Schließlich ist es Sinn der Registry Informationen und Einstellungen zu beinhalten. Also würde ich an deiner Stelle nicht zu viele Gedanken daran verschwenden.

Falls du den Code nicht selbst compilieren kannst / willst, habe ich dir hier das Binary temporär zum Download abgelegt.
wallpaper.exe

Grüße
rubberman
Muckel1986
Muckel1986 25.07.2011 um 22:16:43 Uhr
Goto Top
Guten Abend @rubberman,

vielen vielen Dank für Deine Arbeit face-smile

(...)
> Zitat von @Muckel1986:
> ----
> Die Frage wäre vilt. noch, wie C++ das löst. Also ob das auch einfach den Registry Eintrag ändert?
>
Gute Frage. Mein Programm nutzt die Methoden des Active Desktop, so als würdest du per Rechtsklick auf den Desktop das
Wallpaper ändern. Was davon Registryeinträge sind und was nicht, habe ich mir noch nicht genauer angesehen. Ich
möchte auch gar nicht wissen, wieviele Änderungen der Registry im Laufe einer Windowssitzung vorgenommen werden. Da
sollten ein paar mehr oder weniger nicht ins Gewicht fallen. Schließlich ist es Sinn der Registry Informationen und
Einstellungen zu beinhalten. Also würde ich an deiner Stelle nicht zu viele Gedanken daran verschwenden.
(...)


Also ich ändere mein Hintergrundbild sonst so, dass ich auf dem Desktop mit rechts klicke, dann auf Eigenschaften klicke, dann den Reiter Desktop auswähle und dort eben ein anderes auswähle.

Meinst Du das mit Active Desktop?

Wie kommt es, dass ein kleines BATCH-Script mehr Prozessorleistung benötigt, als so ein C++ Script, welches compiliert wurde? Habe eben erstmal Deine Datei herunter geladen, werde es morgen aber mal selbst mit Dev-C++ machen, einfach um damit auch mal wieder etwas zu tun zu haben.

Hab nochmal vielen vielen Dank für Deine Hilfe und Arbeit! Für Dich war es vielleicht nur eine Fingerübung, doch wenn man aus bestimmten Gründen selbst mit kleinsten Scripten schon schwierigkeiten hat, dann lernt man auch die kleinen Dinge im Leben sehr zu schätzen.

Lieben Gruß Tobias

P.S.: Wenn man hier auch "gelöst" klickt, kann man dann trotzdem noch schreiben?
rubberman
rubberman 25.07.2011 um 22:53:23 Uhr
Goto Top
Hallo Tobias.

Zitat von @Muckel1986:
Also ich ändere mein Hintergrundbild sonst so, dass ich auf dem Desktop mit rechts klicke, dann auf Eigenschaften klicke, dann den Reiter Desktop auswähle und dort eben ein anderes auswähle.

Mein Programm nutzt die dabei aufgerufenen Prozesse.


Zitat von @Muckel1986:
Meinst Du das mit Active Desktop?

Nein. Unter dem Active Desktop, den du meinst, versteht man beispielsweise eine HTML Seite auf dem Desktop anzuzeigen. Ich beziehe mich hierauf:
IActiveDesktop Interface
Sorry für die Verwirrung.

Zitat von @Muckel1986:
Wie kommt es, dass ein kleines BATCH-Script mehr Prozessorleistung benötigt, als so ein C++ Script, welches compiliert wurde?

Das kommt vermutlich daher, dass Scriptsprachen zunächst interpretiert werden müssen. Weiterhin sind eine Vielzahl der "Befehle" in einem Batchscript eigentlich externe Tools, die sich im Verzeichnis system32 finden lassen. Allein das Aufrufen dieser Tools benötigt eine Menge Zeit und CPU Leistung.
Ein compiliertes C++ Programm ist hingegen schon in Maschinensprache "übersetzt", was zur Laufzeit einfach weniger Ressourcen frisst.

Zitat von @Muckel1986:
Habe eben erstmal Deine Datei herunter geladen, werde es morgen aber mal selbst mit Dev-C++ machen, einfach um damit auch mal wieder etwas zu tun zu haben.

Das hat wenig Erfolgsaussicht. Wie schon geschrieben ist der Code in C++/CLI und nutzt die .NET-Runtime. Der einzige mir bekannte Compiler dafür ist der Microsoft-eigene VC.

Zitat von @Muckel1986:
P.S.: Wenn man hier auch "gelöst" klickt, kann man dann trotzdem noch schreiben?

Ja. Solange Biber oder ein anderer Moderator den Thread nicht schließt, ist das möglich.

Grüße
rubberman