1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Oscar

Beiträge von Oscar

  • PCIe 5 SSD

    • Oscar
    • 7. November 2025 um 09:10

    Ich muss mich noch mal melden und mich bei euch entschuldigen, denn mir ist da ein gravierender Fehler passiert. Sorry!
    Also, nicht was die Empfehlung zur Crucial P510 betrifft. Die bleibt bestehen!

    Aber "wer misst, misst Mist" traf auf mich ziemlich offensichtlich zu. Die genauen Einzelheiten habe ich im Post #1 ausgebessert/ausgeweitet.

  • PCIe 5 SSD

    • Oscar
    • 2. November 2025 um 18:19
    Zitat von Andy

    Wurde ein Ryzen 9600X und ein Asrock B850M Pro-A Wifi (auch mit einem PCIe Gen5 Steckplatz für SSD) , 32GB RAM habe ich mir auch dazu gegönnt

    Ich habe mir auch einen Ryzen 5 9600X geholt. Allerdings als Mainboard das ASUS B650-Plus (WiFi brauche ich nicht). Ich brauche auf jeden Fall min. 4 SATA-Ports für meine drei 3,5 Zoll Festplatten und den DVD-Brenner (auch wenn ich den in letzter Zeit selten benutzt habe).
    Außerdem sollten es min. zwei M2-Ports sein (das Asus hat sogar drei) und es sollten schnelle USB3.2 Ports dabei sein. Und ich bin schon seit Jahren Asus-Fan. :)

    Beim RAM habe ich gleich auf 48 GB (2x24) gesetzt. Das war Preis-/Leistungsmäßig am sinnvollsten.

  • PCIe 5 SSD

    • Oscar
    • 2. November 2025 um 08:18
    Zitat von AspirinJunkie

    Was habt ihr für Anwendungen wo derart hohe Datenraten relevant sind?

    Naja, es gibt schon einige Bereiche, wo man diese hohen Transferraten bemerkt (zumindest im Vergleich zu einer SATA-SSD) :

    1. Beim laden von 3D-Games (da werden meist mehrere GB geladen).

    2. Beim bearbeiten von Videos oder Audiodateien (je nach Größe).

    3. Beim kopieren von großen Dateien vom externen USB3-Speicher (falls der schnell genug ist).

    4. Wenn mehrere Prozesse gleichzeitig Daten auf die SSD kopieren (ok, das kommt bei mir nicht so oft vor).

    Aber ich gebe Dir Recht, wenn man sowieso schon eine M2-SSD besitzt, lohnt sich ein Umstieg auf PCIe Gen5 nicht unbedingt.
    Meine andere M2-SSD (per PCIe 4 angebunden) schafft auch schon 1.5 GB/s. Bei mir wurde die Neue halt eine 5er, weil der
    Preisunterschied nur gering war.

  • PCIe 5 SSD

    • Oscar
    • 1. November 2025 um 09:04

    Uih, so viele Antworten! :)

    Noch kurz etwas zur SSD: Bei diesen hohen Transferraten fehlt mir in der Praxis ein Laufwerk, dass als Quell-Laufwerk dienen könnte.
    Da bleibt eigentlich nur das RAM bzw. halt Programme, die diese Daten so schnell zur Verfügung stellen. 8)

    Und zur Installation von Win11 ohne MS-Konto habe ich das hier befolgt (kein Netzwerkkabel anschliessen oder per WLAN verbinden! )

    Nach dem Neustart kann man dann auswählen: "Ich habe kein Internet." und man kann ein lokales Konto erstellen. Das hat problemlos
    geklappt.

  • PCIe 5 SSD

    • Oscar
    • 31. Oktober 2025 um 18:24

    Ich habe mir nach etwas über 10 Jahren mal wieder einen neuen PC zusammengestellt (ja, auch wegen Win11).

    Mein neues Mainboard besitzt 3 M2-Steckplätze. Einen davon mit PCIe Gen5 und weil ich mir sowieso eine neue SSD holen wollte, wurde es die Crucial P510 2TB (Speicher von Micron).
    Das ist eine SSD mit PCIe Gen5 und verspricht eine Transferrate von 10.000 MBit/s (tatsächlich steht dort 10.000 MB/s).
    Im Internet habe ich schon einiges Positives über die SSD gelesen, aber jetzt konnte ich sie selbst testen.

    Edit:
    "Wer misst, misst Mist!" Das trifft auf mich hier voll und ganz zu. Diesen Satz muss ich streichen, weil hier der Fehler im Detail steckt.
    Ich muss sagen, sie übertrifft sogar die Versprechungen (Test mit H2TestW und 100 GB: >1.8 GB/s also ca. 15.0000 MBit/s).

    Das Programm H2TestW (vom Heise Verlag) ist für PCIe-SSD nicht gemacht und liefert falsche Ergebnisse, weil dort mit Dateien gearbeitet wird, die lediglich 1 GB groß sind.
    Ja, bei diesen hohen Transferraten muss man von "nur" 1 GB großen Dateien sprechen, denn das sind in dem Fall kleine Dateien. Aber die Werte von H2TestW hatten mich
    auf die falsche Fährte gelockt, nämlich, dass es sich bei der Angabe um MBit/s handelt und nicht um MB/s.

    Tatsächlich sind diese PCIe-SSDs aber bereits so schnell, dass wir es hier mit 10.000 MB/s zu tun haben. Naja, da tritt wieder der Schummelfaktor der Speicherhersteller zu Tage,
    die im Dezimalsystem rechnen, damit es nach mehr aussieht. Diesen Wert muss man also durch 10 teilen und mit 8 multiplizieren, dann kommt man zu den echten MB/s.

    Zum testen habe ich dann mal das Programm CrystalDiskMark genommen, beim dem dann auch realistische Werte ausgegeben werden.
    Die PCIe5-SSD (Crucial P510):

    Und zum Vergleich meine zweite PCIe4-SSD (eine Samsung 970 EVO Plus):

    Falls ihr also nach einer SSD mit PCIe 5 Ausschau haltet, die Crucial kann ich sehr empfehlen, vor allem weil sie momentan recht günstig ist. :thumbup:

  • EXIF-Rename

    • Oscar
    • 13. September 2025 um 07:45
    Zitat von SOLVE-SMART

    Doch damit fällt meine Modifikation "offiziell" weg. Bleibt es dabei Oscar ?

    Den letzten Satz von dem "Rechtlichen" kannst Du auch streichen. Es ging mir eher darum, dass das Programm nicht etwas abgeändert und dann verkauft wird.

  • EXIF-Rename

    • Oscar
    • 2. September 2025 um 17:59

    Wenn Du mehrere Exif-Einträge brauchst, dann ist es besser/schneller, den gesamten Exifbereich auf einmal einzulesen und die Daten im Speicher zu interpretieren.

    Das habe ich mal in dieser Funktion gemacht:

    AutoIt
    #include <FileConstants.au3>
    #include <WinAPIConv.au3>
    #include <WinAPIFiles.au3>
    #include <WinAPIHObj.au3>
    #include <WinAPIInternals.au3>
    
    
    $sEXIF_DT = _GetExifDateTime('test.jpg')
    ConsoleWrite($sEXIF_DT & @CRLF)
    
    Func _GetExifDateTime($sImgfile)
    	Local $hFile, $tBuffer, $iSOI, $iError, $iMarker, $iMarkerLength, $nBytes, $sRet = ''
    	$hFile = _WinAPI_CreateFile($sImgfile, 2, 2) ; Datei zum lesen oeffnen
    	If $hFile = 0 Then Return SetError(1, 0, $sRet)
    	$tBuffer = DllStructCreate('align 1;ushort SOI')
    	_WinAPI_ReadFile($hFile, $tBuffer, DllStructGetSize($tBuffer), $nBytes)
    	$iSOI = _WinAPI_SwapWord($tBuffer.SOI)
    	If $iSOI <> 0xFFD8 Then ; Marker: Start of Image (SOI) nicht vorhanden, dann
    		_WinAPI_CloseHandle($hFile)
    		Return SetError(2, 0, $sRet)
    	Else ; Marker: SOI vorhanden, dann handelt es sich um eine JPG-Datei
    		$tBuffer = DllStructCreate('align 1;ushort Marker;ushort Length')
    		While True
    			If Not _WinAPI_ReadFile($hFile, $tBuffer, DllStructGetSize($tBuffer), $nBytes) Then
    				_WinAPI_CloseHandle($hFile)
    				Return SetError(3, 0, $sRet) ; Fehler beim Lesen oder Dateiende erreicht
    			EndIf
    			$iMarker = _WinAPI_SwapWord($tBuffer.Marker)
    			If $iMarker < 0xFF00 Then
    				_WinAPI_CloseHandle($hFile)
    				Return SetError(4, 0, $sRet) ; JPG ohne Exif-Marker
    			EndIf
    			$iMarkerLength = _WinAPI_SwapWord($tBuffer.Length)
    			If $iMarker = 0xFFE1 Then ExitLoop ; wenn Marker: 0xFFE1, dann Schleife verlassen (vermutlich Exifdaten)
    			_WinAPI_SetFilePointer($hFile, $iMarkerLength - 2, $FILE_CURRENT) ; zum naechsten Marker springen
    		WEnd
    		Local $tExif, $pExif, $iTIFFbegin, $tTIFF, $tEntry, $iDatatyp, $iTyp, $iData, $iX, $iY, $tDT, $sDT, $iTagCount
    		$tExif = DllStructCreate('align 1;char buf[' & $iMarkerLength & ']') ; Buffer fuer den Exif-Bereich erstellen
    		$pExif = DllStructGetPtr($tExif) ; Pointer auf den Buffer
    		_WinAPI_ReadFile($hFile, $tExif, DllStructGetSize($tExif), $nBytes) ; den gesamten Exif-Bereich einlesen
    		_WinAPI_CloseHandle($hFile) ; Datei schliessen
    		$tBuffer = DllStructCreate('align 1;char Exif[6]', $pExif) ; Struktur fuer String "Exif" und zwei Nullbytes
    		If $tBuffer.Exif = 'Exif' Then ; wenn zusaetzlich "Exif" vorhanden, dann handelt es sich um ein JPG mit Exifdaten
    			$pExif += DllStructGetSize($tBuffer)
    			$iTIFFbegin = $pExif ; Anfang des TIFF-Headers merken
    			$tTIFF = DllStructCreate('align 1;ushort Endian;ushort Code;ulong Offset', $pExif) ; Struktur des TIFF-Headers
    			$pExif += DllStructGetSize($tTIFF)
    			For $iIFD = 0 To 1 ; es gibt zwei Image File Directories (IFDs)
    				$tBuffer = DllStructCreate('align 1;ushort TagCount', $pExif) ; die Anzahl der TAGs in dem IFD
    				$pExif += DllStructGetSize($tBuffer)
    				Do
    					$tEntry = DllStructCreate('align 1;ushort Typ;ushort Datatyp;ulong Length;ulong Data', $pExif) ; Struktur der Eintraege
    					$pExif += DllStructGetSize($tEntry)
    					$iTyp = ($tTIFF.Endian = 0x4D4D ? _WinAPI_SwapWord($tEntry.Typ) : $tEntry.Typ)
    					$iDatatyp = ($tTIFF.Endian = 0x4D4D ? _WinAPI_SwapWord($tEntry.Datatyp) : $tEntry.Datatyp)
    					$iData = ($tTIFF.Endian = 0x4D4D ? _WinAPI_SwapDWord($tEntry.Data) : $tEntry.Data)
    ;~ 					ConsoleWrite(StringFormat('!> Zeile:%i, Typ: 0x%.4X, Datatyp: %i, RawData: %i\r\n', @ScriptLineNumber, $iTyp, $iDatatyp, $iData))
    					Switch $iTyp
    						Case 0xA002 ; X-Aufloesung
    							$iX = $iData
    						Case 0xA003 ; Y-Aufloesung
    							$iY = $iData
    						Case 0x0132, 0x9003, 0x9004
    							; 0x0132 = Erstellungsdatum (ExifDTCreated)
    							; 0x9003 = Aufnahmedatum (ExifDTOrig)
    							; 0x9004 = Digitalisierungsdatum (ExifDTDigitized)
    							$tDT = DllStructCreate('align 1;char DT[20]', $iTIFFbegin + $iData)
    							$sDT = StringReplace(StringLeft($tDT.DT, 10), ':', '/') & StringMid($tDT.DT, 11)
    							$sRet &= '0x' & Hex($iTyp, 4) & ' ' & $sDT & @CR
    						Case 0x8769 ; Position auf den naechsten IFD
    							$pExif = $iTIFFbegin + $iData
    							ExitLoop
    					EndSwitch
    					$iTagCount += 1 ; Anzahl der Tags erhoehen
    				Until $iTagCount > $tBuffer.TagCount
    				$iTagCount = 0
    			Next
    			$sRet = 'Resolution: ' & $iX & 'x' & $iY & @CR & $sRet
    		EndIf
    	EndIf
    	Return $sRet
    EndFunc
    Alles anzeigen
  • EXIF-Rename

    • Oscar
    • 2. September 2025 um 12:34
    Zitat von Tweaky

    Weißt du auch wie man Exif.Photo.DateTimeDigitized und Exif.Photo.DateTimeOriginal auslesen kann?

    Ich habe Dir mal die Funktion umgeschrieben:

    AutoIt
     #include <FileConstants.au3>
    #include <WinAPIConv.au3>
    #include <WinAPIFiles.au3>
    #include <WinAPIHObj.au3>
    #include <WinAPIInternals.au3>
    
    
    $sEXIF_DT = _GetExifDateTime('test.jpg')
    ConsoleWrite($sEXIF_DT & @CRLF)
    
    Func _GetExifDateTime($sImgfile)
    	Local $tDT, $hFile, $tBuffer, $nBytes, $iSOI, $iMarker, $iMarkerLength, $iTIFFbegin, $tTIFF
    	Local $tEntry, $iTyp, $iOffset, $iTagCount, $iError = 0, $iTmpOffset, $sRet, $iX, $iY
    	$tDT = DllStructCreate('char DT[20]')
    	$hFile = _WinAPI_CreateFile($sImgfile, 2, 2) ; Datei zum lesen oeffnen
    	If $hFile = 0 Then Return SetError(1, 0, '')
    	$tBuffer = DllStructCreate('ushort SOI')
    	_WinAPI_ReadFile($hFile, $tBuffer, DllStructGetSize($tBuffer), $nBytes)
    	$iSOI = _WinAPI_SwapWord($tBuffer.SOI)
    	If $iSOI = 0xFFD8 Then ; wenn Marker: Start of Image (SOI) vorhanden, dann JPG
    		$tBuffer = DllStructCreate('ushort Marker;ushort Length')
    		Do
    			If Not _WinAPI_ReadFile($hFile, $tBuffer, DllStructGetSize($tBuffer), $nBytes) Then
    				$iError = 2 ; Fehler beim Lesen oder Dateiende erreicht
    				ExitLoop
    			EndIf
    			$iMarker = _WinAPI_SwapWord($tBuffer.Marker)
    			If $iMarker < 0xFF00 Then
    				$iError = 3 ; JPG ohne Exif-Marker
    				ExitLoop
    			EndIf
    			$iMarkerLength = _WinAPI_SwapWord($tBuffer.Length)
    			If $iMarker = 0xFFE1 Then ExitLoop ; wenn Marker: 0xFFE1, dann Schleife verlassen (vermutlich Exifdaten)
    			_WinAPI_SetFilePointer($hFile, $iMarkerLength - 2, $FILE_CURRENT) ; zum naechsten Marker springen
    		Until $iError > 0
    		If $iError Then ; wenn keine Exifdaten vorhanden, dann beenden
    			_WinAPI_CloseHandle($hFile)
    			Return SetError($iError, 0, '')
    		EndIf
    		$tBuffer = DllStructCreate('char Exif[6]') ; Struktur fuer String "Exif" und zwei Nullbytes
    		_WinAPI_ReadFile($hFile, $tBuffer, DllStructGetSize($tBuffer), $nBytes)
    		If $tBuffer.Exif = 'Exif' Then ; wenn zusaetzlich "Exif" vorhanden, dann handelt es sich um ein JPG mit Exifdaten
    			$iTIFFbegin = _WinAPI_GetFilePointerEx($hFile) ; Anfang des TIFF-Headers merken
    			$tTIFF = DllStructCreate('ushort Endian; ushort Code; ulong Offset') ; Struktur des TIFF-Headers
    			_WinAPI_ReadFile($hFile, $tTIFF, DllStructGetSize($tTIFF), $nBytes)
    			For $i = 0 To 1 ; es gibt zwei Image File Directories (IFDs)
    				$tBuffer = DllStructCreate('ushort TagCount') ; die Anzahl der TAGs in dem IFD
    				_WinAPI_ReadFile($hFile, $tBuffer, DllStructGetSize($tBuffer), $nBytes)
    				$tEntry = DllStructCreate('align 1; ushort Typ; ushort Datatyp; ulong Length; ulong Offset') ; Struktur der Eintraege
    				Do
    					If Not _WinAPI_ReadFile($hFile, $tEntry, DllStructGetSize($tEntry), $nBytes) Then ExitLoop 2
    					; Die Daten können unterschiedlich kodiert sein: 0x4D4D = BigEndian oder 0x4949 = LittleEndian
    					$iTyp = ($tTIFF.Endian = 0x4D4D ? _WinAPI_SwapWord($tEntry.Typ) : $tEntry.Typ)
    					$iOffset = ($tTIFF.Endian = 0x4D4D ? _WinAPI_SwapDWord($tEntry.Offset) : $tEntry.Offset)
    					Switch $iTyp
    						Case 0xA002 ; X-Aufloesung
    							$iX = $iOffset
    						Case 0xA003 ; Y-Aufloesung
    							$iY = $iOffset
    						Case 0x0132, 0x9003, 0x9004
    							; 0x0132 = Erstellungsdatum (ExifDTCreated)
    							; 0x9003 = Aufnahmedatum (ExifDTOrig)
    							; 0x9004 = Digitalisierungsdatum (ExifDTDigitized)
    							$iTmpOffset = _WinAPI_GetFilePointerEx($hFile)
    							_WinAPI_SetFilePointer($hFile, $iTIFFbegin + $iOffset)
    							_WinAPI_ReadFile($hFile, $tDT, 0x14, $nBytes) ; und ist 20 Bytes (0x14) lang.
    							$sRet &= '0x' & Hex($iTyp, 4) & ' -> ' & $tDT.DT & @CRLF
    							_WinAPI_SetFilePointer($hFile, $iTmpOffset)
    						Case 0x8769 ; Position auf den naechsten IFD
    							_WinAPI_SetFilePointer($hFile, $iTIFFbegin + $iOffset)
    							ExitLoop
    					EndSwitch
    					$iTagCount += 1 ; Anzahl der Tags erhoehen
    				Until $iTagCount > $tBuffer.TagCount
    				$iTagCount = 0
    			Next
    			$sRet &= $iX & 'x' & $iY & @CRLF
    		EndIf
    	EndIf
    	_WinAPI_CloseHandle($hFile)
    	Return $sRet
    EndFunc   ;==>_GetExifDateTime
    Alles anzeigen
  • EXIF-Rename

    • Oscar
    • 30. August 2025 um 17:14

    Hintergrundgeschichte:
    Mein Schwager hat tausende JPG-Bilder auf seinem Rechner, die meistens von irgendwelchen Digitalkameras oder Smartphones stammen. Alle mit mehr oder weniger kryptischen Dateinamen plus Zaehler.
    Zum Teil mit identischen Dateinamen in unterschiedlichen Unterverzeichnissen. Ich schlug ihm vor, dass er diese doch wenigstens nach Datum/Uhrzeit umbenennen kann, um da etwas Ordnung reinzubekommen. Also habe ich mal wieder AutoIt bemüht und ihm ein Programm geschrieben, welches anhand der EXIF-Daten einen entsprechenden Dateinamen generiert und die Datei so umbenennt.

    Technisches:
    Das auslesen der EXIF-Daten kann man entweder mit den GDI+ Funktionen erledigen, was allerdings relativ lange dauert, weil man das Bild erst komplett in den Speicher laden muss. Bei mehreren Hundert Bilder dauert das seeehr lange.
    Also habe ich im Internet recherchiert und mir den Aufbau der Struktur direkt in den Binärdaten der Datei angesehen. So kann man die EXIF-Daten sehr viel schneller auslesen, weil man nur wenige Bytes der Datei einlesen muss.
    Problematisch war, dass mein Schwager auch Bilder hat, die keinerlei EXIF-Daten enthalten und diverse Bilder, bei denen die EXIF-Daten fehlerhaft sind. Also habe ich noch eine Fallback-Funktion eingebaut, bei der in diesen Fällen das Dateierstellungsdatum verwendet wird und falls das JPG selbst kaputt ist (da waren auch einige dabei), wird "1900-01-01__00-00-00" als Dateiname zurückgegeben. Auf diese Weise sieht er gleich, woran er ist.

    Naja, lange Rede kurzer Sinn: Vielleicht könnt ihr ja auch so ein Programm gebrauchen.


    Eigenschaften:

    - "Drag and drop" von Verzeichnissen/Dateien auf ein markiertes Feld im Hauptfenster.

    - Verzeichnisse können auch rekursiv eingelesen werden (das kann u.U. aber sehr lange dauern, wenn dort mehrere Tausend Bilder liegen)

    - Hauptfenster kann "Immer im Vordergrund" gesetzt werden.

    - Ein bereits bestehender Dateiname wird an das EXIF-Datum/Uhrzeit angehängt, wenn der Haken im Listview gesetzt ist.

    - Über das Kontextmenü beim Listview kann man das markieren/anhaken etwas komfortabler erledigen.

    - Eine Vorschau-Funktion, wenn man eine Datei im Listview doppelt anklickt.


    Das Script gibt es als ZIP-Archiv im Anhang zum download.


    Screenshot:

    Dateien

    EXIF_Rename_2.0.zip 34,36 kB – 82 Downloads
  • Arduino - Problem

    • Oscar
    • 22. Juni 2025 um 15:26
    Zitat von BugFix

    Gebe ich auf die IN-Kontakte des Relais Moduls direkt GND, zieht das entsprechende Relais.

    Wenn die Relais Low-aktiv sind mußt Du im Sketch auch LOW für EIN benutzen.

    Zitat von BugFix

    Pulldown habe ich 10k genommen, sollte völlig ausreichen.

    Wozu einen Pulldown-Widerstand, wenn Du im Sketch INPUT_PULLUP definierst?

    Bei INPUT_PULLUP brauchst Du gar keinen externen Widerstand. Einfach nach GND tasten.

  • Anti "false-positive" Strategie mit PureBasic

    • Oscar
    • 18. Januar 2025 um 10:34
    Zitat von Schnuffel

    die lediglich die 2 AutoIt exen und ein paar Registry Einträge erstellt.

    Die Registry-Einträge bräuchte man gar nicht unbedingt.

    Wenn die AutoIt-Exe im a3x Verzeichnis liegt, müsste man nur eine Verknüpfung (in der die AutoIt-Exe mit dem a3x gestartet wird) in dem Verzeichnis erstellen.

  • Anti "false-positive" Strategie mit PureBasic

    • Oscar
    • 18. Januar 2025 um 09:14
    Zitat von Schnuffel

    die auf dem Zielrechner lediglich eine a3x Unterstützung installiert

    Dafür bräuchte man ja lediglich die 32/64 Bit exe im a3x-Verzeichnis.

    Ich hatte gestern schon die Idee, das alles zu packen und als BASE64 in ein NIM-Programm zu integrieren, sodass man damit die exe ins Scriptverzeichnis entpacken kann.

    Allerdings wenn ein AV-Programm bereits auf die AutoIt-Exe anschlägt, wird das auch keine Lösung sein. :/

  • Icon extrahieren - Skript läuft nicht

    • Oscar
    • 4. Januar 2025 um 15:19
    Zitat von Tweaky

    Bekommt es von euch jemand hin?

    Das geht sehr viel kürzer und unabhängig von 32/64 Bit:

    AutoIt
    #include <WinAPIGdi.au3>
    #include <WinAPIIcons.au3>
    #include <WinAPIShellEx.au3>
    #AutoIt3Wrapper_UseX64=y
    Global $iIconSize = 64
    Global $hIcon = _WinAPI_ShellExtractIcon('shell32.dll', -42, $iIconSize, $iIconSize)
    _WinAPI_SaveHICONToFile(@ScriptDir & '\test.ico', $hIcon)
    _WinAPI_DestroyIcon($hIcon)
  • _WinAPI_ShellChangeNotifyRegister 64bit - Absturz

    • Oscar
    • 1. Januar 2025 um 13:59
    Zitat von Velted

    das ist eine von den 'Shell-Ausrichtungsfallen'. Die Struktur SHChangeNotifyEntry ist in ShlObj_core.h definiert. Da steht am Anfang ein
    #include <pshpack1.h> /* Assume byte packing throughout */,
    das auch für die Struktur gilt und ein 'Byte-Packing' erzwingt.

    Ah! Vielen Dank!

    So funktioniert es dann:

    AutoIt
    #Region    ;************ Includes ************
    #include <WinAPISysWin.au3>
    #include <WinAPIShellEx.au3>
    #EndRegion ;************ Includes ************
    #AutoIt3Wrapper_UseX64=y ;32bit funktioniert / 64bit funktioniert
    
    Global $aTest[] = ["C:\_test\", "C:\_test2\", "C:\_test3\", "C:\_test4\"]
    
    For $i = 0 To UBound($aTest) - 1
    	DirCreate($aTest[$i])
    Next
    
    OnAutoItExitRegister('OnAutoItExit')
    HotKeySet('{ESC}', '_End')
    
    Global $hWnd = GUICreate('')
    Global $iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY')
    GUIRegisterMsg($iMsg, 'WM_SHELLCHANGENOTIFY')
    Global $g_iID = _WinAPI_ShellChangeNotifyRegister64($hWnd, $iMsg, $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $aTest, 1)
    If @error Then
    	MsgBox(($MB_ICONERROR + $MB_SYSTEMMODAL), 'Fehler', 'Das Fenster wurde nicht registriert.')
    	Exit
    EndIf
    
    While 1
    	Sleep(1000)
    WEnd
    
    Func _End()
    	Exit
    EndFunc   ;==>_End
    
    Func OnAutoItExit()
    	If $g_iID Then
    		_WinAPI_ShellChangeNotifyDeregister($g_iID)
    	EndIf
    EndFunc   ;==>OnAutoItExit
    
    Func WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
    	#forceref $hWnd, $iMsg
    	Local $tIDL = DllStructCreate((@AutoItX64 ? 'uint64 Item1;uint64 Item2;' : 'dword Item1;dword Item2;'), $wParam) ; bei 64 Bit ist das ein QWord (8 Byte)
    	Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData($tIDL, 'Item1'))
    	If $sPath Then
    		ConsoleWrite('Event: 0x' & Hex($lParam) & ' | Pfad: ' & $sPath & @CRLF)
    	Else
    		ConsoleWrite('Event: 0x' & Hex($lParam) & @CRLF)
    	EndIf
    EndFunc   ;==>WM_SHELLCHANGENOTIFY
    
    Func _WinAPI_ShellChangeNotifyRegister64($hWnd, $iMsg, $iEvents, $iSources, $aPaths, $bRecursive = False)
    	Local $iPath = $aPaths, $tagStruct = 'align 1;'
    
    	If IsArray($aPaths) Then
    		If UBound($aPaths, $UBOUND_COLUMNS) Then Return SetError(1, 0, 0)
    	Else
    		Dim $aPaths[1] = [$iPath]
    	EndIf
    	For $i = 0 To UBound($aPaths) - 1
    		If Not _WinAPI_PathIsDirectory($aPaths[$i]) Then Return SetError(2, 0, 0)
    	Next
    	For $i = 0 To UBound($aPaths) - 1
    		$tagStruct &= 'ptr;int;'
    	Next
    	Local $tEntry = DllStructCreate($tagStruct)
    	For $i = 0 To UBound($aPaths) - 1
    		$aPaths[$i] = _WinAPI_ShellILCreateFromPath(_WinAPI_PathSearchAndQualify($aPaths[$i]))
    		DllStructSetData($tEntry, 2 * $i + 1, $aPaths[$i])
    		DllStructSetData($tEntry, 2 * $i + 2, $bRecursive)
    	Next
    	Local $iError = 0
    	Local $aCall = DllCall('shell32.dll', 'ulong', 'SHChangeNotifyRegister', 'hwnd', $hWnd, 'int', $iSources, 'long', $iEvents, _
    			'uint', $iMsg, 'int', UBound($aPaths), 'struct*', $tEntry)
    	If @error Or Not $aCall[0] Then $iError = @error + 10
    
    	For $i = 0 To UBound($aPaths) - 1
    		_WinAPI_CoTaskMemFree($aPaths[$i])
    	Next
    	Return SetError($iError, 0, $aCall[0])
    EndFunc   ;==>_WinAPI_ShellChangeNotifyRegister64
    Alles anzeigen
  • _WinAPI_ShellChangeNotifyRegister 64bit - Absturz

    • Oscar
    • 1. Januar 2025 um 13:03
    Zitat von Velted

    Ich denke, dass sich der Feldindex (@AutoItX64 ? 4 : 2) * $i + 1 von 32- zu 64-Bit nicht ändert.

    Ja, das war falsch!

    Der Feldindex bleibt gleich, auch wenn das damit funktioniert hat (warum versuche ich gerade rauszukriegen).

  • _WinAPI_ShellChangeNotifyRegister 64bit - Absturz

    • Oscar
    • 31. Dezember 2024 um 16:05

    Ich habe das mal auf 64 Bit angepasst:

    AutoIt
    #Region    ;************ Includes ************
    #include <WinAPISysWin.au3>
    #include <WinAPIShellEx.au3>
    #EndRegion ;************ Includes ************
    #AutoIt3Wrapper_UseX64=y ;32bit funktioniert / 64bit funktioniert
    
    Global $aTest[2] = ["C:\_test\", "C:\_test2\"]
    
    DirCreate($aTest[0])
    DirCreate($aTest[1])
    
    OnAutoItExitRegister('OnAutoItExit')
    ConsoleWrite((@AutoItX64 ? 4 : 2) & @CRLF)
    
    Local $hWnd = GUICreate('')
    Local $iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY')
    GUIRegisterMsg($iMsg, 'WM_SHELLCHANGENOTIFY')
    Global $g_iID = _WinAPI_ShellChangeNotifyRegister64($hWnd, $iMsg, $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $aTest, 1)
    If @error Then
    	MsgBox(($MB_ICONERROR + $MB_SYSTEMMODAL), 'Fehler', 'Das Fenster wurde nicht registriert.')
    	Exit
    EndIf
    
    While 1
    	Sleep(1000)
    WEnd
    
    Func WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
    	#forceref $hWnd, $iMsg
    	Local $tIDL = DllStructCreate((@AutoItX64 ? 'uint64 Item1; uint64 Item2' : 'dword Item1; dword Item2'), $wParam) ; bei 64 Bit ist das ein QWord (4 Byte)
    	Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData($tIDL, 'Item1'))
    	If $sPath Then
    		ConsoleWrite('Event: 0x' & Hex($lParam) & ' | Pfad: ' & $sPath & @CRLF)
    	Else
    		ConsoleWrite('Event: 0x' & Hex($lParam) & @CRLF)
    	EndIf
    EndFunc   ;==>WM_SHELLCHANGENOTIFY
    
    Func OnAutoItExit()
    	If $g_iID Then
    		_WinAPI_ShellChangeNotifyDeregister($g_iID)
    	EndIf
    EndFunc   ;==>OnAutoItExit
    
    Func _WinAPI_ShellChangeNotifyRegister64($hWnd, $iMsg, $iEvents, $iSources, $aPaths, $bRecursive = False)
    	Local $iPath = $aPaths, $tagStruct = ''
    
    	If IsArray($aPaths) Then
    		If UBound($aPaths, $UBOUND_COLUMNS) Then Return SetError(1, 0, 0)
    	Else
    		Dim $aPaths[1] = [$iPath]
    	EndIf
    	For $i = 0 To UBound($aPaths) - 1
    		If Not _WinAPI_PathIsDirectory($aPaths[$i]) Then Return SetError(2, 0, 0)
    	Next
    	For $i = 0 To UBound($aPaths) - 1
    		$tagStruct &= 'ptr;int;'
    	Next
    	Local $tEntry = DllStructCreate($tagStruct)
    	For $i = 0 To UBound($aPaths) - 1
    		$aPaths[$i] = _WinAPI_ShellILCreateFromPath(_WinAPI_PathSearchAndQualify($aPaths[$i]))
    		DllStructSetData($tEntry, (@AutoItX64 ? 4 : 2) * $i + 1, $aPaths[$i]) ; bei 64Bit ist PIDLIST_ABSOLUTE = 64 Bit (4 Byte)
    		DllStructSetData($tEntry, (@AutoItX64 ? 4 : 2) * $i + 2, $bRecursive)
    	Next
    
    	Local $iError = 0
    	Local $aCall = DllCall('shell32.dll', 'ulong', 'SHChangeNotifyRegister', 'hwnd', $hWnd, 'int', $iSources, 'long', $iEvents, _
    			'uint', $iMsg, 'int', UBound($aPaths), 'struct*', $tEntry)
    	If @error Or Not $aCall[0] Then $iError = @error + 10
    
    	For $i = 0 To UBound($aPaths) - 1
    		_WinAPI_CoTaskMemFree($aPaths[$i])
    	Next
    
    	Return SetError($iError, 0, $aCall[0])
    EndFunc   ;==>_WinAPI_ShellChangeNotifyRegister
    Alles anzeigen
  • Denkknoten im Umgang mit Timerinit/Timerdiff

    • Oscar
    • 12. Juli 2024 um 13:27

    Man kommt auch ganz ohne Adlib und mit nur einem Timer aus:

    AutoIt
    $iTimer = TimerInit()
    
    $iIntervallmeldung = 60000
    $iDauermeldung = 5000
    HotKeySet('{ESC}', _Exit)
    
    While Sleep(1000)
    	_CheckMeldung()
    WEnd
    
    Func _CheckMeldung()
    	Local Static $iLastMillis = 0, $bMeldung = False
    	Local $iMillis = TimerDiff($iTimer)
    	ConsoleWrite(Int(($iMillis - $iLastMillis) / 1000) & @CRLF)
    	If $iMillis - $iLastMillis > $iIntervallmeldung Then
    		$iLastMillis = $iMillis
    		$bMeldung = True
    	EndIf
    	If $bMeldung Then
    		ConsoleWrite(' Alarm' & @CRLF)
    		If $iMillis - $iLastMillis > $iDauermeldung Then
    			ConsoleWrite(' Alarm aus' & @CRLF)
    			$bMeldung = False
    		EndIf
    	EndIf
    EndFunc
    
    Func _Exit()
    	Exit
    EndFunc
    Alles anzeigen
  • sortieren nach IP

    • Oscar
    • 26. Juni 2024 um 17:19

    Dann will ich auch noch eine Möglichkeit beisteuern (vom Prinzip her wie bei Kanashius, nur mit 32Bit UINT):

    AutoIt
    #include <Array.au3>
    Local $aListViewData[10][4] = [ _
        ["PC-001", "00:1A:2B:3C:4D:5E", "192.168.23.145", "Büro 101"], _
        ["PC-002", "00:2B:3C:4D:5E:6F", "10.0.15.87", "Empfang"], _
        ["PC-003", "00:3C:4D:5E:6F:7G", "172.16.78.209", "Besprechungsraum"], _
        ["PC-004", "00:4D:5E:6F:7G:8H", "192.168.1.3", "Buchhaltung"], _
        ["PC-005", "00:5E:6F:7G:8H:9I", "10.10.55.201", "Marketing"], _
        ["PC-006", "00:6F:7G:8H:9I:0J", "172.20.100.50", "Entwicklung 1"], _
        ["PC-007", "00:7G:8H:9I:0J:1K", "192.168.0.11", "Entwicklung 2"], _
        ["PC-008", "00:8H:9I:0J:1K:2L", "10.1.1.254", "Personalabteilung"], _
        ["PC-009", "00:9I:0J:1K:2L:3M", "172.31.255.1", "Kantine"], _
        ["PC-010", "00:0J:1K:2L:3M:4N", "192.168.100.100", "Serverraum"] _
    ]
    
    For $i = 0 To UBound($aListViewData) - 1
    	$aListViewData[$i][2] = _IPaddrToUInt($aListViewData[$i][2])
    Next
    _ArraySort($aListViewData, 1, 0, 0, 2)
    For $i = 0 To UBound($aListViewData) - 1
    	$aListViewData[$i][2] = _UIntToIPaddr($aListViewData[$i][2])
    Next
    _ArrayDisplay($aListViewData)
    
    Func _IPaddrToUInt($sIP)
    	Local $tAddr = DllStructCreate('uint IP')
    	Local $aTmp = StringSplit($sIP, '.', 2)
    	Local $iAddr = BitOR(BitShift(Int($aTmp[0]), -24), BitShift(Int($aTmp[1]), -16), BitShift(Int($aTmp[2]), -8), Int($aTmp[3]))
    	$tAddr.IP = $iAddr
    	Return $tAddr.IP
    EndFunc
    
    Func _UIntToIPaddr($iAddr)
    	Local $tAddr = DllStructCreate('uint IP')
    	$tAddr.IP = $iAddr
    	Local $tIP = DllStructCreate('byte D;byte C;byte B;byte A', DllStructGetPtr($tAddr))
    	Return $tIP.A & '.' & $tIP.B & '.' & $tIP.C & '.' & $tIP.D
    EndFunc
    Alles anzeigen

    Wenn man die Daten gleich im UINT-Format speichert, braucht man sie nur bei der Anzeige zurückwandeln.

  • Combobox mit mehreren Spalten

    • Oscar
    • 25. Juni 2024 um 16:32
    Zitat von atomas

    Besten Dank, ich werde mal schauen ob ich das erweitern kann, so wie ich das möchte.

    Gern geschehen!

    Ja, es kommt noch darauf an, was Du mit dem Listview vor hast. Wenn es nicht nur eine Auswahlbox sein soll, muss man da evtl. noch zusätzliche GUI-Elemente ein-/ausblenden.

    Wenn Du Hilfe brauchst, sag Bescheid!

  • RichEdit Hyperlinks

    • Oscar
    • 24. Juni 2024 um 17:23

    Mit dem Beispiel aus der Hilfe funktioniert es:

    AutoIt
    #include <GuiRichEdit.au3>
    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WinAPIShellEx.au3>
    #include <MsgBoxConstants.au3>
    
    
    Global $hWh = GUICreate("RichEdit Link Test", 600, 400)
    Global $hRichEdit = _ChatBoxCreate($hWh, 10, 10, 580, 380)
    GUISetState()
    
    $data = "Hier ist ein Link: https://www.autoit.de" & @CRLF
    _ChatBoxAdd($hRichEdit, $data)
    
    While 1
    	$nMsg = GUIGetMsg()
    	Switch $nMsg
    		Case $GUI_EVENT_CLOSE
    			ExitLoop
    	EndSwitch
    	Sleep(10)
    WEnd
    
    _GUICtrlRichEdit_Destroy($hRichEdit)
    GUIDelete($hWh)
    Exit
    
    Func _ChatBoxCreate($gui, $x = 0, $y = 0, $w = 100, $h = 100)
    	$hRichEdit = _GUICtrlRichEdit_Create($gui, "", $x, $y, $w, $h, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    	_GUICtrlRichEdit_AutoDetectURL($hRichEdit, True)
    	_GUICtrlRichEdit_SetEventMask($hRichEdit, $ENM_LINK) ; Setze das Ereignismask, um Link-Benachrichtigungen einzuschließen
    	GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    	Return $hRichEdit
    EndFunc   ;==>_ChatBoxCreate
    
    Func _ChatBoxAdd($box, $txt)
    	_GUICtrlRichEdit_AppendText($box, $txt)
    EndFunc   ;==>_ChatBoxAdd
    
    Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    	#forceref $hWnd, $iMsg, $wParam, $lParam
    	; Struktur für NMHDR
    	Local $tNMHDR = DllStructCreate("struct;hwnd hWndFrom;uint_ptr idFrom;int code;endstruct", $lParam)
    	Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    	Local $iCode = DllStructGetData($tNMHDR, "code")
    	If $hWndFrom = $hRichEdit And $iCode = $EN_LINK Then
    		$tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
    		If DllStructGetData($tMsgFilter, "msg") = $WM_LBUTTONUP Then
    			$tEnLink = DllStructCreate($tagENLINK, $lParam)
    			$iCpMin = DllStructGetData($tEnLink, "cpMin")
    			$iCpMax = DllStructGetData($tEnLink, "cpMax")
    			ConsoleWrite("Hyperlink: " & _GUICtrlRichEdit_GetTextInRange($hRichEdit, $iCpMin, $iCpMax) & @CRLF)
    		EndIf
    	EndIf
    EndFunc   ;==>WM_NOTIFY
    Alles anzeigen

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™