Eine Linse ohne eine Blende hat immer einen recht eng definierten Bereich der größten Schärfe.

Das kannst du mit einer Lupe und der Sonne an einem Stück Papier ausprobieren. Brennglaseffekt. (Bitte nicht ins Auge!)

Eine Linse hat also immer Bereiche der Unschärfe vor und hinter dem Brennpunkt.

Den andere Optischen Effekt einer Kamera liefert die Blende. Diese verhält sich wie eine Lochkamera.

Hänge eine dunkle Decke vors Fenster und nach ein kleines Loch in die Mitte. Du siehst an der Wand gegenüber ein umgekehrtes Bild der "Außenwelt". Es gibt jedoch keine definierte Brennweite. Da die Lichtstrahlen immer im Durchmesser des Lochs den Raum durchqueren (Beugungseffekte mal vernachlässigt).

Der Schärfeberreich ist immer etwa so klein oder groß wie das Loch. Vergrößerst Du das Loch wird das Bild Unschärfe, weil sich dickere Lichtstrahlen überlagern.

Dein Fotoobjektiv ist ein Kompromiss aus beiden Effekten .

Ein kleines Loch macht in der Tiefe immer so scharfe Abbilder wie der Durchmesser der Öffnung (Blende), da dies jedoch enorme Belichtungszeit erforderlich machen würde um genügend Licht auf den Sensor/Film zu bringen, wird vor ein größereres Loch eine Linse gesetzt.

Diese Bündelt den dicken unscharfen Lichtstrahl der großen Lochs zu einem kleinen Durchmesser, welcher sich weniger mit anderen Lichtstrahlen beim Auftreten überlagert.

...hat jedoch eine bestimmte Entfernung in welcher diese Bündelung am stärksten ist.

Anschaulicher bekomme ich es nicht beschrieben.

Damit bin ich jedoch nicht allein. Garnicht so einfach eine Kombination aus mehreren physikalischen Effekten "billig" zu beschreiben....

  • https://de.m.wikipedia.org/wiki/Sch%C3%A4rfentiefe
  • https://pa-photo.de/wie-entsteht-schaerfentiefe/
...zur Antwort
andere

Für größere Sachen C#.

Für kleine Quick & Dirty Aufgaben Powershell. (Wobei ich die nahezu unschlagbare "Großzügigkeit" bezüglich des Umgangs mit Daten zu schätzen weiß). Powershell ist es ziemlich egal ob man schön die Größe eines Windows.Forms-Objects brav nach .Net-Art mit :

$form.Size = New-Object System.Drawing.Size(600,200)

Oder im einfach brutal die Größe als String vor die Füße wirft:

$form.Size = '600,200'

Das Ergebnis ist das Gleiche. Powershell orientiert sich am Zieldatentype und castet die übergeben Werte damit sie passen.

Allerdings sollte sich ein Anfänger eher auf die "brave" Variante verlegen, sonst bekommt er früher oder später Ärger mit dem wesentlich anspuchsvolleren Java oder C#.

Ich kann beides, aber mag Powershell schon etwas mehr. Im übrigen lässt sich auch C#-Code in PowershellScripte direkt "einbauen".

...zur Antwort

testfile.txt

anderserver=1.1.6.6
server=10.15.3.5
blubb=muh

es wird nur der String ausgetauscht, wo "server=" am Beginn der Zeile steht andere Zeilen in denen was Ähnliches steht bleiben unbehelligt!

$Lines = Get-Content 'testfile.txt'
$NewLines = $Lines|%{
   #Regexpatern erklärt "Zeilenbeginn","server=beliebige Zeichen","Zeilenende" 
  $_ -replace '^server=.*$' , 'server=Ersatz'
}
'mal anzeigen:'
$Lines
'
wird:'
$NewLines
$NewLines | Set-Content 'new.testfile.txt'
pause
...zur Antwort

Die neuste Datei in einem ganzen Verzeichnisbaum zu finden ist recht simpel:

  • Ordner Rekursive nach Dateien durchsuchen
  • alle gefundenen Dateien für die Property LastWriteTime absteigend durchsuchen (höchter Wert zuerst)
  • der erste wert hat das Neueste Datum
$Folder = "$Env:Userprofile\Desktop"  #zur Demo aktueller Desktop
  #Erroraction setzen , es gibt Pfade, af welche  man mit Userprivilegien nicht zugreifen kann!
$NewestFile = Get-ChildItem -Path $Folder -File -Recurse -Erroraction SilentlyContinue |
    Sort-Object -Property LastWriteTime -Descending |
    Select-Object -First 1
    
'NewestFile in FolderTree: "{0}" is: "{1}" from {2:g}'-f $Folder, $NewestFile.FullName, $NewestFile.LastWriteTime
pause

Um für jeden Ordner im Tree die neuste Datei zu ermitteln, müssen wir etwas anders vorgehen

  • Erstmal speichern wir den Startordner in ein Liste
  • fügen auch noch alle übrigen Folder hinzu
  • führen wir obiges Prozetere für jeden Ordner in unserer Liste aus (...aber ohne Rekursion)
$StartFolder = "$Env:Userprofile\Desktop"


 #erstmal das StartOrdner-Objekt in die Liste schreiben.
 #Achtung Explizit festlegen, das  die Variable ein Array ist
[Array]$FolderList = get-Item $StartFolder
 # Alle übrigen Ordner im Tree "merken"
$FolderList += Get-ChildItem -Path $StartFolder -Directory -Recurse -Erroraction SilentlyContinue
 
 # aus jedem einzelnen Ordner  in der Liste  die Neueste Datei ermitteln
