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

  • DisplaySettings

    • Oscar
    • 22. Oktober 2017 um 08:58
    Zitat von bazii

    Ich blicke das Script nicht ganz aber kann es sein, dass es mit folgender Zeile im ersten Script zusammenhängt?

    Ja, ich hatte das im zweiten Script absichtlich weggelassen. Damit wollte ich jetzt erstmal alle Auflösungen plus Farbtiefe und Frequenz in einem Array haben.

    Der Smilie (:() sollte da eigentlich gar nicht hin. Das hat die Forensoftware automatisch ersetzt (Klammer zu und Doppelpunkt).

  • DisplaySettings

    • Oscar
    • 21. Oktober 2017 um 18:29
    Zitat von bazii

    Wenn Du es dann hier zur Verfügung stellen würdest, fände ich es eine klasse Sache, vor allem dann, wenn das Tool portabel und auch in einer WinPE nutzbar sein wird?

    Ja klar, wenn es fertig ist, wird es auch hier veröffentlicht.

    Portabel sollte nicht das Problem sein. WinPE weiß ich nicht, ob AutoIt-Scripte im "kleinen" Windows laufen.

    Hier ist mal noch eine ausführlichere Version des obigen Scripts (es werden jetzt auch die verschiedenen Frequenzen angezeigt und es ist konfigurierbar aber es wird nicht mehr der aktive Modus markiert) :

    AutoIt
    #include <Array.au3>
    #include <WinAPI.au3>
    #include <WinAPIGdi.au3>
    
    Global $iBPP = -1 ; Bits per pixel: -1 fuer alle, ansonsten 8, 16, 32
    Global $iFreq = -1 ; Bildfrequenz (in Hz): -1 fuer alle, ansonsten 50, 59, 60, 70, 72, 75, usw.
    
    
    Global $aDevices = _GetDisplayDevices()
    Global $aDispaySettings[UBound($aDevices)], $aTmp
    For $i = 0 To UBound($aDevices) - 1
        $aTmp = _GetDisplaySettings($aDevices[$i], $iBPP, $iFreq)
        $aDispaySettings[$i] = $aTmp
        _ArrayDisplay($aTmp, $aDevices[$i], '', 0, '|', 'Width|Height|Bit|Hz')
    Next
    Exit
    
    Func _GetDisplayDevices()
        Local $aDevice, $iDevNum = 0, $sOut = ''
        While True
            $aDevice = _WinAPI_EnumDisplayDevices('', $iDevNum)
            If @error Or Not $aDevice[0] Then ExitLoop
            If BitAND($aDevice[3], 1) Then $sOut &= $aDevice[1] & @LF
            $iDevNum += 1
        WEnd
        Return StringSplit(StringTrimRight($sOut, 1), @LF, 2)
    EndFunc   ;==>_GetDisplayDevices
    
    Func _GetDisplaySettings($sDevice, $iBPP = -1, $iFreq = -1)
        Local $iMode = 0, $aData, $sOut, $sSettings, $aDisplaySettings
        While 1
            $aData = _WinAPI_EnumDisplaySettings($sDevice, $iMode)
            If @error Then ExitLoop
            If $iBPP = -1 Or $aData[2] = $iBPP Then
                If $iFreq = -1 Or $aData[3] >= $iFreq Then
                    $sSettings = StringFormat('%d|%d|%d|%d\n', $aData[0], $aData[1], $aData[2], $aData[3])
                    If Not StringInStr($sOut, $sSettings) Then $sOut &= $sSettings
                EndIf
            EndIf
            $iMode += 1
        WEnd
        $aDisplaySettings = _StringSplit2D(StringTrimRight($sOut, 1), @LF, '|')
        _ArrayNumberSort($aDisplaySettings)
        Return $aDisplaySettings
    EndFunc   ;==>_GetDisplaySettings
    
    Func _ArrayNumberSort(ByRef $aData)
        Local $iRowCount = UBound($aData, $UBOUND_ROWS), $iColCount = UBound($aData, $UBOUND_COLUMNS), $vTmp
        For $i = 0 To $iRowCount - 2
            For $j = $iRowCount - 1 To $i + 1 Step -1
                If $aData[$i][0] + $aData[$i][1] < $aData[$j][0] + $aData[$j][1] Then _Switch2D($aData, $i, $j)
                If $aData[$i][0] + $aData[$i][1] = $aData[$j][0] + $aData[$j][1] Then
                    If $aData[$i][2] < $aData[$j][2] Then _Switch2D($aData, $i, $j)
                    If $aData[$i][2] = $aData[$j][2] Then
                        If $aData[$i][3] < $aData[$j][3] Then _Switch2D($aData, $i, $j)
                    EndIf
                EndIf
            Next
        Next
    EndFunc   ;==>_ArrayNumberSort
    
    Func _Switch2D(ByRef $aData, $a, $b)
        Local $vTmp
        For $iCol = 0 To UBound($aData, $UBOUND_COLUMNS) - 1
            $vTmp = $aData[$a][$iCol]
            $aData[$a][$iCol] = $aData[$b][$iCol]
            $aData[$b][$iCol] = $vTmp
        Next
    EndFunc   ;==>_Switch2D
    
    Func _StringSplit2D($sData, $sRowDel, $sColDel)
        Local $aRows = StringSplit($sData, $sRowDel, 3)
        Local $aCol = StringSplit($aRows[0], $sColDel, 3)
        Local $aOut[UBound($aRows)][UBound($aCol)], $aTmp
        For $iRow = 0 To UBound($aRows) - 1
            $aTmp = StringSplit($aRows[$iRow], $sColDel, 3)
            For $iCol = 0 To UBound($aCol) - 1
                $aOut[$iRow][$iCol] = Number($aTmp[$iCol])
            Next
        Next
        Return $aOut
    EndFunc   ;==>_StringSplit2D
    Alles anzeigen
  • DisplaySettings

    • Oscar
    • 21. Oktober 2017 um 14:31
    Zitat von Musashi

    Wenn ich die Farbtiefe auf 16-Bit einstelle, dann wird keine der Auflösungen als '(Aktiv)' markiert, es kommt aber auch kein Fehler.

    Ja, weil ich die Ausgabe auf die 32Bit-Auflösungen beschränke. Du müsstest dann in Zeile 8 "_GetDisplaySettings" mit 16 als zweiten Parameter aufrufen (32 ist Standard).

    Gibt es wirklich noch Anwender, die "nur" 16 oder gar 8 Bit verwenden?

    Zitat von autoiter

    In meinen Anzeigeeinstellungen und im Grafiktreiber kann ich nur auf mindestens 800 x 600 gehen (Liegt wohl an einer Beschränkung in Windows?). Das Skript zeigt aber weitere, kleinere Auflösungen an.

    Ich denke auch, dass Windows die Auflösung "künstlich" nach unten begrenzt, obwohl Grafikkarte und Monitor durchaus auch kleinere Auflösungen anzeigen können.

    _WinAPI_EnumDisplaySettings gibt halt alle verfügbaren/darstellbaren Auflösungen aus.

    Mein Windows 7 lässt in den Einstellungen auch nur 800x600 als kleinste Auflösung zu, aber ich hab's gerade getestet und auch auf meinem 32 Zoll Monitor kann ich auf 640x480 umschalten.

    Das ist nicht sonderlich sinnvoll, weil einige Fenster dann nicht mehr vollständig angezeigt werden, aber es funktioniert durchaus.

  • Progressbar

    • Oscar
    • 21. Oktober 2017 um 13:13
    Zitat von AspirinJunkie

    Eventuell macht es Sinn deine UDF auf _CopyFileEx() umzustellen.

    Damit werden Dateien über eine API-Funktion kopiert, welche regelmäßig per Callback den aktuellen Stand zurückgibt.


    Vielleicht wäre das ja was für dich.

    Damit hatte ich schon mal rumgespielt. Ist aber schon eine Weile her.

    Das Problem dabei war, dass sich das Script irgendwann "aufgehängt" hat. Irgendwas mit dem Callback war da das Problem (evtl. Laufzeitprobleme, also, dass die Callback-Funktion zu lange brauchte?).

    Jedenfalls hatte ich die Variante dann aufgegeben. Die UDF (Link oben) funktioniert aber recht gut. Es werden unterschiedliche Buffergrößen benutzt (512KB bei Dateien <16MB und 8MB bei größeren Dateien).

    Das hatte ich damals so testweise ermittelt, damit klappt das kopieren recht schnell (kein großer Unterschied zu FileCopy).

  • Progressbar

    • Oscar
    • 21. Oktober 2017 um 12:37

    Ja, meine UDF (_FileCopyEx) kann einzelne oder mehrere Dateien kopieren (mit Progressbar).

    Sie basiert im Prinzip darauf, dass man nicht FileCopy benutzt, sondern die Datei mittels FileOpen/FileRead stückchenweise einliest und dann mit FileWrite stückchenweise schreibt.

    So kann man den Fortschritt überwachen und währenddessen eine Progressbar befüllen.

  • StringSplit innhalber einer Funktion, funktioniert nicht

    • Oscar
    • 21. Oktober 2017 um 12:28
    Zitat von AspirinJunkie

    Der Errohandler soll hierbei dafür sorgen dass das Skript sich nicht mit einem Fehler verabschiedet - richtig?

    Genau!

    Ohne den Errorhandler würde das Script mit einer Fehlermeldung abbrechen.

    Die Fehler kamen, weil einige Properties erst ab Windows10 existieren.

    Zitat von AspirinJunkie

    Meine Variante sollte auch bisschen als Hinweis dafür verstanden werden wie man es alternativ auch machen könnte.

    Finde ich sehr gut!

    So ist das viel besser umzusetzen. Die beste Art eine Fehlermeldung zu bearbeiten, ist es, den Fehler erst gar nicht auftreten zu lassen. ;) :thumbup:

  • DisplaySettings

    • Oscar
    • 21. Oktober 2017 um 10:44

    Ich habe vor, ein kleines Tool zum ändern der Bildschirm-Auflösung zu schreiben.

    Dazu bräuchte ich mal eure Hilfe. Dieses kleine Testscript soll alle verfügbaren Auflösungen (Einschränkung: nur die 32 Bit-Auflösungen) von allen angeschlossenen Monitoren liefern:

    AutoIt
    #include <Array.au3>
    #include <WinAPI.au3>
    #include <WinAPIGdi.au3>
    
    Global $aDevices = _GetDisplayDevices()
    Global $aDispaySettings[UBound($aDevices)], $aTmp
    For $i = 0 To UBound($aDevices) - 1
        $aTmp = _GetDisplaySettings($aDevices[$i])
        $aDispaySettings[$i] = $aTmp
        _ArrayDisplay($aTmp, $aDevices[$i])
    Next
    
    Func _GetDisplayDevices()
        Local $aDevice, $iDevNum = 0, $sOut = ''
        While True
            $aDevice = _WinAPI_EnumDisplayDevices('', $iDevNum)
            If @error Or Not $aDevice[0] Then ExitLoop
            If BitAND($aDevice[3], 1) Then $sOut &= $aDevice[1] & @LF
            $iDevNum += 1
        WEnd
        Return StringSplit(StringTrimRight($sOut, 1), @LF, 2)
    EndFunc
    
    Func _GetDisplaySettings($sDevice, $iBPP = 32)
        Local $iMode = 0, $sCurrent, $aData, $sOut, $sSettings, $aDisplaySettings
        $aData = _WinAPI_EnumDisplaySettings($sDevice, $ENUM_CURRENT_SETTINGS)
        $sCurrent = StringFormat('%d x %d, %d bit\n', $aData[0], $aData[1], $aData[2])
    
        While 1
            $aData = _WinAPI_EnumDisplaySettings($sDevice, $iMode)
            If @error Then ExitLoop
            If $aData[2] = $iBPP Then
                $sSettings = StringFormat('%d x %d, %d bit\n', $aData[0], $aData[1], $aData[2])
                $sOut &= StringReplace($sSettings, @LF, ($sSettings = $sCurrent ? ' (Aktiv)' : '')) & @LF
            EndIf
            $iMode += 1
        WEnd
        $aDisplaySettings = StringSplit(StringTrimRight($sOut, 1), @LF, 2)
        $aDisplaySettings = _ArrayUnique($aDisplaySettings, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
        _ArrayNumberSort($aDisplaySettings)
        Return $aDisplaySettings
    EndFunc
    
    Func _ArrayNumberSort(ByRef $aData)
        Local $vTmp
        For $i = 0 To UBound($aData) - 2
            For $j = UBound($aData) - 1 To $i + 1 Step -1
                If Number($aData[$i]) < Number($aData[$j]) Then
                    $vTmp = $aData[$i]
                    $aData[$i] = $aData[$j]
                    $aData[$j] = $vTmp
                EndIf
            Next
        Next
    EndFunc
    Alles anzeigen

    Bei mir (Windows 7, 64 Bit) funktioniert das auch einwandfrei, aber ich weiß nicht, ob das auch unter anderen Windows-Versionen der Fall ist.

    Wenn alles funktioniert gibt das Script pro angeschlossenen Monitor ein Array aus, in dem die Auflösungen aufgelistet sind und die gerade aktive Auflösung entsprechend markiert ist.

    Es würde mir helfen, wenn ihr das Script bei euch mal testen könnt und mir eine Rückmeldung gebt.

    Noch eine kleine Zusatzfrage: Gibt es noch jemanden, der eine nicht-32-Bit-Auflösung benutzt?

  • StringSplit innhalber einer Funktion, funktioniert nicht

    • Oscar
    • 21. Oktober 2017 um 08:48
    Zitat von Bitnugger

    und AspirinJunkie (wieder was gelernt!) sind beide sehr schön, letztere ist allerdings ohne Error-Handler

    Die Version von AspirinJunkie benötigt keinen Error-Handler, weil er die verfügbaren Properties ausliest und davon dann die Werte ermittelt. Übrigens: Gute Idee, AspirinJunkie!

  • NVidia Tray-Icon zum ändern der Auflösung?

    • Oscar
    • 20. Oktober 2017 um 16:51
    Zitat von alpines

    Schau dir mal GeForce Experience an

    Hmm...beim Start soll ich mich erstmal anmelden. Was soll das denn?

    Zitat von alpines

    Aber es sollte sicherlich UDFs dafür geben

    Na ok, die UDF funktioniert zumindest.

    Dann muss ich mir wohl mein eigenes Tray-Icon-Tool programmieren.

  • NVidia Tray-Icon zum ändern der Auflösung?

    • Oscar
    • 20. Oktober 2017 um 16:33

    Ach Mist, ich habe immer nach Tray-Icon gesucht.

    Dabei ist zumindest das de-/aktivieren des zweiten Monitors so einfach: [WINDOWS] & [P]

    Aber zum ändern der Auflösung hätte ich gern noch eine (einfachere) Lösung.

  • NVidia Tray-Icon zum ändern der Auflösung?

    • Oscar
    • 20. Oktober 2017 um 16:26

    Ich richte mich mal an diejenigen unter euch, die eine Grafikkarte von NVIDIA besitzen.

    Ich habe mir ja einen neuen Monitor zugelegt (Ich besitze nun einen 32 und einen 24 Zoll Monitor) und habe mir dann auch eine neue Grafikkarte gegönnt.

    Der Umstieg von der AMD (5770) zur NVIDIA (1050TI) verlief auch soweit problemlos und ich bin im Großen und Ganzen sehr zufrieden.

    Aber:

    Bei der AMD hatte ich ein Tray-Icon mit einem Menü, wo ich die Auflösung der Monitore ändern konnte. Das ging einfach und schnell. Und ich konnte darüber auch den Zusatzmonitor de-/aktivieren.

    Bei der NVIDIA muss ich dazu die NVIDIA-Systemsteuerung aufrufen, wozu ich erstmal auf den Desktop gehen muss. Das ist viel umständlicher und dauert länger.

    Gibt es bei NVIDIA wirklich kein Tray-Icon? Oder muss/kann man da ein Zusatzprogramm installieren?

  • StringSplit innhalber einer Funktion, funktioniert nicht

    • Oscar
    • 20. Oktober 2017 um 13:45

    Hier mal die Funktion von Bitnugger in einer von mir abgewandelten Version (Objektfehler werden abgefangen und das Array erst am Ende der Funktion erstellt:

    AutoIt
    ;-- TIME_STAMP   2017-10-20 13:40:00   v 0.2
    
    #Region ;************ Includes ************
    #include <Array.au3>
    #EndRegion ;************ Includes ************
    
    Opt('MustDeclareVars', 1) ; Variablen müssen vor der Verwendung deklariert werden
    
    Global $oErrorHandler = ObjEvent('AutoIt.Error', '_ErrFunc')
    
    Global $g_aBIOSInfo = _GetBIOSInfo()
    
    If @error Then
        ConsoleWrite("! Fehler in der Funktion _GetBIOSInfo! Error = " & @error & @CRLF)
    Else
        _ArrayDisplay($g_aBIOSInfo)
    EndIf
    
    Func _ErrFunc($oError)
        ConsoleWrite('! Zeile: ' & $oError.scriptline & ' ==> Error intercepted: ' & $oError.windescription & @CRLF)
    EndFunc   ;==>_ErrFunc
    
    Func _GetBIOSInfo()
        Local $objWMI, $colItems, $objItem, $wbemFlagReturnImmediately = 0x10, $wbemFlagForwardOnly = 0x20
        Local $sOut, $strBiosCharacteristics, $strBIOSVersion, $strListOfLanguages
        $objWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2")
        $colItems = $objWMI.ExecQuery("SELECT * FROM Win32_BIOS", "WQL", BitOR($wbemFlagReturnImmediately, $wbemFlagForwardOnly))
        If IsObj($colItems) Then
            For $objItem In $colItems
                With $objItem
                    $sOut &= 'BiosCharacteristics|' & .BiosCharacteristics & @CRLF
                    $sOut &= 'BIOSVersion|' & .BIOSVersion & @CRLF
                    $sOut &= 'BuildNumber|' & .BuildNumber & @CRLF
                    $sOut &= 'Caption|' & .Caption & @CRLF
                    $sOut &= 'CodeSet|' & .CodeSet & @CRLF
                    $sOut &= 'CurrentLanguage|' & .CurrentLanguage & @CRLF
                    $sOut &= 'Description|' & .Description & @CRLF
                    $sOut &= 'EmbeddedControllerMajorVersion|' & .EmbeddedControllerMajorVersion & @CRLF
                    $sOut &= 'EmbeddedControllerMinorVersion|' & .EmbeddedControllerMinorVersion & @CRLF
                    $sOut &= 'IdentificationCode|' & .IdentificationCode & @CRLF
                    $sOut &= 'InstallableLanguages|' & .InstallableLanguages & @CRLF
                    $sOut &= 'InstallDate|' & .InstallDate & @CRLF
                    $sOut &= 'LanguageEdition|' & .LanguageEdition & @CRLF
                    $sOut &= 'ListOfLanguages|' & .ListOfLanguages & @CRLF
                    $sOut &= 'Manufacturer|' & .Manufacturer & @CRLF
                    $sOut &= 'Name|' & .Name & @CRLF
                    $sOut &= 'OtherTargetOS|' & .OtherTargetOS & @CRLF
                    $sOut &= 'PrimaryBIOS|' & .PrimaryBIOS & @CRLF
                    $sOut &= 'ReleaseDate|' & .ReleaseDate & @CRLF
                    $sOut &= 'SerialNumber|' & .SerialNumber & @CRLF
                    $sOut &= 'SMBIOSBIOSVersion|' & .SMBIOSBIOSVersion & @CRLF
                    $sOut &= 'SMBIOSMajorVersion|' & .SMBIOSMajorVersion & @CRLF
                    $sOut &= 'SMBIOSMinorVersion|' & .SMBIOSMinorVersion & @CRLF
                    $sOut &= 'SMBIOSPresent|' & .SMBIOSPresent & @CRLF
                    $sOut &= 'SoftwareElementID|' & .SoftwareElementID & @CRLF
                    $sOut &= 'SoftwareElementState|' & .SoftwareElementState & @CRLF
                    $sOut &= 'Status|' & .Status & @CRLF
                    $sOut &= 'SystemBiosMajorVersion|' & .SystemBiosMajorVersion & @CRLF
                    $sOut &= 'SystemBiosMinorVersion|' & .SystemBiosMinorVersion & @CRLF
                    $sOut &= 'TargetOperatingSystem|' & .TargetOperatingSystem & @CRLF
                    $sOut &= 'Version|' & .Version
                EndWith
            Next
        Else
            Return SetError(1)
        EndIf
        Return _StringSplit2D($sOut, @CRLF, '|')
    EndFunc   ;==>_GetBIOSInfo
    
    Func _StringSplit2D($sData, $sRowDel, $sColDel)
        Local $aRows = StringSplit($sData, $sRowDel, 3)
        Local $aCol = StringSplit($aRows[0], $sColDel, 3)
        Local $aOut[UBound($aRows)][UBound($aCol)], $aTmp
        For $iRow = 0 To UBound($aRows) - 1
            $aTmp = StringSplit($aRows[$iRow], $sColDel, 3)
            For $iCol = 0 To UBound($aCol) - 1
                $aOut[$iRow][$iCol] = ($aTmp[$iCol] = '' ? 'not available' : $aTmp[$iCol])
            Next
        Next
        Return $aOut
    EndFunc   ;==>_StringSplit2D
    Alles anzeigen
  • Listenfeld durchsuchen

    • Oscar
    • 18. Oktober 2017 um 13:29
    Zitat von DerSchatten

    Die Einträge die in meinem Listenfeld angezeigt werden kommen aus einer txt-Datei.

    Ist der Ansatz dann der gleiche oder durchsucht man da lieber gleich die Datei selbst und wertet diese dann aus?

    Wie viel Einträge enthält Dein Listview?

    Ab einer gewissen Anzahl von Einträgen (ab ca. 200 - 300 aufwärts / hängt vom Prozessor ab) wird das Suchen im Listview merklich langsam (die Verzögerung liegt dann nicht mehr im Millisekundenbereich).

    Bei vielen Einträgen also lieber die Datei in ein Array laden und dann dort suchen. Das ist um ein Vielfaches schneller. Das Listview kannst Du dann zum anzeigen der Suchtreffer benutzen.

  • _GDIPlus_ImageFixFileExtension

    • Oscar
    • 16. Oktober 2017 um 12:40
    Zitat von Bitnugger

    Sind doch nur ein paar Zeilen mehr... ich war mal so frei und habe sie eingebaut.

    Ok, ich habe das mal mit übernommen. Danke für das Beispiel! :thumbup:

    Allerdings funktioniert das prüfen auf die Dateiendung mit StringInStr nicht. Wenn man z.B. als Dateiendung nur ".jp" hat (das "g" vergessen), dann wird das mit StringinStr als korrekt angesehen.

    Da bin ich doch bei der Array-Schleife geblieben und die Funktionsnamen habe ich mal eindeutiger gemacht, um Verwechslungen auszuschliessen.

    Neue Version in Post#1.

  • _GDIPlus_ImageFixFileExtension

    • Oscar
    • 14. Oktober 2017 um 16:20
    Zitat von Bitnugger

    Du solltest hier aber noch differenzieren, dass File Type nicht gleich File Type Extension ist... denn *.JPG in *.JPEG oder *.TIF in *.TIFF umzubenennen, ist zumindest für mich nicht erwünscht.

    Ah, verdammt!

    Du hast recht, "_GDIPlus_ImageGetRawFormat" gibt nicht die FileExtension zurück.

    Die Abfrage, ob es sich bei der bisherigen um eine korrekte Dateiendung handelt, ist also "suboptimal". :whistling:

    Ich habe die UDF nun noch um eine bessere Abfrage erweitert. Neue Version in Post#1.

    Zitat von Bitnugger

    Hier habe ich lediglich eine Kopie der AutoIt.bmp erstellt und sie in AutoIt.gif umbenannt. Hiervon sollte also keine weitere *.bmp Kopie unter anderem Namen erstellt werden.

    Naja, ich denke, dass das übertrieben wäre, jetzt auch noch eine Abfrage auf Gleichheit der Dateien einzubauen.

    Und bezüglich dem ExifTool: eine 2.5KB-Funktion gegen ein 5MB-Programm austauschen? ;)

  • _GDIPlus_ImageFixFileExtension

    • Oscar
    • 14. Oktober 2017 um 11:50
    Zitat von alpines

    Darf ich fragen was du erwartet hast? Alle _WinAPI_* Funktionen (vermutlich bis auf ganz wenige Ausnahmen) benutzen die WinAPI und diese sind nur in Dlls verfügbar.

    So war das nicht gemeint. :)

    Mir ist schon klar, dass die _WinAPI_Funktionen hauptsächlich aus Dll-Calls bestehen.

    Ich wollte darauf hinaus, dass _WinAPI_PathRenameExtension wirklich nur einen Dll-Call ausführt plus eine Error-Zeile.

    Bei vielen _WinAPI-Funktionen werden ja noch diverse Vor- und/oder Nachbereitungen der Parameter/Rückgaben durchgeführt.

    Heißt: Viele der Funktionen bestehen eben nicht nur aus dem Dll-Call.

    Für die zwei Zeilen von _WinAPI_PathRenameExtension wollte ich halt nicht extra das ganze Include einfügen müssen.

  • _GDIPlus_ImageFixFileExtension

    • Oscar
    • 14. Oktober 2017 um 11:24

    Ich habe gerade gesehen, dass _WinAPI_PathYetAnotherMakeUniqueName nur ein Dll-Call der shell32.dll ist.

    Den habe ich jetzt direkt in die Funktion eingefügt, dann braucht man nicht das ganze Include nur für diesen Aufruf.

    Geänderte Version in Post#1.

  • _GDIPlus_ImageFixFileExtension

    • Oscar
    • 14. Oktober 2017 um 09:23
    Zitat von Musashi

    Wäre es ggf. sinnvoll einen zusätzlichen Parameter einzufügen, der von bereits bestehenden Dateien eine Sicherheitskopie anlegt ?

    Ah, stimmt!

    Ich hab's jetzt aber etwas anders gelöst. Wenn der neue Dateiname bereits existiert, so wird dem neuen Dateinamen ein Zaehler hinzugefügt.

    Das ist mit _WinAPI_PathYetAnotherMakeUniqueName bloß eine Zeile (und ein Include) mehr.

    Geänderte Version in Post#1.

  • _GDIPlus_ImageFixFileExtension

    • Oscar
    • 13. Oktober 2017 um 17:57

    Mit dieser Funktion kann man Bilddateien, die eine falsche Dateiendung aufweisen, automatisch umbenennen lassen.

    Die Funktion liest das korrekte Bildformat aus und ändert die Dateiendung entsprechend.

    Die UDF:

    AutoIt
    #Region ;************ Includes ************
    #include-once
    #include <GDIPlus.au3>
    #EndRegion ;************ Includes ************
    
    Global $__g_iIFFE_DEBUG = True ; True = Debug-Ausgaben eingeschaltet
    
    If $__g_hGDIPDll = 0 Then
        _GDIPlus_Startup()
        OnAutoItExitRegister('__IFFE_Exit')
    EndIf
    Global Const $__g_aGDIPDecoders = _GDIPlus_Decoders()
    Global Const $__g_sIFFE_Version = '1.0.0.0'
    Global Const $__g_sIFFE_Date = '2017-10-16 12:00:00'
    
    Func __IFFE_Exit()
        _GDIPlus_Shutdown()
    EndFunc   ;==>__IFFE_Exit
    
    ;===============================================================================
    ; Function Name:   _GDIPlus_ImageFixFileExtension($sFilename)
    ; Description:     Diese Funktion korrigiert die Dateiendung einer Bilddatei,
    ;                  wenn die Bilddatei eine falsche Endung aufweist.
    ;                  Existiert der neue Dateiname bereits, wird der neue Dateiname
    ;                  um einen Zaehler " (n)" erweitert.
    ;                  Wenn die bereits existierende Datei allerdings inhaltsgleich
    ;                  (gleiche CRC32-Checksumme) ist, mit der neuen Datei,
    ;                  dann wird die Datei mit der falschen Endung geloescht.
    ; Parameter(s):    $sFilename = Dateiname und -pfad der Bilddatei
    ; Requirement(s):  #include <GDIPlus.au3>
    ; Return Value(s): bei Erfolg = der neue Dateiname
    ;                     @extended = 0 - die Datei wurde umbenannt
    ;                     @extended = 1 - die Datei wurde nicht umbenannt
    ;                     @extended = 2 - die Datei war identisch mit einer
    ;                                     bereits existierenden Datei
    ;                  im Fehlerfall wird 0 zurueckgegeben und
    ;                     @error = 1 wenn FileMove fehlgeschlagen ist
    ;                     @error = 2 wenn PathYetAnotherMakeUniqueName fehlgeschlagen ist
    ;                     @error = Rueckgabe von _GDIPlus_ImageGetRawFormat, wenn
    ;                              Datei nicht vorhanden oder keine Bilddatei
    ; Author(s):       Oscar & Bitnugger (www.autoit.de)
    ;===============================================================================
    Func _GDIPlus_ImageFixFileExtension($sFilename)
        Local $hImage, $aRet, $iFormat = -1, $iError, $aExt, $sNewFile, $aCrc32[2]
        $hImage = _GDIPlus_ImageLoadFromFile($sFilename)
        $aRet = _GDIPlus_ImageGetRawFormat($hImage)
        $iError = @error
        _GDIPlus_ImageDispose($hImage)
        If $iError Then Return SetError($iError, 0, 0)
        For $i = 1 To $__g_aGDIPDecoders[0][0]
            If $aRet[1] = $__g_aGDIPDecoders[$i][5] Then
                $iFormat = $i
                ExitLoop
            EndIf
        Next
        If $iFormat = -1 Then Return SetError(30, 0, 0)
        __IFFE_DebugPrint('> _GDIPlus_ImageFixFileExtension(): FileName   = ' & $sFilename & @CRLF)
        __IFFE_DebugPrint('> _GDIPlus_ImageFixFileExtension(): Format     = ' & $__g_aGDIPDecoders[$iFormat][5] & @CRLF)
        __IFFE_DebugPrint('> _GDIPlus_ImageFixFileExtension(): Extensions = ' & $__g_aGDIPDecoders[$iFormat][6] & @CRLF)
        $aExt = StringSplit(StringReplace(StringLower($__g_aGDIPDecoders[$iFormat][6]), '*', ''), ';', 2)
        For $sExt In $aExt
            If $sExt = StringRegExpReplace($sFilename, '(?:.+)(\..+)', '$1') Then Return SetError(0, 1, $sFilename)
        Next
        $sNewFile = StringRegExpReplace($sFilename, '(.+)\..+', '$1') & $aExt[0]
        If FileExists($sNewFile) Then
            $aCrc32[0] = __IFFE_ComputeCrc32($sFilename)
            If @error Then Return SetError(40, 0, 0)
            $aCrc32[1] = __IFFE_ComputeCrc32($sNewFile)
            If @error Then Return SetError(40, 0, 0)
            If $aCrc32[0] = $aCrc32[1] Then
                __IFFE_DebugPrint(StringFormat('! _GDIPlus_ImageFixFileExtension(): Diese Dateien sind identisch:\r' & _
                        '! --> Crc32 = 0x%s  %s\t - Falsche Dateierweiterung  (wird gelöscht)\r' & _
                        '+ --> Crc32 = 0x%s  %s\t - Richtige Dateierweiterung (wird behalten)\r', _
                        $aCrc32[0], $sFilename, $aCrc32[1], $sNewFile))
                FileDelete($sFilename)
                Return SetError(0, 2, $sNewFile)
            EndIf
        EndIf
        $aRet = DllCall('shell32.dll', 'int', 'PathYetAnotherMakeUniqueName', 'wstr', '', 'wstr', $sNewFile, 'ptr', 0, 'ptr', 0)
        If @error Or Not $aRet[0] Then Return SetError(2, 0, 0)
        $sNewFile = $aRet[1]
        Return FileMove($sFilename, $sNewFile, 1) ? SetError(0, 0, $sNewFile) : SetError(1, 0, 0)
    EndFunc   ;==>_GDIPlus_ImageFixFileExtension
    
    Func __IFFE_DebugPrint($sString)
        If $__g_iIFFE_DEBUG Then ConsoleWrite($sString)
    EndFunc   ;==>__IFFE_DebugPrint
    
    Func __IFFE_ComputeCrc32($sFilePath)
        Local $hFile, $bData, $iLen, $tData, $aRet
        $hFile = FileOpen($sFilePath, $FO_BINARY)
        If $hFile = -1 Then Return SetError(1, 0, 0)
        $bData = FileRead($hFile)
        FileClose($hFile)
        $iLen = BinaryLen($bData)
        If $iLen = 0 Then Return SetError(2, 0, 0)
        $tData = DllStructCreate('byte[' & $iLen & ']')
        DllStructSetData($tData, 1, $bData)
        $aRet = DllCall('ntdll.dll', 'dword', 'RtlComputeCrc32', 'dword', 0, 'struct*', DllStructGetPtr($tData), 'int', $iLen)
        If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)
        Return Hex($aRet[0], 8)
    EndFunc   ;==>__IFFE_ComputeCrc32
    Alles anzeigen

    Beispiel:

    AutoIt
    #include '_GDIPlus_ImageFixFileExtension.au3'
    
    $vRet = _GDIPlus_ImageFixFileExtension('d:\test.jpg')
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $vRet = ' & $vRet & @CRLF & '>Error code: ' & @error & @CRLF & '>Extended code: ' & @extended & @CRLF) ;### Debug Console

    Dateien

    _GDIPlus_ImageFixFileExtension.au3 5,04 kB – 404 Downloads
  • Ordner Kopieren und in andere Pfad einfügen und die Endungen von Dateien in der neuer Ordner umbennen

    • Oscar
    • 13. Oktober 2017 um 15:06
    Zitat von bobmarley

    Ich kann den Pfad irgendwie nicht auswählen, kann ich irgendwie nur die Endungen einem Art von Dateien umbennen und den Rest bleibt.

    Ehrlich gesagt, verstehe ich nicht, was Du erreichen willst. Deine Sätze sind schon unverständlich.

    Aber auch Dein Script lässt den Sinn nicht wirklich erahnen. Du kannst Bilder jedenfalls nicht einfach durch das ändern der Dateiendung in ein anderes Bildformat umwandeln.

    Eine BMP-Datei bleibt eine BMP-Datei, auch wenn sie die Dateiendung ".jpg" trägt.

    Dein StringRegExReplace-Pattern ist auch fehlerhaft. Ersetze das mal mit: StringRegExpReplace($Files[$i], "(.+)\..+", "$1")

    Und dann versuche mal genau zu beschreiben, was Du erreichen willst.

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™