Läuft der Bot durchgehend? Dann würde ich einfach einen Timer anlegen, der nach 48h eine Funktion aufruft. Beispiel und weitere Infos: https://docs.python.org/3/library/threading.html#timer-objects

...zur Antwort

Den Code will ich sehen, ich glaube nicht, dass du in JSON die Discord API ansprichst 😅

Vermutlich meinst du JavaScript? JSON (=JavaScript Object Notation) ist nur eine Teilmenge von JS und ein reines Datenübertragungsformat.

JavaScript Code kannst du ganz einfach mit z.B. NodeJS lokal ausführen: https://nodejs.org/de/

...zur Antwort

Du kannst dafür z.B. den Beep von `choice` missbrauchen, indem du statt einer Benutzereingabe einfach per Pipe eine leere Eingabe reingibst:

echo;|choice/N 2>nul

Für mehr Variation kannst du auch per run-dll folgende Funktion aufrufen:

rundll32.exe Kernel32.dll,Beep 750,300

(https://docs.microsoft.com/de-de/windows/win32/api/utilapiset/nf-utilapiset-beep)

Oder du verwendest dieses Skript hier, das einen Hybrid aus Batch und JScript darstellt:

https://raw.githubusercontent.com/npocmaka/batch.scripts/master/hybrids/.net/systemSounds.bat

...zur Antwort
 ob ein bestimmer Wert (z.B. X) in mindestens einer der fünf Variablen enthalten ist.

Dies sollte recht einfach gehen:

for /L %%i in (1 1 5) do if %X% equ !Var%%i! set /a found += 1

Am Ende ist found == Anzahl der Variablen, die gleich X sind.

Im ersten Fall möchte ich überprüfen, ob mindestens drei davon gleich sind.

Hierfür ein, von der Laufzeit gesehen, komplexerer Algorithmus:

for /L %%i in (1 1 5) do (
  set /a currentlyFound = 0
  for /L %%j in (1 1 5) do (
    if !Var%%i! equ !Var%%j! (
      set /a currentlyFound += 1
    )
  )
  if !currentlyFound! geq 3 echo more than 3 elements are !Var%%i!
)

Die Ausgabe erfolgt dann natürlich 3 oder mehr mal (für jeden Index, der eines der 3 mehrfach vorkommenden Elemente enthält).

Hier noch mal das erste Programm mit Beispielvariablen zum Testen:

@echo off & setlocal enabledelayedexpansion
for /L %%i in (1 1 5) do (
  set /a Var%%i=!random! %% 3
  echo !Var%%i!
)
echo.

set /a X = 2
set /a found = 0

for /L %%i in (1 1 5) do (
  if %X% equ !Var%%i! (
    set /a found += 1
  )
)
echo %X% was found %found% times.
pause

Und das zweite:

@echo off & setlocal enabledelayedexpansion
for /L %%i in (1 1 5) do (
  set /a Var%%i=!random! %% 3
  echo !Var%%i!
)
echo.


for /L %%i in (1 1 5) do (
  set /a currentlyFound = 0
  for /L %%j in (1 1 5) do (
    if !Var%%i! equ !Var%%j! (
      set /a currentlyFound += 1
    )
  )
  if !currentlyFound! geq 3 echo more than 3 elements are !Var%%i!
)
pause
...zur Antwort

(1) Erkennen der Frage nach einem Witz.

Da du anscheinend schon einen funktionierenden Chatbot hast, sollte das ja recht einfach gehen. Du musst also nur z.B. die Keywords Witz, lustig, etc. hinzufügen.

(2) Metadaten über deine Witzdatei erfassen.

Du brauchst hier lediglich die Anzahl an Zeilen, um dir später dann eine davon zufällig aussuchen zu können. Mit einer for-Schleife kannst du die ganz simpel zählen.

(3) Eine Zeile zufällig auswählen.

Die durch %random% generierte Zufallszahl auf den hier benötigten Zahlenbereich von [1; Zeilenlänge] bringen. Sehr simple, wenn auch nicht optimale Methode hierfür wäre:

set /a selectedLine=%random% %% lines + 1

(4) Die Zeile ausgeben.

Du traversierst hierfür alle Zeilen deiner Witze-Datei und gibst die Zeile mit der zuvor berechneten Zeilennummer aus. Dies kannst du mithilfe von findstr /n, mit einer Hilfsvariable oder mittels dekrementieren der selectedLine-Variable erledigen.

Die Schritte 2 bis 4 habe ich in dieser Antwort schon für Verzeichnisse umgesetzt:

https://www.gutefrage.net/frage/cmd-zufaelliges-wort#answer-347286974

Du musst die for-Schleifen also nur noch anpassen, dass sie sich auf Textdateien beziehen.

...zur Antwort

Ich habe vor einiger Zeit bereits auf eine ähnliche Frage geantwortet (https://www.gutefrage.net/frage/batchdatei-hoehere-zufallswert-als-32768#answer-336018767) mithilfe von diesem Code kannst du ganz einfach eine achtstellige Zufallszahl erzeugen, oder 2 vierstellige mit einem Bindestrich aneinanderhängen:

@echo off
call :randomNumber 4
set "n=%return%"
call :randomNumber 4
set "n=%n%-%return%"
echo %n%
pause & exit

:: returns random number (base 10) with %~1 digits.
:randomNumber <digits>
    setlocal enableDelayedExpansion
        set "return="
        for /L %%i in (1,1,%~1) do (
            set /a "r = (10 * !random!) / 32768"
            set "return=!return!!r!"
        )
    endlocal & set "return=%return%"
exit /b
...zur Antwort

Du kannst mit NirCmds "win focus" ein bestimmtes Fenster fokussieren, weiteres dazu findest du hier: https://nircmd.nirsoft.net/win.html

Einen bestimmten Tab des Fensters auswählen geht von der cmd aus nur unter Verwendung von externen Tools, nur sehr sehr aufwendig und alles andere als zuverlässig, da wäre es besser du startest die Seite, die du fokussiert haben willst einfach per "start" von der Batch aus.

Das senden von Tastendrücken kannst du hingegen komplett ohne zusätzlich zu installierende Programme erledigen. Du kannst dir eine vbs Datei erstellen (manuell oder automatisch mit Batch), in der du mit CreateObject("WScript.Shell") ein shell Objekt anlegst und auf diesem dann SendKeys aufrufst.

Was hast du denn endgültig vor? Gibt es wirklich keine bessere Lösung für dein Problem, als Benutzerinteraktionen zu simulieren?

...zur Antwort

Mit einem Rubber Ducky geht das relativ einfach (also z.B. so etwas: https://shop.hak5.org/products/usb-rubber-ducky-deluxe).

Mit einem normalen USB-Stick kannst du lediglich eine autorun.inf erstellen, allerdings wird das inzwischen in fast allen Fällen nicht mehr funktionieren.

...zur Antwort

Was mir zuerst auffällt sind die falschen if-Abfragen: Du hast hier Zahlen vorliegen, da solltest du keinen String-Vergleich durchführen und demnach auch keine Anführungszeichen verwenden. Vor allem aber solltest du nie die Anführungszeichen nur auf einer Seite verwenden, da z.B. `5=="5"` oder auch `16 leq "16"` immer false ist.

Zudem brauchst du keine else-if Verschachtelung, wenn du nur goto's benutzt.

Was aber wahrscheinlich den Fehler verursacht hat, ist das Springen zu Labels, welche nicht existieren. Ich habe dir hier mal eine verbesserte Version aufgeschrieben:

set /a ergebnis=%F1%+%F2%+%F3%+%F4%+%F5%
echo.
echo Deine Punktzahl ist %ergebnis%
echo.

ping localhost -n 3 >nul
if %ergebnis% LEQ  7 goto schlecht
if %ergebnis% LEQ 12 goto besser
if %ergebnis% LEQ 16 goto gut
if %ergebnis% LEQ 20 goto ehrenmann

:schlecht
  echo schlecht
  goto ende

:besser
  echo besser
  goto ende

:gut
  echo gut
  goto ende

:ehrenmann
  echo ehrenmann

echo wie auch immer
...zur Antwort

Mit start /b kannst du eine Art zweiten Thread im gleichen Fenster starten und dort dann eine Sekunde warten. Oder du startest eine zweite Batch minimiert und beendest die erste nach einer Sekunde...

Aber warum so kompliziert, wenn der Befehl den du bereits benutzt schon diese Funktion eingebaut hat?

choice /c abc /t 1 /d c

/t 1 lässt dem Benutzer nur eine Sekunde Zeit eine Auswahl zu treffen. Hier eine genauere Beschreibung aus der Hilfe von choice (choice /?):

/T    Zeitlimit  Bestimmt die Länge der Pause vor der Auswahl
                 in Sekunden. Gültige Wert sind 0 bis 9999.
                 Der Wert 0 bedeutet keine Pause und Verwendung
                 der Standardauswahl.

/D    Auswahl    Bestimmt die Standardauswahl nach nnnn Sekunden.
                 Zeichen müssen im Auswahlsatz durch die Option
                 /C und nnnn mit Option /T festgelegt werden.
...zur Antwort

Ein Skript um bestimmte Dateien zu suchen, habe ich vor kurzem erst für diese Frage hier geschrieben. Das sieht dann ungefähr so aus:

@echo off

:: CONFIG ::
set searchDirectory="C:\User\"
set searchString="test.txt"
:: CONFIG ::

set result="%TEMP%\search_result.txt"
cd /D %searchDirectory%
dir /s /b | findstr %searchString% > %result%

:read
set amount=0
for /f "usebackq tokens=*" %%f in (%result%) do (
    set /a amount += 1
)

if %amount% equ 0 (
    echo Datei wurde nicht gefunden.
    del %result%
    pause & exit /b 1
)
if %amount% gtr 1 (
    echo Mehrere Dateien gefunden.
    echo Druecken Sie eine beliebige Taste um alle gefundenen Dateien angezeigt zu bekommen.
    echo Loeschen Sie dann alle ungewuenschten Zeilen, sodass am Ende nur die zu kopierende Datei in der ersten Zeile steht.
    echo Dann speichern Sie ihre Auswahl mit [Strg] + [s] und schliessen das Fenster.
    pause
    notepad %result%
    goto read
)

set /p file=<%result%
del %result%
echo Gefundene Datei: %file%
pause

Die Funktionalität zum Ersetzen der Datei kannst du entweder schnell selbst am Ende einbauen, oder du erklärst genauer, was getan werden soll.

...zur Antwort

Habe dir mal eben eine kleine Batch hierfür geschrieben. Das eigentliche Suchen der Datei wird dabei so erledigt:

dir /s /b | findstr %searchString%

Das komplette Programm kann dann auch mit mehreren gefundenen Dateien umgehen und erledigt auch das kopieren. Die Parameter im CONFIG-Bereich kannst du je nach deinen Anforderungen anpassen.

@echo off

:: CONFIG ::
set searchDirectory="C:\User\"
set searchString="test.txt"
set outputFolder="D:\output"
:: CONFIG ::

set result="%TEMP%\search_result.txt"
cd /D %searchDirectory%
dir /s /b | findstr %searchString% > %result%

:read
set amount=0
for /f "usebackq tokens=*" %%f in (%result%) do (
    set /a amount += 1
)

if %amount% equ 0 (
    echo Datei wurde nicht gefunden.
    del %result%
    pause & exit /b 1
)
if %amount% gtr 1 (
    echo Mehrere Dateien gefunden.
    echo Druecken Sie eine beliebige Taste um alle gefundenen Dateien angezeigt zu bekommen.
    echo Loeschen Sie dann alle ungewuenschten Zeilen, sodass am Ende nur die zu kopierende Datei in der ersten Zeile steht.
    echo Dann speichern Sie ihre Auswahl mit [Strg] + [s] und schliessen das Fenster.
    pause
    notepad %result%
    goto read
)

set /p file=<%result%
del %result%
cd /D %outputFolder%
copy "%file%"
pause
...zur Antwort

Wie du den Fehler schnell behebst (zurücksetzen von Klick und verwenden von "") wurde ja schon gezeigt. Allerdings ist dies eine gute Stelle um choice zu verwenden.

Knapp formuliert könnte das dann so aussehen:

@echo off
:main
set /p "operand1=Erster  Operand: "
:loop
set /p "operator=Operator (+-/*): "
set /p "operand2=Zweiter Operand: "
set /a operand1 %operator%= operand2
echo:=%operand1%

choice /m "[f]ortfahren oder [n]eu beginnen" /c fn
if errorlevel 2 goto main
if errorlevel 1 goto loop
...zur Antwort

Du kannst auch eine Batch zum Autostart hinzufügen, ohne die Batch selbst modifizieren/herumkopieren zu müssen. Es genügt die ersten 5 Zeilen des folgenden Programms zu deiner Batch hinzuzufügen:

set "REG_PATH_RUN=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"

REG QUERY %REG_PATH_RUN% /v "%~n0" || (
  REG ADD %REG_PATH_RUN% /v "%~n0" /t REG_SZ /d "%~f0"
)

echo Hello World
pause

"REG QUERY ..." überprüft, ob die Batch sich bereits zum Autostart hinzugefügt hat. Falls nicht, wird der errorlevel 1 zurückgegeben und damit der zweite Befehl "REG ADD ..." ausgeführt.

Startest du die Batch also mit obigen Code eingebaut, so wird sie sich von da an immer automatisch beim hochfahren starten. Sollte angezeigt werden, dass der Zugriff verweigert wird, so musst du die Batch als Administrator ausführen (Rechtsklick auf die .cmd-Datei > "Als Administrator ausführen").

...zur Antwort

Für arithmetische Operationen steht dir `set/a` zur Verfügung:

set /a minutes = 5
set /a seconds = minutes * 60

Die Berechnung muss dabei vor dem shutdown-Befehl ausgeführt werden. Dein Beispiel muss also so aussehen:

set /a Wert *= 60
shutdown -s -t %Wert% -f

`set /a Wert *= 60` ist dabei eine Kurzschreibweise für

set /a Wert = Wert * 60

mit der du den Variablennamen nicht zweimal hinschreiben musst.

...zur Antwort

In Batch hast du neben "==" noch folgende Vergleichsoperatoren zur Verfügung:

    EQU - gleich
    NEQ - nicht gleich
    LSS - kleiner als
    LEQ - kleiner als oder gleich
    GTR - größer als
    GEQ - größer als oder gleich

Also um zwei Zahlen zu vergleichen:

set /a a = 5
set /a b = 7

if %a% leq %b% (
    echo a ist kleiner als oder gleich b
)

Beim Datum allerdings hast du das Problem, dass du meist keine Zahlen, sondern Strings in einem bestimmten Datumsformat vorliegen hast.

Das Datumsformat von %date% kann zudem auf unterschiedlichen Computern variieren. Darum ist es besser das Datum mit z.B. `wmic os get LocalDateTime /VALUE` abzufragen. Das speichern dieses Wertes kannst du mit for erledigen:

for /f "tokens=1,2 delims==" %%d in ('wmic os get LocalDateTime /VALUE') do (if "%%d" equ "LocalDateTime" set dt=%%e)

Da du dich beim Datum nur für die ersten 8 Stellen interessierst, kannst du den Rest abschneiden; Ich füge zudem gerne zwischen Jahr, Monat und Tag noch Striche "-" ein, damit das Datum besser lesbar ist:

set currentDate=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%

Mit `if` kannst du nun einen Stringvergleich mit einem anderen Datum (im selben Format) durchführen:

if "%currentDate%" gtr "%maxDate%" goto licenseExpired

Hier mal ein ganzes Beispielprogramm:

for /f "tokens=1,2 delims==" %%d in ('wmic os get LocalDateTime /VALUE') do (if "%%d" equ "LocalDateTime" set dt=%%e)
::  dateFormat:=   YYYY  -    MM   -   DD
set currentDate=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%
set maxDate=2020-05-10

if "%currentDate%" gtr "%maxDate%" goto licenseExpired

echo passed.
pause&exit

:licenseExpired
echo error. license expired.
pause&exit
...zur Antwort

Wie schon gesagt ist der Name der Programmiersprache einfach nur "Batch".

Da Batch allerdings einfach das englische Wort für Stapel ist und in der Softwareentwicklung die Stapelverarbeitung eine allgemeine Arbeitsweise von Computerprogrammen darstellt, wird die Batch-Programmiersprache oftmals als "Batch-file", "Batch-Script" oder "Batch Scripting Language" bezeichnet. So wird die Verwechslung mit den allgemeineren Begriffen vermieden.

...zur Antwort