$NewestFilesList = $FolderList|
    ForEach-Object {
          #wie gehabt, nur ohne Recursion , die haben wir ja schon in der Ordnerliste
        $currentPath = $_.FullName
        $NewestFile = Get-ChildItem -Path $currentPath -File -Filter *.* -Erroraction SilentlyContinue|
            Sort-Object -Property LastWriteTime -Descending |
            Select-Object -First 1
         #manche Ordner haben keine Dateien...
        if ($NewestFile) {
            Write-Host ('NewestFile in Folder: "{0}" is: "{1}" from {2:g}'-f $currentPath, $NewestFile.Name, $NewestFile.LastWriteTime)
            $NewestFile  #in Pipe schreiben
        }
        else {
            Write-Host ('Folder: "{0}" have no File'-f $currentPath ) -fo red
        }
    }
pause
$NewestFilesList |fl *   #optional  mal alle Details  der Dateien
pause
...zur Antwort

Nierenstau durch Harnleiterverschluß.

  • Ich bin viel chronischen Schmerz gewohnt (M.Bechterew, FibroMyalgie)
  • Zahnwurzelbehandlung ohne Betäubung ...pillepalle
  • Verbrennung 3.Grades Füße erträglich...

, aber eine Harnwegsblockade stellt alles in den Schatten. Da wünsch man sich nur noch noch Erlösung, egal wie...gib mir die Kugel...

...zur Antwort
color a

ganz wichtig...😅 cooles grün... (aufhübschen kann man den output, wenn alles läuft😏 )

C:\Users\TimGoldschmidt\Desktop ...

was gefällt Dir nicht an "%UserProfile%\Desktop" ? Das passt immer, egal ob der Nutzer Rumpestilzchen oder Erzesel heist.

echo "%UserProfile%\Desktop"

und natürlich sollte man Pfade immer in "Gänsefüßchen" an Befehle übergeben

was muss ich noch hinzufügen, damit der Kopierte Ordner im Backup Ordner das Datum + die Zeit anzeigt? 

Ich habe doch in den obigen beiden Demos erklärt, wie man eine guten Zeitstempel erstellt.

richtig:

 rem Zeistempel erstellen
set "ZTime=%time: =0%"
set "TimeStamp=%date:~6,4%%date:~3,2%%date:~0,2%%ZTime:~0,2%%ZTime:~3,2%%ZTime:~6,2%
echo %Timestamp%

total falsch:

set "TimeStamp=%date%_%time%"
  • %Time% beinhaltet einen Doppelpunkt(e)! Diese sind in Datei-/Ordnernamen unzulässig. (Der Doppelpunkt kennzeichnet unter Windows Laufwerkbuchstaben)
  • einstellige Stunden beginnen mit einem Leerzeichen. (das ist in WindowsDateinamen zwar nicht kritisch, aber unschön
  • ein deutsches Datum beginnt mit dem Tag. Wollte man solche Datatumstrings sortieren, würden alle Daten nach dem Tag sortiert erscheinen:
01.05.2022
07.02.2022
09.09.2022
10.02.2022
14.10.2021

...die sind wirklich sortiert! (inakzeptabel)

Wenn ich etwas auf ein bestimmte Art tue, hat das seine Bewandtnis. international gebräuchlich ist ein Zeitstempel im Format "yyyyMMddHHmmss" (20220914131949) das entsprich jahr:2022 monat:09 tag:14 stunde:13 minute:19 sekunde: 49

...und lässt sich perfekt sortieren:

20211031131852
20211219131852
20211224131852
20220308131852
20220523131852
wie kann ich das jetzt vorhandene Script erweitern, damit es überprüft ob dann schon 3 Backups vorhanden sind und somit beim 4ten versuch das älteste löscht damit es immer 3 Backups bleiben.

...macht Doch die 1.Demo.

for /f "skip=3 ...usw. überspringt 3 übermittelte Ergebnisse. Wenn dann nichts übrig bleibt wird der Loop-Body ( do (...) ) nicht ausgeführt. Die Routine ist logisch bereits so aufgebaut, das sie automatisch 3 Ergebnisse bewahrt, indem sie diese nicht an den Löschbefehl übergibt. was soll da noch extra überprüft werden?

du hättest nichts weiter tun müssen als die entsprechend Routine zu übernehmen und die Pfade /Wildcard-Muster anzupassen.

Die Nummer mit forFiles scheidet ohnehin aus, weil sie mehr als 3 backups innerhalb 3 Tagen zulässt...

also nochmal Demo1.cmd an Deine neuen Pfadvorgaben angepasst: lösche ggf. die gekennzeichneten Zeilen, welche die Demoumgebung kreieren.

@echo off
chcp 65001 >nul

set "Basefolder=%userprofile%\Desktop"
set "BackupBase=%userprofile%\Desktop\Backup

 rem erzeuge testordner die folgenden 3 Zeilen können weg
md "%Basefolder%\Testordner" 2>nul
echo Hallo Test >"%Basefolder%\Testordner\blubb.txt"
md "%Basefolder%\Testordner\blubbFolder"

color a &rem hauptsache grün
 rem Zeistempel erstellen
set "ZTime=%time: =0%"
set "TimeStamp=%date:~6,4%%date:~3,2%%date:~0,2%%ZTime:~0,2%%ZTime:~3,2%%ZTime:~6,2%

 rem erstelle Backup
xcopy "%Basefolder%\Testordner\" "%BackupBase%\Testordner_%TimeStamp%\" /ehyrk

for /f "skip=3 tokens=*" %%a in ('dir /b /ad /tc /o-d "%BackupBase%\Testordner_20*"') do (
  echo lösche: "%BackupBase%\%%~a"
  rd /s /q "%BackupBase%\%%~a"
)
pause
 
...zur Antwort
Danke, Danke, liebe Halbwissende, IT-Esotherker und Schlangenölverkäufer.

Erstmal ein paar technische Grundlagen auf Normalmenschennivea erklärt:

Die IP ist vergleichbar mit einer Telefonnummer, welche jedem Internetanschluß zugeordnet ist und genau wie bei Telefonnummern sind IPs nötig um eine Verbindung zwischen Teilnehmern herzustellen.

Mehr noch, alle sich im Internet bewegenden Daten werden in kleine Pakete zerlegt und der Reihenfolge nach nummeriert. Damit ist es egal ob ein Teil der Pakete über London,NewYork oder Tokio verschickt wird. Jedes Paket hat die eigene Adresse als Absender, die Adresse des Empfängers und Paketnummern. Das nennt sich Requestheader. Ohne diesen "Adresskopf" bewegt sich nichts.

Jeder Internetprovider vergibt jedem Internetanschluss recht zufällig eine IP. Jedes Land hat einen Adressraum, also von einem internationalen Konsortium vergebene Zahlen mit denen eine IP beginnt...

  • USA: 1.x.x.x
  • Deutschland: 87.x.x.x
  • ...usw.

War nur ein Beispiel, es sind mehrere "Beginne" für ein Land möglich oder mehrere kleine Länder teilen sich eine Nummer.

192.x.x.x, 10.x.x.x ist ein besonderer Addressraum. Dieser ist mehrfach vergeben und nur lokal in Deinen 4 Wänden gültig.

Mein Rechner hat die IP 192.168.0.2, mein Fernseher 192.168.0.3.

Bin ich irre, meine IP zu veröffentlichen?

...Natürlich nicht, denn meine IntenIP gibt es zigmillionen mal.

...und meine Internet IP ist aktuell 83.221.90.52 ... (greift mich an 😅)

Das is natürlich Käse, bei mir im Router ist nicht definiert, was mit einer Verbindungsanforderung passieren soll. Bestenfalls wird auf ein Ping geantwortet... und wenn sich jemand mit meinem PC verbinden möchte, müsste ich dem Router sagen, über welches Port er die Verbindung an meinen Rechner weiterleiten soll.

Es ist völlig unerheblich ob jemand Deine IP kennt. Dein Router ist ein Tor, welches nur das durchnässt, was er darf und das ist nornalerweise relativ einseitig von innen nach draußen.

...und weil Jedes Datenpaket einen Absender habe muss um anzukommen, sieht jeder Empfänger Deine externe IP (die 192ger ist ohnehin Wurst) was er mit Deiner IP macht bleibt ihm überlassen...Eigentlich nutzt nicht mal speichern etwas, denn die ist wie oben erwähnt vom Provider zufällig vergeben)

Das kannst Du probieren: https://www.whatismyip.com/de/ total ungefährlich.

Aber warum gibt's dann im Fernsehen die Werbung von NordVPN & Co , ....😱wo jeder Deine Privatsphäre kennt 😱...?

Das sind Schlangenölverkäufer ....

Wer sich im Internet bewegt hat eine zurück verfolgbare Adresse. Nur mit einer richterlichen Anordnung muss der Provider die Verbindungsdaten preisgeben, wer wann welche IP hatte.

Das ist kein Problem wenn man nichts blödes getan hat.

Solche IPverschleierung wie VPN oder Proxies waren ursprünglich dafür gedacht um vor politischer Verfolgung in Diktaturen zu schützen. ...und natürlich auch für jegliche kriminelle Aktionen.

Was will nun ein kommerzielles Unternehmen welche VPN..Proxies verkauft von Dir als redlichen Bürger?

...Deine Daten... Du schickst all Deine Post über ein und den selben Briefkasten. Du weißt nicht was der Unsichtbare Briefträger tut, außer einen falschen auf das Couvert zu kleben...

Ist Dir schon mal in den Sinn gekommen, das die VPN-Abieter all Deine "Briefe" öffnen und speichern/analysieren?

Du gibst jemandem ohne das ein Richter dies angeordnet hat, all Deine geheimsten Daten... und hast nichts als das Versprechen , das es ihn nicht interessiert was über seine Server geleitet wird.

Du musst Dich nicht vor dem Wolf (den bösen Hacker) fürchten. Die nette Schlange, der Fuchs ist gefährlich, der dich einschüchtert , bis Du freiwillig in seinen Sack hüpfst.

...zur Antwort

Abgesehen von den überflüssigen Leerzeichen ist noch einiges andere Falsch in Deinem Pattern.

Dein Pattern (ohne falsche Leerzeichen) erklärt:

^[A-Z]{1,3}[:][A-Z]{1,2}[ ][1-9]+[0-9]{,3}
  • ^ Beginn Zeile/Einzelstring
  • [A-Z]{1,3} 1 bis 3 Buchstaben A-Z
  • [:] Doppelpunkt
  • [A-Z]{1,2} 1 bis 2 Buchstaben A-Z
  • [ ] 1 Leerzeichen
  • [1-9]+ mindestens eine Ziffer 1-9 (!!!böse Falle '+' ist gefräßig und matched so lange bis ein nicht definiertes Zeichen auftaucht!!!) QT:WR 211011 wäre somit ein volles Match im Bezug auf die folgende...
  • [0-9]{,3} abhängig von der Plattform ist der fehlende Startwert ein Syntaxfehler

Da keine Zeilenende definiert ist, würden (ohne obigen Syntaxfehler) alle auch Strings mit 100 beliebigen Zeichen an ende matchen, da die vorangegangene Zeichenkette einfach am Beginn eine langen Strings stehen muss...

So sollte es Richtig werden

^[A-Z]{1,3}:[A-Z]{1,2} [1-9][0-9]{0,3}$
  • ^[A-Z]{1,3}[:][A-Z]{1,2}[ ][1-9] war soweit OK, allerdings sind die [] um den Doppelpunkt und das Leerzeichen überflüssig.

(das + weglassen es ist nur genau einmal 1-9gefordert! (aber nicht mindestens einmal!))

  • [0-9]{0,3}
  • $ Ende Zeile/Einzelstring (danach kommt nix mehr!)

Kleines PowershellSript zum Probieren:

$pattern='^[A-Z]{1,3}[:][A-Z]{1,2} [1-9][0-9]{0,3}$'
 # ..:WR.. =wrong  ...RT...=right
$List=@(
    'AW:KE 4049'
    'QFT:WR 10689'
    'QFT:WR 211011'
    'BLB:WR 001'
    'ME:RT 2068'
    'HH:RT 11'
    'MUL:RT 8'
)
$List|?{$_ -cmatch $pattern}
  • http://www.regexe.de/hilfe.jsp
...zur Antwort

Naja mit 3 Kilo hast Du mächtig übertrieben. Den Zeh solltest Du handbreit unterhalb des Knies amputieren. Benutze am besten eine Axt.

hör auf mit trollen...

Schade um die Kamera.

...zur Antwort

Ich war (als alter Hase) einigermaßen erschüttert, das beim Testen, nach umstellen der Uhr, das Datum der letzten Änderung nich von der Windowsuhr geholt wird sondern (möglicherweise?) von der Biosuhr?

echt seltsam😱... anders kann ich mir nicht vorstelle, woher robocopy die "wahre" Zeit nimmt, wenn nicht aus dem Bios? ..ein Bug?

Wenn die Backupordner vor dem Kopieren mit Robocopy per md erstellt werden, klappt die Sache.... (md verwendet die Uhr des Betriebssystems)

Die im Ordnernamen sichtbare Datumsangabe habe ich zu einen sortierbaren Zeitstempel im internationalen Format : "yyyyMMddhhmmss" umgebaut.

Ordner löscht man nicht mit del, sondern mit rd .

Da rd /s /q @path Ordner mit samt Inhalt löscht, darf Forfiles nicht mit dem Parameter /s rekursiv Unterordner erfassen! Sonst wird versucht den rd-Befehl auf bereits gelöschte Objekte auszuführen, was zu Fehlermeldungen führen würde.

demo.cmd

@echo off
chcp 65001 >nul
  rem sortierbarer Zeitstempel: JahrMonatTagStundeMinuteSekunde
set ntime=%time: =0%  &rem Leerzeichen bei  einer Stunden durch 0 ersetzen
set "SortableTimstamp=%date:~6,4%%date:~3,2%%date:~0,2%%ntime:~0,2%%ntime:~3,2%%ntime:~6,2%"


 rem  hier  deine Pfade
set "Source=%UserProfile%\Documents\Testordner"
set "DestinationBase=%UserProfile%\Documents\Backupordner"
set "DesinationFull=%DestinationBase%\Testordner%SortableTimstamp%" 


  rem erzeuge den Zielordner schon vor dem kopieren mit  robocopy
md "%DesinationFull%"
robocopy "%Source%" "%DesinationFull%" /E
ForFiles /p "%DestinationBase%" /m Testordner* /d -2 /c "cmd /c rd /s /q @path"
pause
...zur Antwort

Ich veremute mal Du meinst bei Mausklick an die Cursorposition verschieben?...

Du must nichts weiter tun als die Cursorposition ermitteln und das Element dort absolut positionieren...

Ganz billige Demo:

<!DOCTYPE html>
<html>
<style>
html, body {
  margin: 0;
  height: 100%;
}
</style>

<body onclick="MachWasCursorPosition(event)">

<div>X-Position ist: <span id="cursor-position-x">0</span>. </div>
<div>Y-Position ist: <span id="cursor-position-y">0</span>. </div>
<div id="mydiv">Hallo mein Freund</div>
<script>

function MachWasCursorPosition(event) {
 MouseX=event.clientX;
 MouseY=event.clientY;
 document.getElementById("cursor-position-x").textContent = MouseX;
 document.getElementById("cursor-position-y").textContent = MouseY;
  //verschiebe das Element zu absoluter Position
 d = document.getElementById("mydiv");
 d.style.position = "absolute";
 d.style.left = MouseX+'px';
 d.style.top = MouseY+'px';
}
</script></body>

Text folgt der Maus:

wie oben
<body onmousemove="MachWasCursorPosition(event)">
wie oben
  • https://www.w3schools.com/howto/howto_js_draggable.asp
  • https://stackoverflow.com/questions/15702867/html-tooltip-position-relative-to-mouse-pointer
  • https://stackoverflow.com/questions/7143806/make-an-image-follow-mouse-pointer
...zur Antwort

Irgendwie bist scheinst Du auf einem völlig falschen Weg zu sei, dazu später mehr...

Ich benutze mal statt Word einfach Notepad, um eine automatisierte Demo zu basteln, welche den Fenstertitel eines Prozesses in einer Variable speichert:

WinTitleDemo.cmd

@echo off
  rem erzeuge einem Demo.txt -Datei (damit ich  iergendwas  definiertetes  zum  öffnen habe)
echo Ich irgendein Text>"demo.txt"
  rem ...mit Notepad als Parallelprozess öffnen und etwas Zeitgeben zum starten
start "" Notepad.exe "demo.txt"
timeout 1 >nul

  rem ...mit Hilfe  von Tasklist den Fenstertitel von Notepad in einer Variable  speichern. (hoffendlich ist es das einzige Notepadfenster, dass offen ist?)
for /f "tokens=1,2,8* delims=," %%a in ('tasklist /fi "ImageName eq Notepad.exe"  /nh /v /fo:csv') do (
    echo von Tasklist gefunden:
    echo %%a mit der ProzessID: %%b  hat den Fenstertitel: %%d
      rem Fenstertittel in Variable speichern
    set "MeinFensterTitel=%%~d"
)

echo.
echo Ich vermute mal, der gesuchte Fenstertitel war: "%MeinFensterTitel%" 
pause
Ich möchte nämlich ein Textdokument mit dem gleichen Namen haben, welches sich dann dazu öffent (mit Zusatzinformationen)

Meinst Du nicht auch, das es absolut der falsch wäre, eine Batch im Hintergrund per Polling warten zu lassen bis irgendwann ein bestimmter Fenstertitel in einer Variable erscheint?

Das wäre nicht nur grusselig, sondern könnte im ungünstigsten Fall ca.10-15% Systemleistung "auffressen".

Notepad ist ein billiger Editor ohne Tabs. Bei Programmen welche mehrere Tabs enthalten ist nicht sicher, das der Fenstertitel auch dem gewünschten Tab entspricht...

Dein Denkfehler ist, das deine Batch aktiv auf ein Ereignis warten müsste. Denke es einfach anders...

Ich möchte Dir nicht empfehlen die Verknüpfung von Worddokumenten, in der Registry, auf eine Batch umzuleiten.

Was du jedoch tun kannst, eist eine Batch als Droptarget einzurichten... und die zu öffnende Datei einfach auf die Batch zu ziehen. Diese startet Word oder Notepad oder was auch immer Du mit eienr Datei anstellen möchtest und parallel dazu führt es andere Aktionen aus.

dropTargetDemo.cmd

@echo off
chcp 65001 >nul
  rem abfragen ob eine übegeben wurde
if "%~1"=="" (
    echo Diese Batch ist ein Droptarget.
     echo ...ziehe eine .txt ,.jpg ,.bmp ,.png, .gif oder .tiff Datei auf diese Batch: "%~nx0"
    timeout 10 >nul
    exit /b
)

set "myFile=%~f1"
set "myFileExt=%~x1"
echo du hast  die Datei "%myFile%" auf die Batch gezogen.&echo:

if /i "%myFileExt%"==".txt" goto :openTextFile
for %%a in (jpg,bmp,png,gif,tiff) do if /i "%myFileExt%"==".%%a" goto :openPicture
echo Ich  kann nichts  mit der Extension "%myFileExt%" anfangen!
timeout 5 >nul
exit /b

:openTextFile
start "" notepad.exe "%myFile%"
echo zusätzliche  Informaton:
echo Statt dieder Mitteilung würde ich die passende informationsdatei anzeigen....
pause
exit /b


:openPicture
  rem  öffne  Bild  mit StandardAnwendung
start "" "%myFile%"
echo zusätzliche  Informaton zum Bild "%myFile%" :
echo Statt dieder Mitteilung würde ich die passende Informationsdatei anzeigen....
pause
exit /b

Ergo.

Die Batch wartet nicht bis eine Datei ein Fenster mit einem Namen öffnet, sondern die Datei startet die Batch, welche ihrerseits die passende Anwendung dafür startet und ggf. noch andere Aktionen ausführt. "so herum wird ein Schuh draus"

ich weiß nicht, was Du da bastelst, aber ich würde Dir empfehlen für Komplexere Anforderungen als ein paar einfache Programmstarts auf Powershell umzusteigen.

Wenn du Dir oben anschaust wie umständlich es ist in Batch mit einem for/f-Loop die Ausgabe eines Kommandozeilenprogramms wie Tasklist zu filtern, wirst Du Powershell schätzen:

Obige in Powershell:

WinTitleDemo.ps1

'Ich irgendein Text'>"demo.txt"
Start-Process -FilePath 'Notepad.exe' -ArgumentList '"demo.txt"'
Start-Sleep -Seconds 1

$MeinFensterTitel = (Get-Process -Name 'notepad').MainWindowTitle
Write-Host ('Ich vermute mal, der gesuchte Fenstertitel war:"{0}"'-f $MeinFensterTitel) -fo green 
pause

ein Polling ist zwar auch in Powershell nicht schön, jedoch hält sich der Resorcenhunger in grenzen, das nicht ständig Kommandozeilenprogramme gestartet und beendet werden, sondern interne Systemfunktionen ausgeführt werden

  #pollt so lange im Abstand von einer halben Sekunde bis die Datei demo.txt mit Notepad geoeffnet wird
do {
    Start-Sleep -Milliseconds 500
    $MyWindowName = (Get-Process -Name 'notepad' -ErrorAction Silent|
        Where-Object {$_.MainWindowTitle -like 'demo.txt*'}
        ).MainWindowTitle
} while (!$MyWindowName)


Write-Host ('FensterTitel: {0}  wurde geoeffnet'-f $MyWindowName) -fo green
'würde  an dieser Stelle irgendwas  machen'
pause
...zur Antwort

Der Aufruf einer andern Batch ohne call , wechselt zu dieser Batch und beendet die aufrufende Batch.

Aufrrufer.cmd

@echo off
andereBatch.cmd
echo Dies  wird nicht mehr ausgeführt

wird eine andere Batch/Subroutine mit call aufgerufen, wird die aufrufende Batch nach Beendigung der anderen Batch mit der auf den call folgenden Zeile weitergeführt.

@echo off
call andereBatch.cmd
echo weider  zurück in "%nx0"
pause

oder

@echo off
call :Subroutine
echo weider  zurueck in "%0"
pause
exit /b

:Subroutine
echo ich bin die Subroutine..."%0"

allerdings sollte man dass mit den Calls nicht übertreiben...

set "i=0"
call :rercursFunc
pause
exit /b


:rercursFunc
set /a "i+=1"
echo %i%
call :rercursFunc

endet kläglich 🥱:

C:\Users\Erzesel Secure\Desktop>call :rercursFunc
******  B A T C H R E K U R S I O N  überschreitet Stapellimit    ******
Rekursionszähler=339, Stapelauslastung=90 Prozent
******  B A T C H V E R A R B E I T U N G  A B G E B R O C H E N  ******

...aber weshalb legst Du Dein :

cd F:\folder
robocopy F:\folder D:\temp /MIR

...überhaupt in eine Extra Batch...

Sowas ist purer Unsinn , wegen 2 Zeilen... 😅

noch bevor man eine Extra Batch einsetzt sollte man erwägen ob eine Subroutine oder ein Macro angebracht sein könnte (macros setz man bei häufig auftretenden unübersichtlichen Kommandos ein (sehr schnell)

@echo off
set "MeinMacro=echo ich bin die erste Zeile eines Macros& echo ich bin die zweite Zeile eines Macros"

echo irgendwas
%MeinMacro%
echo blubb
%MeinMacro%
echo blahhh
%MeinMacro%
pause
...zur Antwort

Ich mach mal einen Schuss ins Blaue...

test.txt

Hallo du
blah&blubb
"Hupt"," dummel","ditum"
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren.
Hallo du
"Hupt"," dummel","ditum"
Mokkamix
"abra","Muckel","13.08.86"
ratzfatz
MokkaMix

Einfachste Variante,

  • Zeilen einlesen
  • Zeilen nach ihrem Inhalt gruppieren
  • nur die Gruppen mit einem Element auswählen
  • den Inhalt der gewählten Gruppen in Datei schreiben

Die Reihenfolge der zurückgegebenen Zeilen hängt von der Powershellversion ab... 5.1: bleibt erhalten, 7: sortiert

$SingleLines = Get-Content 'test.txt'|
    Group-Object -CaseSensitive|  #Zeilen nach nach ihrem Inhalt gruppieren
    Where-Object{$_.Count -eq 1}  #und nur  die Zeilen behalten von denen es nur eine in der Gruppe  gibt (.Count=1)

 #mal zur Demo anzeigen was wir  da so ausgesucht haben
$singleLines
  #den in Group.Name gespeicherten Inhalt zurückschereiben
Set-Content 'Test.new.txt' $SingleLines.Name
pause

...wie erwähnt sortiert Version 7 die Gruppen nach Namen... Dem kann man nur begegnen, indem man sich beim Einlesen der Quelldatei merkt, was in welcher Zeilennummer war... und später die alte Reihenfolge der Zeilennummern widerherstellt:

$SingleLines =Get-Content 'test.txt'|
    ForEach-Object {$Line=0}{
          #originale Zeilennummer & Inhalt als gemeinsames Object erhalten
        [PSCustomObject]@{
            LineNumber  = $Line++
            LineContent = $_
        }
    }|
    Group-Object -Property LineContent -CaseSensitive|
    Where-Object{$_.Count -eq 1}

 #mal zur Demo anzeigen was wir da haben
$SingleLines|ft
$SingleLines.Group|ft
$SingleLines.Group|Sort-Object -Property LineNumber|ft

 #den Inhalt der Gruppen wieder nach Zeilennummern in die alte Reihenfolge bringen
$Newlines = $SingleLines.Group|Sort-Object -Property LineNumber
Set-Content 'Test.new.txt' $Newlines.LineContent
pause

Sollte Groß-/Kleinschreibun unwichtig sein, entferne -CaseSensitive aus der Group-Anweisung

Das sollte für die meisten gängigen Situationen ausreichen.

  • https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/group-object
  • https://docs.microsoft.com/de-de/powershell/scripting/learn/deep-dives/everything-about-pscustomobject
  • https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/sort-object
...zur Antwort

Beim Ausführen einer .ps1-Datei wird der Prompt automatisch abgeschaltet.

Bei der direkten Eingabe von Kommandos in die Powershellconsole ist ein unterdrücken des Prompts eher unzweckmäßig , wird doch im Standardprompt angezeigt, wo man sich gerade im Dateisystem befindet.. und das vorangestellte PS vermeidet Verwechslungen mit dem Cmd-Prompt.

Möchtes Du den StandardPrompt für die aktuell Session ändern kannst Du die Prompt-Funktion durch einen eigene überschreiben (override).

function prompt { 'Ein Frosch sitzt in ' + $pwd + '> ' }
#oder
function prompt { ' /\_/\'+[Environment]::NewLine+'( o.o )'+[Environment]::NewLine+' > ^ <  Was darfs  sein?:' }

Einen Pferdefuß gibt's immer... wird ein leerer String angegeben, wird automatisch 'PS>' angenommen (eben weil kein Prompt wenig Sinn macht).

function prompt {' '}  #geht  nicht und liefert "PS>"

Das geht sehr wohl 🤫:

function prompt {' '+[char]8}  #ein Leerzeichen Schreiben und mit einem Backspace rückwärts löschen

Powershell mit einem solchen Prompt zu starten änderst Du einfach den Zieleintrag für eine Veknüpfung:

powershell.exe -nol -noe -c "function prompt {' '+[char]8}"

...zur Antwort

Im einfachste Fall ist die Sache ganz simple Stringakrobatik. CSV ist einfach eine Datei mit Stringzeilen und Strings kann man etwas hinzufügen:

Demo0.ps1

$String1='"Name","Vorname","Ort"'
$String2='"Geschlecht","Erben"'
$String1+','+$String2   #das ist sehr unordentlich...
  #besser mit -format String
'{0},{1}' -f $String1 , $String2

Ich habe zwei CSVdateien welche ich Zeilenweise zusammenführen möchte:

test1.csv

"Name","Vorname","Ort"
"Meier","Franz","Kleckersdorf"
"Huber ","Xaver","Bergstadt"
"Paschuke","Erna","Keksfeld"
"Zechpreller","Max","Schnorringen"

test2.csv

"Geschlecht","Erben"
"m","6"
"d","0"
"w","22"

Am einfachsten ist die "Holzhammermethode" einfach die Zeilen beider Dateien als Strings einlesen und wie in Demo0 zusammenkleistern.

nicht schön aber Effizient:

demo1.ps1

$CsvLines1=@(Get-Content 'test1.csv')
'Daten in CSV1:'
$CsvLines1
$CsvLines2=@(Get-Content 'test2.csv')
'Daten in CSV2'
$CsvLines2
  #vereinigen mit  ganz  banaler Stringakrobatik
$NewLines=$CsvLines1|%{$index=0}{
    if ($CsvLines2[$index]){
        '{0},{1}' -f $_,$CsvLines2[$index]
    }
    else {
          #wenn die Zeilen in der 2.Datei nicht  ausreichen...
        '{0},{1}' -f $_,'"Keine Daten","Keine Daten"'
    }
    $index++
}
'Daten Vereinigt:'
$NewLines
  #Den  ganzen "sch..." wieder Speichern...
$NewLines|Set-Content 'new.csv'
pause

...das war einfach brutal...

Normalerweise arbeitet man mit Objekten... ich verzichte mal auf die automatische Erkennung von Properties und deren zusammenfügen, sonst würde es richtig derb.

...also erstellen eines von Hand definierten Objekts und zuweisen der Objektpropeties anhand deren Reihung (index)

demo2.ps1

$ObjectArray1=Import-Csv 'test1.csv'
$ObjectArray2=Import-Csv 'test2.csv'
 #mal anzeigen
$ObjectArray1|ft
$ObjectArray2|ft
 #definiere neues PSCustomObject mit den Daten aus beiden csv
$MergedObjects=$ObjectArray1|%{$index=0}{
  if ($ObjectArray2[$index]){
    [PSCustomObject]@{
      Name   = $_.Name
      Vorname  = $_.Vorname
      Ort    = $_.Ort
      Geschlecht= $ObjectArray2[$index].Geschlecht
      Erben   = $ObjectArray2[$index].Erben
    }
  }
  else {
    [PSCustomObject]@{
      Name   = $_.Name
      Vorname  = $_.Vorname
      Ort    = $_.Ort
      Geschlecht= 'unknown'
      Erben   = 'unknown'
    }
  }
  $index++
}

 #mal anzeigen
$MergedObjects|ft * -auto
 # als Neues CSV Exportieren
$MergedObjects|Export-Csv -Path 'Neu.csv' -NoTypeInformation
pause

Da Du nicht Angegeben hast woher du die Daten für die Neu hinzuzufügenden Propeties hebekommst wäre auch Input von Hand eine Option:

Demo3.ps1

$ObjectArray1=Import-Csv 'test1.csv'
 #mal anzeigen
$ObjectArray1|ft


  #definiere  neues  PSCustomObject mit den  Daten aus  beiden csv
$MergedObjects=$ObjectArray1|%{
    Write-Host 'Bisherige Daten:' -fo green
    Write-Host (
'Name: {0}
Vorname: {1}
Ort: {2}' -f $_.Name,$_.Vorname,$_.Ort) -fo yellow
    
    $newObject=[PSCustomObject]@{
        Name      = $_.Name
        Vorname   = $_.Vorname
        Ort       = $_.Ort
        Geschlecht= 'unbekannt'
        Erben     = 'unbekannt'
    }
    $Gender = Read-Host 'welches  Geschlecht soll ich eintragen? (m,w,d  oder Enter)'
    $Heirs  = Read-Host 'wwie  viele Erben gibt es? (Anzahl oder Enter)'
    if ($Genter){$newObject.Geschlecht = $Gender}  #wenn etwas  eingegeben wurde dies im Objekt  änden
    if ($Heirs) {$newObject.Erben = $Heirs}  #dito
    $newObject #fertiges Object in die Pipe schreiben
}
  #mal anzeigen
$MergedObjects|ft * -auto
  # als Neues CSV Exportieren
$MergedObjects|Export-Csv -Path 'Neu.csv' -NoTypeInformation
pause

..ist doch garnicht schwer...

  • https://docs.microsoft.com/de-de/powershell/scripting/learn/deep-dives/everything-about-pscustomobject
  • https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/export-csv
...zur Antwort
Noch nie gehabt

Wenn man als Fotograf mit einer ordentlichen u Kameraausrüstung unterwegs ist, sollte man bei der Qualität einer SDkarte nicht geizen. Ich bin in den vergangenen Jahren immer recht gut mit Samsung SDs unterwegs gewesen).

...Allerdings sollte man sich bei SD prinzipiell an die "Physik" dahinter halten, dann überlebt auch ein "Billigheimer"...

SDspeicher kann nur begrenzt überschrieben werde dann sind die Speicherzellen "ausgebrannt" für einen Fotografen heist dies, möglichst kein Löschen/überschreiben von unbrauchbaren Bildern. (Das wäre schreiben in die gleichen Speicherzellen). Keine Ionisierende Strahlung. Keine Daten speichern welche nichts mit Fotos zu tun haben.

Es werden zwar von den Herstellern riesige "Schreibwerte" angegeben, die sind jedoch bezogen auf ein ausgeklügeltes Speichermanagenent und eine gewisse Speicherreserve. Die reale Anzahl von Schreibzyklen pro Zelle ist bei modernen SD wesentlich geringer als bei den "Riesenchips" vor 15 Jahren.

Die SD der Kamera gehört nur der Kamera und ist kein Speichermedium für irgendwelchen andern Schnickschnack!

...dann lebt eine SD nahezu Ewig.

Wenn man ein wichtiges Fotoevent hat , wo absolut nichts schiefgehen sollte, ist es ein kleiner Preis für einen Zehner eine "jungfräuliche" SD einzulegen...

Ich musste noch nie irgendwelche Fotos von einer SD retten.

Es sollte selbstverständlich sein, das man möglichst zeitnah wichtige Fotos auf ein "sicheres" Medium überträgt (HDD/Cloud). Original nicht Löschen, sonst werden "gebrauchte" Speicherzellen wieder mit einbezogen!

Auf eine 32GB passen 1200 Foto im RAW-Format. Für einen Durchnittsknipser dürfte das für Monate ausreichen...

...zur Antwort

vergiss VBScript...🤢

VBScipt war schon zu seiner "Blütezeit" nicht gerade das gelbe vom Ei. Die einzige Existenzberechtigung war die Möglichkeit, einigermaßen umständlich über ActiveX-Steuerelmente/-Objekte auf systemnahe Funktionen zuzugreifen.

Da der Umgang mit Basisfunktionen jedoch langatmig und aufwändig war und sich für den Nutzer keine wirklichen Vorteile zu Batch oder Compilierten Sprache ergaben wurden VBS in der Regel nur als dynamisch generierte Hilfsscripte genutzt. (welcher Administrator möchte schon 20 Zeilen VBS tippen, wenn eine Zeile Batch das gleiche leistet?)

Ich bin schon sehr lange im Geschäft, aber wirklich lustige Sachen kann man mit VBS nicht machen. (ob Jemand das unverhoffte automatische ausfahren eines DVD-Laufwerks oder anderen Missbrauch von systemnahen Steuerfunktionen als lustig empfindet wage ich zu bezweifeln) Hier eine JScript-Adaption des Themas: https://www.gutefrage.net/frage/wieso-funktioniert-dieser-java-script-code-nicht#answer-310455861

VBScript ist wird seit nunmehr 13 Jahren nicht mehr von Microsoft supported die gesamte Funktionalität ist auf dem Stand von 2009 eingefroren und nur noch aus Kompatibilität mit Uraltadminscripten in modernen Systemen vorhanden.

Unter https://www.gutefrage.net/home/thema/batch-trick/neue/1 findest Du diversen Schabernack mit Batch in Kombination mit anderen Scriptsprachen. die häufige Verwendung von JScript ist einfach der besseren Handhabbarkeit gegenüber VBScript geschuldet (die Funktion ist die gleiche) ...Zukunftweisend sind die Spielerein jedoch nicht

Lass den alten Mist in seinem "Grab". Powershell und C# sind moderne Sprachen, welche in ihrer Funktionalität kaum Wünsche offen lassen.

...zur Antwort

einfach so...:

@echo off
chcp 65001 >nul

:drawMenu
echo Menü
echo [1] Tue dies
echo [2]  Mach jenes
echo [x] tschüß...

:ask2
set /p "userinp=Input:"
set "userinp=%userinp:~0,3%"  &rem keine Ahnung was das soll
if "%userinp%"=="1" (goto :test)
if "%userinp%"=="2" (cls & goto :misc_menu)
if /i "%userinp%"=="x" (exit /b)  &rem  /i ignorier Groß/Kleinschreibung 
echo ich  bin die Situation mit unerwartetem Input!
goto :ask2
  rem hier kommt diese Batch nie hin, trotzdem einen "Sicherheitsausgang"
exit /b
 
:Test
echo Hallo ich  bin Test
goto :ask2


:misc_menu
echo Miskmenü
echo ....
echo ....
echo ende Miscmenü
echo blah und Blubb
echo:
goto :drawMenu

...aber warum dem Nutzer die Wahl einer unerwünschten Eingabe lassen?

verwende Choice, dann kann es keinen falsche Eingabe geben.

@echo off
chcp 65001 >nul

:drawMenü
echo Menü
echo [1] Tue dies
echo [2]  Mach jenes
echo [x] tschüß...

:ask2
choice /c 12x
if %errorlevel% equ 1 (goto :test)
if %errorlevel% equ 2 (cls & goto :misc_menu)
  rem die  3.option  brauchst Du nicht explizit abfragen da nur  noch errorlevel=3 übrig bleibt
exit /b
 
:Test
echo Hallo ich  bin Test
goto :ask2


:misc_menu
echo Miskmenü
echo ....
echo ....
echo ende Miscmenü
echo blah ^& Blubb
echo:
goto :drawMenü
  • https://ss64.com/nt/choice.html
...zur Antwort