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. Bitnugger

Beiträge von Bitnugger

  • ​Sammlung: Nim Snippets / Procedures

    • Bitnugger
    • 10. Juni 2020 um 16:25
    Zitat von BugFix

    Ich habe mal noch gefiltert:

    - Parent muss "0" sein

    - Fenster muss Titel haben

    Hier eine Version, bei der ein Filter für den Titel/ClassName angeben werden kann... und bei jedem Aufruf wird sEnumWnd zurückgesetzt, damit sich die gefundenen Fenster nicht aufsummieren:

    Code
    import os, strutils, strformat
    include winim/[inc\winuser]
    
    proc printf(formatstr: cstring) {.header: "<stdio.h>", varargs.}
    
    type
      ConditionPair[T] = object
        ifTrue, ifFalse: T
    
    proc `!`*[T](a, b: T): ConditionPair[T] {.inline.} = ConditionPair[T](ifTrue: a, ifFalse: b)
    
    template `?`*[T](cond: bool; p: ConditionPair[T]): T =
      (if cond: p.ifTrue else: p.ifFalse)
    
    type
      WndID = object
        pid, tid: int
      EnumWnd = object
        hwnd: HWND
        class: WideCStringObj
        title: WideCStringObj
        pid, tid: int
    
    var 
      sEnumWnd = newSeq[EnumWnd]()
      lp: LPARAM
    
    var
      classfilter = newWideCString("", 4096)
      titlefilter = newWideCString("", 4096)
      spacer: string = repeat("-", 128)
      fo: string = "HWND      : %-18sPID : %6s TID : %6s %54sWindow : %4i|%4i\nTITLE     : %s\nCLASSNAME : %s\n%s\n"
    
    # - Parent muss "0" sein
    # - Fenster muss Titel haben
    proc my_WndEnumProc(hwnd: HWND, lp: LPARAM): WINBOOL {.stdcall.} =
      if GetParent(hwnd) == 0:
        var buflen = GetWindowTextLengthW(hwnd) + 1
        if buflen == 0: return TRUE
    
        var buf = newWideCString("", buflen)
        discard GetWindowTextW(hwnd, cast[LPWSTR](addr buf[0]), buflen)
        if titlefilter.len > 0:
          if fmt"{buf}" != fmt"{titlefilter}": return TRUE
    
        var className = newWideCString("", 4096)
        discard GetClassNameW(hwnd, cast[LPWSTR](className), 4096)
        if classfilter.len > 0:
          if fmt"{className}" != fmt"{classfilter}": return TRUE
    
        var
          pPID: LPDWORD
          pTID = GetWindowThreadProcessId(hwnd, cast[LPDWORD](addr pPID))
          oWndID = WndID(pid: cast[int](pPID), tid: cast[int](pTID))
    
        sEnumWnd.add(EnumWnd(hwnd: hwnd, 
                            class: className, 
                            title: buf,
                            pid: oWndID.pid,
                            tid: oWndID.tid))
      return TRUE
    
    proc GetEnumWindows(cfilter, tfilter: string): int =
      titlefilter = newWideCString(tfilter, tfilter.len + 1)
      classfilter = newWideCString(cfilter, cfilter.len + 1)
      sEnumWnd = newSeq[EnumWnd]()
      EnumWindows(my_WndEnumProc, lp)
      result = sEnumWnd.len
    
    proc printEnumWnds(): void =
      printf("%s\nclassfilter = %s\ntitlefilter = %s\n%s\n",
                 spacer, $classfilter, $titlefilter, spacer)
      var n = sEnumWnd.len
      for i in 0..n - 1:
        printf(fo, toHex(sEnumWnd[i].hwnd), $sEnumWnd[i].pid, $sEnumWnd[i].tid, "",
                   i, sEnumWnd.len, $sEnumWnd[i].title, $sEnumWnd[i].class, spacer)
      echo "Es wurde" & (n <= 0 ? " kein" ! (n == 1 ? " ein" ! "n " & $n)) &
           " Window" & (n <= 1 ? "" ! "s") & " gefunden...\n" &
           spacer & "\n"
    
    if GetEnumWindows("SciTEWindow", "") > 0: printEnumWnds()
    if GetEnumWindows("SciTEWindow", r"M:\AutoIt\WakeOnLan.au3 - SciTE") > 0: printEnumWnds()
    if GetEnumWindows("", "(Frozen) AutoIt v3 Window Info") > 0: printEnumWnds()
    Alles anzeigen
    Ausgabe
    Code
    --------------------------------------------------------------------------------------------------------------------------------
    classfilter = SciTEWindow
    titlefilter =
    --------------------------------------------------------------------------------------------------------------------------------
    HWND      : 0000000000370F18  PID :  10484 TID :   5544                                                       Window :    0|   2
    TITLE     : F:\AutoIt\AutoIt3_Tools\OrganizeIncludes\OI_1.0.0.50.au3 - SciTE [9 von 11]
    CLASSNAME : SciTEWindow
    --------------------------------------------------------------------------------------------------------------------------------
    HWND      : 00000000030E11B2  PID :   2324 TID :   1976                                                       Window :    1|   2
    TITLE     : M:\AutoIt\WakeOnLan.au3 - SciTE
    CLASSNAME : SciTEWindow
    --------------------------------------------------------------------------------------------------------------------------------
    Es wurden 2 Windows gefunden...
    --------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------------------------------------------------------------------------------------------
    classfilter = SciTEWindow
    titlefilter = M:\AutoIt\WakeOnLan.au3 - SciTE
    --------------------------------------------------------------------------------------------------------------------------------
    HWND      : 00000000030E11B2  PID :   2324 TID :   1976                                                       Window :    0|   1
    TITLE     : M:\AutoIt\WakeOnLan.au3 - SciTE
    CLASSNAME : SciTEWindow
    --------------------------------------------------------------------------------------------------------------------------------
    Es wurde ein Window gefunden...
    --------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------------------------------------------------------------------------------------------
    classfilter =
    titlefilter = (Frozen) AutoIt v3 Window Info
    --------------------------------------------------------------------------------------------------------------------------------
    HWND      : 0000000003691100  PID :   4684 TID :  10248                                                       Window :    0|   1
    TITLE     : (Frozen) AutoIt v3 Window Info
    CLASSNAME : Au3Info
    --------------------------------------------------------------------------------------------------------------------------------
    Es wurde ein Window gefunden...
    --------------------------------------------------------------------------------------------------------------------------------
    Alles anzeigen
    Zitat von Bitnugger

    --------------------------------------------------------------------------------------------------------------------------------
    HWND : 0000000000020CD6 PID : 668 TID : 14828 Window : 633| 876
    TITLE : TmainFrm
    CLASSNAME : HFS ~ HTTP File Server 2.3m Build 300
    --------------------------------------------------------------------------------------------------------------------------------

    Hier ist mir übrigens aufgefallen, dass ich TITLE und CLASSNAME bei der Ausgabe vertauscht hatte... habe es korrigiert.

  • WinActivate funktioniert nicht und suche Alternative

    • Bitnugger
    • 8. Juni 2020 um 00:53
    Zitat von Faultier_1982

    Normalerweise verwende ich dafür dann immer WinActivate($Name_des_Chrome_Tabs) um das gewünschte Fenster zu aktivieren...

    Chrome, wie auch Firefox, setzen den Namen des aktiven Tabs als Title, oder hat Chrome bei dir etwa für jeden geöffneten Tab ein eigenes Fenster?

    WinActivate benötigt das Handle oder den Title des Fensters bzw. aktiven Tabs... wenn das Fenster nicht gefunden wird, ist wohl ein anderer Tab aktiv.

    In seltenen Fällen kann es aber auch sein, dass ein Fenster nicht gefunden wird, wenn der Titel Sonderzeichen enthält. Dann ist REGEXPTITLE bzw. REGEXPCLASS dein Freund.

    AutoIt
    Local $hWnd = WinGetHandle("[REGEXPTITLE:(?i)(.*SciTE.*|.*Internet Explorer.*)]")
    ConsoleWrite("$hWnd --> " & $hWnd & @LF)
    ; ===>>> $hWnd --> 0x0123161E
    
    ; oder dieser Kandidat... sehr tückisch, weil man die Leerzeichen vorne und hinten nicht sieht:
    Local $hWnd = WinGetHandle("[REGEXPTITLE:(?i)(.*Total Com.*7\.3.*)]")
    ConsoleWrite("$hWnd --> " & $hWnd & @LF)
    ConsoleWrite('"' & WinGetTitle($hWnd) & '"' & @CRLF)
    ; ===>>> " Total Commander Ultima Prime 7.3  :: CPU: 015% (3,2 GHz) :: RAM: 079% (6,0 GB) :: C: 52% :: 08.06.2020 - 00:48:14 :: 2 Days, 05:28:32 :: "
    ;         ^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .^
  • Text formatieren in Farbe und blinkend

    • Bitnugger
    • 8. Juni 2020 um 00:14
    Zitat von HansJ54

    ohne dieses Forum hätte ich schon lange das Handtuch geworfen.

    Hört sich so an, als hättest du nur eines... immerhin eines mehr als ich... 8o

    Ne, Quatsch beiseite... ich habe hier auch sehr viel gelernt... aber auch im blauen Forum... und ohne Hilfe ist es immer viel schwerer, etwas Gescheites auf die Beine zu stellen, das wissen wir alle.

  • Text formatieren in Farbe und blinkend

    • Bitnugger
    • 7. Juni 2020 um 23:50
    Zitat von BugFix

    Oder du nimmst ein RichEdit-Ctrl. Könnte für dein Vorhaben passen.

    Ahhh... ne, da würde ich viel eher auf GDIPlus setzen... damit hast du quasi unendlich viele Möglichkeiten... aber ok, da muss man sich erst einmal feste durchbeißen, bis die ersten Erfolge kommen.

  • Daten sichern und redundant speichern --- Vorschläge?

    • Bitnugger
    • 7. Juni 2020 um 23:46
    Zitat von alpines

    Sollte ich lieber einen HW-Raid-Controller nehmen?

    Für deinen Anwendungsfall würde ich eher eine Software-RAID-Lösung empfehlen. Die ist zwar etwas langsamer, aber hat den großen Vorteil, dass du nicht an eine spezielle Hardware gebunden bist.

    RAID 1... na ja, besser als nichts... ist das teuerste RAID.. damit verlierst du über 50% an Speicher... empfehlen würde ich RAID 5... hier eine gute Seite: https://www.storage-insider.de/was-ist-raid-a…-mehr-a-517806/

    Ansonsten mache meine Backups mit RoboCopy. Ich lasse ihn 1x täglich laufen und kann deswegen gut schlafen und brauche keine Bange um meine Daten haben.

    Ich habe allerdings auch noch einen Root-Server (Debian, selbst eingerichtet) gemietet, 4 TB, auf dem ich ebenfalls die essentiell wichtigen Sachen verschlüsselt speichere.

    Wichtig ist aber vor allem, das in Sachen Backup eine gut ausgeklügelte Automatik ins Spiel kommt, da wir Menschen ja gerne dazu neigen, Dinge zu vergessen, auch wenn sie extrem wichtig für uns sind. Deshalb eben nicht nur
    RoboCopy und Image des System-Laufwerks erstellen... das ist für mich nämlich die fieseste Arbeit, obwohl ich es gelernt habe und auch gut kann, aber ich hasste es, Windows neu einzurichten, wenn es um mein System geht.

    Falls du trotz aller Vorsicht mal einen Platten-Crash haben solltest, frag doch einfach bei der NSA nach, ob sie dir ein Backup verkaufen... :rofl:

  • Diskussionen etc. zu Snippets

    • Bitnugger
    • 7. Juni 2020 um 23:16

    Mit AutoIt: 212

    Mit Nim: 897

    Zitat von BugFix

    Vielleicht verwendet die AutoIt Funktion stattdessen EnumDesktopWindows.

    _WinAPI_GetDesktopWindow() und dann __WinAPI_EnumWindowsChild... ===>>> _WinAPI_GetWindow / [_WinAPI_IsWindowVisible] / _WinAPI_GetWindow ...ist klar, sind ja alle Childs des Desktops...

    Mit Nim kannst du die aber sicher auch filtern...

  • Diskussionen etc. zu Snippets

    • Bitnugger
    • 7. Juni 2020 um 18:36
    Zitat von BugFix

    Das ist Absicht. In vielen Fällen meckert der Compiler, wenn du den Rückgabewert einer Funktion nicht auffängst. Deshalb habe ich mir das so angenommen.

    Ich habe es hin bekommen... er meckert nicht mehr... und die Ausgabe formatiert... passt allerdings nicht alles in eine Zeile, deshalb habe ich es auf drei umgebrochen.

    Diese Funktion holt aber wohl alle Windows, auch die Childs bzw. Controls... daran erkennbar, weil etliche Windows dieselbe PID/TID haben.

    Code
    import os, strutils #, strformat
    include winim/[inc\winuser]
    
    proc printf(formatstr: cstring) {.header: "<stdio.h>", varargs.}
    
    type
      WndID = object
        pid, tid: int
      EnumWnd = object
        hwnd: HWND
        class, title: WideCStringObj
        pid, tid: int
    
        # title: WideCStringObj
    var 
      sEnumWnd = newSeq[EnumWnd]()
      lp: LPARAM
    
    proc my_WndEnumProc(hwnd: HWND, lp: LPARAM): WINBOOL {.stdcall.} =
      var
        buflen = GetWindowTextLengthW(hwnd) + 1
        buf = newWideCString("", buflen)
        className = newWideCString("", 4096)
        pPID: LPDWORD
        pTID = GetWindowThreadProcessId(hwnd, cast[LPDWORD](addr pPID))
        oWndID = WndID(pid: cast[int](pPID), tid: cast[int](pTID))    
      discard GetWindowTextW(hwnd, cast[LPWSTR](addr buf[]), buflen)
      discard GetClassNameW(hwnd, cast[LPWSTR](className), 4096)
      sEnumWnd.add(EnumWnd(hwnd: hwnd, 
                           class: className, 
                           title: buf,
                           pid: oWndID.pid,
                           tid: oWndID.tid))
      return TRUE
    
    
    EnumWindows(my_WndEnumProc, lp)
    
    
    var
      spacer: string = repeat("-", 128) & "\n"
      fo: string = "HWND      : %-18sPID : %6s TID : %6s %54sWindow : %4i|%4i\nTITLE     : %s\nCLASSNAME : %s\n%s"
    echo spacer
    for i in 0..sEnumWnd.len - 1:
      printf(fo, toHex(sEnumWnd[i].hwnd), $sEnumWnd[i].pid, $sEnumWnd[i].tid, "",
                 i, sEnumWnd.len, $sEnumWnd[i].title, $sEnumWnd[i].class, spacer)
    echo "Es wurden " & $sEnumWnd.len & " Windows im System gefunden...\n" & spacer
    
    
    #[
    --------------------------------------------------------------------------------------------------------------------------------
    HWND      : 0000000000030CF2  PID :    668 TID :  14828                                                       Window :  632| 876
    TITLE     : 
    CLASSNAME : tooltips_class32
    --------------------------------------------------------------------------------------------------------------------------------
    HWND      : 0000000000020CD6  PID :    668 TID :  14828                                                       Window :  633| 876
    TITLE     : HFS ~ HTTP File Server 2.3m                                                                                Build 300
    CLASSNAME : TmainFrm                   
    --------------------------------------------------------------------------------------------------------------------------------
    Es wurden 867 Windows im System gefunden.
    --------------------------------------------------------------------------------------------------------------------------------
    ]#
    Alles anzeigen
  • Diskussionen etc. zu Snippets

    • Bitnugger
    • 7. Juni 2020 um 14:00
    Zitat von BugFix

    txtlen = GetWindowTextW(hwnd, cast[LPWSTR](addr buf[0]), buflen)

    classlen = GetClassNameW(hwnd, cast[LPWSTR](className), 4096)

    EnumWindows... die beiden Variablen werden sonst an keiner Stelle verwendet... da muss du noch mal gucken...

  • FindWindowW ohne Resultat bei Übergabe Klasse und/oder Titel

    • Bitnugger
    • 6. Juni 2020 um 22:14
    Zitat von BugFix

    echo "hWnd SciTE [class & title] = ", toHex(FindWindow(title = r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]"))
    echo "hWnd SciTE [title] = ", toHex(FindWindow("SciTEWindow", r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]"))

    Hier hast du dich vertan... [class & title] gehört in die letzte Zeile, [title] in die vorletzte.

    Code
    import strutils 
    include winim/[inc\winuser]
    
    proc FindWindow(class = "", title = ""): HWND =
      let 
        className = newWideCString(class, class.len)
        wndName = newWideCString(title, title.len)
      if class == "" and title == "": result = FindWindowW(nil, nil)
      elif class != "" and title == "": result = FindWindowW(cast[LPWSTR](className), nil)
      elif class == "" and title != "": result = FindWindowW(nil, cast[LPWSTR](wndName))
      else: result = FindWindowW(cast[LPWSTR](className), cast[LPWSTR](wndName))
    
    var find: string = r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]"
    echo "hWnd SciTE [ACTIVE]        = ", toHex(FindWindow())
    echo "hWnd SciTE [class]         = ", toHex(FindWindow("SciTEWindow"))
    echo "hWnd SciTE [title]         = ", toHex(FindWindow("", find))
    echo "hWnd SciTE [class & title] = ", toHex(FindWindow("SciTEWindow", find))
    #[ 
    hWnd SciTE [ACTIVE]        = 0000000000030844
    hWnd SciTE [class]         = 00000000001A0F3C
    hWnd SciTE [title]         = 00000000001A0F3C
    hWnd SciTE [class & title] = 00000000001A0F3C
    ]#
    Alles anzeigen
  • Diskussionen etc. zu Snippets

    • Bitnugger
    • 6. Juni 2020 um 19:18
    Zitat von BugFix

    let WndID = GetIDByWindow(hWnd)

    Das passiert, wenn man das Bsp. nicht testet: 8o

    Code
    {
        ...
        "severity": 8,
        "message": "redefinition of 'WndID'; previous declaration here: c:\\Users\\ghost\\NIM\\@BugFix\\GetIDByWindow.nim(6, 3)\r\n\r\n",
        ...
    }
    Code
    # Ermitteln von Process-ID und Thread-ID eines Fensters
    
    include winim/[inc\winuser]
    
    type
      WndID = object
        pid, tid: int
    
    proc GetIDByWindow(hWnd: HWND): WndID =
      # determines the process and thread ID by a window handle
      # returns the object type "WndID" with .pid & .tid
      # requires: include winim/[inc\winuser]
      var 
        pPID: LPDWORD
        pTID = GetWindowThreadProcessId(hWnd, cast[LPDWORD](addr pPID))
      result = WndID(pid: cast[int](pPID), tid: cast[int](pTID))
    
    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # Example
    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    var
      wndName = newWideCString(r"M:\AutoIt\Cursor.au3 - SciTE [22 von 22]", 4096)
      hWnd = FindWindowW(nil, cast[LPCWSTR](wndName))
    
    let id = GetIDByWindow(hWnd)
    echo "Process-ID      = ", id.pid
    echo "Thread-ID       = ", id.tid
    echo "Process-ID only = ", GetIDByWindow(hWnd).pid
    echo "Thread-ID only  = ", GetIDByWindow(hWnd).tid
    #[
    Process-ID      = 16140
    Thread-ID       = 11472
    Process-ID only = 16140
    Thread-ID only  = 11472
    ]#
    Alles anzeigen

    Tags: <Process ID>, <PID>, <Thread ID>

  • FindWindowW ohne Resultat bei Übergabe Klasse und/oder Titel

    • Bitnugger
    • 6. Juni 2020 um 18:44
    Zitat von BugFix

    className = cast[LPCWSTR]("SciTEWindow")
    wndName = cast[LPCWSTR](r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]")

    So funktioniert es bei mir:

    Code
    import strutils 
    include winim/[inc\winuser]
    
    var
      className = newWideCString("SciTEWindow", 4096)
      # wndName = newWideCString(r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]", 4096)
      wndName = newWideCString(r"M:\AutoIt\Cursor.au3 - SciTE [22 von 22]", 4096)
      hScite0 = FindWindowW(nil, nil)
      hScite1 = FindWindowW(cast[LPCWSTR](className), nil)
      hScite2 = FindWindowW(cast[LPCWSTR](className), cast[LPCWSTR](wndName))
    echo "hWnd SciTE [ACTIVE]        = ", toHex(hScite0), ", " & $type(hScite0) # OK
    echo "hWnd SciTE [class]         = ", toHex(hScite1), ", " & $type(hScite1) # OK
    echo "hWnd SciTE [class & title] = ", toHex(hScite2), ", " & $type(hScite2) # OK
    
    var
      buflenW: int32 = 4096 #GetWindowTextLengthW(hScite2) + 1
      bufW0 = newWideCString("", buflenW)
      bufW1 = newWideCString("", buflenW)
      bufW2 = newWideCString("", buflenW)
      txtlenW0 = GetWindowTextW(hScite0, cast[LPWSTR](addr bufW0[0]), buflenW)
      txtlenW1 = GetWindowTextW(hScite1, cast[LPWSTR](addr bufW1[0]), buflenW)
      txtlenW2 = GetWindowTextW(hScite2, cast[LPWSTR](addr bufW2[0]), buflenW)
    
    echo "txtlenW0 = ", txtlenW0
    echo "txtlenW1 = ", txtlenW1
    echo "txtlenW2 = ", txtlenW2
    echo "buflenW  = ", buflenW
    echo "bufW0    = ", bufW0
    echo "bufW1    = ", bufW1
    echo "bufW2    = ", bufW2
    
    #[ OUTPUT
    hWnd SciTE [ACTIVE]        = 0000000000030844, HWND
    hWnd SciTE [class]         = 00000000001A0F3C, HWND
    hWnd SciTE [class & title] = 00000000001A0F3C, HWND
    txtlenW0 = 11
    txtlenW1 = 40
    txtlenW2 = 40
    buflenW  = 4096
    bufW0    = MSCTFIME UI
    bufW1    = M:\AutoIt\Cursor.au3 - SciTE [22 von 22]
    bufW2    = M:\AutoIt\Cursor.au3 - SciTE [22 von 22]
    ]#
    Alles anzeigen
  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 4. Juni 2020 um 23:06

    Bei _OL_ItemFind bekomme ich die ersten 1-3 mal den @error 1001... davor wird _OL_ItemSend und _OL_ItemSendReceive ausgeführt, dann wird 1 Sekunde gewartet. 1 Sek. scheint wohl zu wenig zu sein, aber warum passiert das?

    Code
    > _OL_ItemFind($oOutlook = Object, "*\Postausgang       ", 43, "[Subject]='Telefonnummern Kunden Tour 1 04.06.2020 23:00:42'", "", "", "", "", 2) @error = 1001, @extended =    0 $iOutlook_PID = 17060
    - _OL_ItemFind($oOutlook = Object, "*\Gesendete Elemente", 43, "[Subject]='Telefonnummern Kunden Tour 1 04.06.2020 23:00:42'", "", "", "", "", 2) @error =    0, @extended =    0 $iOutlook_PID = 17060
    > _OL_ItemFind($oOutlook = Object, "*\Postausgang       ", 43, "[Subject]='Telefonnummern Kunden Tour 1 04.06.2020 23:00:42'", "", "", "", "", 2) @error = 1001, @extended =    0 $iOutlook_PID = 17060
    - _OL_ItemFind($oOutlook = Object, "*\Gesendete Elemente", 43, "[Subject]='Telefonnummern Kunden Tour 1 04.06.2020 23:00:42'", "", "", "", "", 2) @error =    0, @extended =    0 $iOutlook_PID = 17060
    > _OL_ItemFind($oOutlook = Object, "*\Postausgang       ", 43, "[Subject]='Telefonnummern Kunden Tour 1 04.06.2020 23:00:42'", "", "", "", "", 2) @error =    0, @extended =    0 $iOutlook_PID = 17060
    - _OL_ItemFind($oOutlook = Object, "*\Gesendete Elemente", 43, "[Subject]='Telefonnummern Kunden Tour 1 04.06.2020 23:00:42'", "", "", "", "", 2) @error =    0, @extended =    0 $iOutlook_PID = 17060
  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 4. Juni 2020 um 15:00
    Zitat von water

    Ich vermute mal, dass diese Outlook Spezialität hier zuschlägt:

    Hehe... ja, das wird es wohl sein! Direkt nach _OL_Open wird die Outlook.exe mit ProcessExists gefunden, ist dann aber schnell wieder verschwunden.

    Tzzz... nun ja, man muss ergo sicherstellen, das die Outlook.exe bereits gestartet wurde, bevor man mit _OL_* arbeitet.

  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 4. Juni 2020 um 11:55

    Ich habe noch ein wenig experimentiert, denn es war mir zu grobschlächtig, mehrmals den kompletten Inhalt des Postausgangs/Posteingangs als Array zu holen, um mit _ArraySearch zu überprüfen, ob die gesuchte Mail darin enthalten ist.

    So kann man den kompletten Inhalt holen:

    $aItems = _OL_ItemFind($oOutlook, "*\Posteingang", $olMail, "", "", "", "", "", 2) ; EN = *\Inbox

    $aItems = _OL_ItemFind($oOutlook, "*\Postausgang", $olMail, "", "", "", "", "", 2) ; EN = *\Outbox

    So bekommt man jedoch nur die gesuchte Mail geliefert, insofern sie vorhanden ist:

    $aItems = _OL_ItemFind($oOutlook, "*\Posteingang", $olMail, "[Subject]='" & $sSubject & "'", "", "", "", "", 2) ; EN = *\Inbox

    $aItems = _OL_ItemFind($oOutlook, "*\Postausgang", $olMail, "[Subject]='" & $sSubject & "'", "", "", "", 2) ; EN = *\Outbox

    Jetzt bin ich allerdings sehr erstaunt, dass die zweite Variante nur dann funktioniert, wenn die Outlook.exe gestartet wurde, bevor das Objekt $oOutlook mit _OL_Open() erstellt wird!

    Hier liefert mir _OL_ItemFind folgende Fehlermeldung: @error = 3, @extended = 4

    ; @error |3 - Error accessing the specified folder. See @extended for errorcode returned by _OL_FolderAccess

    ; @extended |4 - Specified folder could not be found. @extended is set to the index of the subfolder in error (1 = root folder)

    Die Mail wird aber versandt... ich kann nur nicht via OutlookEX UDF darauf zugreifen.

    water , hast du eine Idee bzw. weißt du, warum das so ist?

    Das Script dazu (_OL_Mail_senden.au3) findet ihr im Anhang. Hier muss die Variable $sMeineMailadresse gesetzt werden.

    Wenn ich allerdings mit _OL_Check_InOutbox.au3 eine bereits vorhandene Nachricht abfrage, funktioniert die zweite Variante auch ohne dass Outlook gestartet wird. Hier muss die Variable $sSubject vor dem Start korrigiert werden.

    Dateien

    _OL_Mail_senden.au3 7,91 kB – 190 Downloads _OL_Check_InOutbox.au3 2,21 kB – 232 Downloads
  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 4. Juni 2020 um 02:23
    Zitat von water

    Da Sleep in Millisekunden angegeben wird, wird er die 10 Sekunden sicher überleben

    Hehe... oh ja, ich werde alt... ne, ich bin alt, und senil! :D

    Habe nun auch herausgefunden, wie ich den Postausgang überprüfe... schön zu wissen, aber nicht relevant für mich, da ich mit Thunderbird hantiere. 8o

    AutoIt
    ;-- TIME_STAMP   2020-06-04 02:30:55   v 0.1
    
    Opt('MustDeclareVars', 1)
    
    #include <Array.au3>
    #include <OutlookEX.au3>
    
    Global Enum $eSubject, $eBody, $eCreationTime, $eLastModificationTime, $eSize
    
    Global $oOutlook = _OL_Open()
    If @error Then Exit MsgBox(16, "OutlookEX UDF", "Error creating a connection to Outlook. @error = " & @error & ", @extended = " & @extended)
    
    _Check_Outbox()
    
    Func _Check_Outbox()
        Local $sSubject = 'Test32'
        Local $aItems = _OL_ItemFind($oOutlook, "*\Postausgang", $olMail, "", "", "", "", "", 2) ; EN = *\Outbox
        If @error Then
            MsgBox(16, "OutlookEX UDF", "Error _OL_ItemFind failed. @error = " & @error & ", @extended = " & @extended)
        Else
            Local $iIndex = _ArraySearch($aItems, $sSubject, 1, 0, 0, 0, 1, $eSubject)
            Local $sMsg = 'Die Mail mit dem Subject "'& $sSubject &'" wurde ' & (@error ? '' : 'nicht') & ' versandt!' & @CRLF & '($iIndex = ' & $iIndex & ')'
    
            MsgBox(64,"OutlookEX UDF", "Im Postausgang sind " & UBound($aItems) -1 & " eMails." & @CRLF & @CRLF & $sMsg & @CRLF & @CRLF & _ArrayToString($aItems, '|'))
            _ArrayDisplay($aItems, '$aItems')
        EndIf
    EndFunc
    
    _OL_Close($oOutlook)
    Alles anzeigen

    _OL_Check_Outbox.png

  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 3. Juni 2020 um 20:28
    Zitat von Windi

    Hatte Probleme mit der GPX Datei.

    z.B. beim Ort: Frankfurt / Main

    das mag gpx überhaupt nicht das hatte ich ihm abgewöhnt.

    Müller GmbH CO. KG mag er auch nicht.

    Muss jetzt mal testen wie sich das mit - & usw verhält.

    Lies mal hier: https://www.gerhard-fobe.de/besondere-zeic…d-mailinhalten/

  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 3. Juni 2020 um 20:06
    Zitat von water

    Ah ja: _Main musst Du noch irgendwo aufrufen :)

    Ok, da muss ich dir wohl zustimmen... habe es korrigiert. 8o

    Zitat von water

    Eine weitere Möglichkeit statt Sleep wäre es, den Ordner Postausgang auf Inhalt zu prüfen. Sobald er leer ist, müssten eigentlich alle Mails gesendet sein.

    Die Idee kam mir auch... doch auch hier muss ein Abbruch-Timer gesetzt werden, damit es nicht zur Endlosschleife wird, falls Outlook die Mail, aus welchen Gründen auch immer, nicht verschicken kann. Nötig wären dann aber zwei Timer... denn es ja nicht bekannt, wie lange es dauert, bis Outlook die Mail in den Ordner Postausgang verfrachtet hat... denn wenn zu früh geprüft wird, ob der Ordner leer ist, wird das ein Schuss ins eigene Knie. Und um ganz sicher zu gehen, reicht es nicht aus, zu prüfen, ob der Ordner leer ist... es muss geprüft werden, ob genau diese Mail nicht mehr im Ordner ist. Würde mich aber schon interessieren, wie man das prüfen kann...

    Das Sleep von 10 auf 10000 setzen... erhöht aber die Wahrscheinlichkeit extrem, das Windi vor Erhalt der Mail bereits verstorben ist. :rofl:

  • IsNumber() und Zahlen in Textvariablen

    • Bitnugger
    • 3. Juni 2020 um 00:42
    Zitat von HansJ54

    Du hast absolut recht, StringIsDigit() ist besser - das hatte ich überlesen.

    Jeep, in deinem Fall... hatte mich schon wegen deiner Reaktion gewundert... aber wenn du so wichtige Botschaften einfach überliest... dann Schande über Dich und deine Nachkommen! :rofl:

  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 3. Juni 2020 um 00:34
    Zitat von water

    _OL_ItemSendReceive läuft leider asynchron d.h. es wird nicht auf die Fertigstellung des Befehls gewartet.

    Baue doch nach _OL_ItemSendReceive und vor _OL_Close ein Sleep von z.B. 10 Sekunden ein.

    Das ist dann natürlich tückisch... ich würde das _OL_Open/_OL_Close aber auch nicht in der Funktion _Mail_senden platzieren, sondern es etwa so machen:

    AutoIt
    #include <OutlookEX.au3>
    
    Global $oOutlook, $sMeineMailadresse = 'Windi@outlook.de'
    
    _Main()
    
    Func _Main()
        $oOutlook = _OL_Open()
        If @error <> 0 Then Exit MsgBox(16, "", "_OL_Open: Error creating a connection to Outlook. @error = " & @error & ", @extended = " & @extended)
        
        OnAutoItExitRegister('_Exit')
        
        ; ...tu was
        _Mail_senden()
        ; ...tu was
        
        Exit
    EndFunc
    
    Func _Mail_senden() ;Funtion Mail_senden
        ...blablabla
    EndFunc   ;==>_Mail_senden
    
    Func _Exit()
        ; _OL_ItemSendReceive läuft leider asynchron d.h. es wird nicht auf die Fertigstellung des Befehls gewartet.
        ; Deshalb warten wir mit _OL_Close und geben Outlook somit etwas Zeit, eine evtl. noch nicht versandte Mail zu versenden.
        Sleep(10)
        _OL_Close($oOutlook)
    EndFunc   ;==>_Exit
    Alles anzeigen
  • OutlookEX Mail automatisch senden

    • Bitnugger
    • 2. Juni 2020 um 23:52
    Zitat von Windi

    Du hast das 2 mal drin ist das so korrekt.

    Nein, habe es korrigiert...

    Zitat von Windi

    Das hab ich so probiert funktioniert aber nicht wenn Outook nicht voher offen ist.

    offen ist... du meinst, wenn es nicht angezeigt wird? Denn gestartet wurde es ja... mit:

    Code
        Local $oOutlook = _OL_Open()
        If @error <> 0 Then Exit MsgBox(16, "OutlookEX UDF", "Error creating a connection to Outlook. @error = " & @error & ", @extended = " & @extended)

    Ich habe das jetzt mal so bei mir getestet...

    AutoIt
    #include <OutlookEX.au3>
    
    Global $sMeineMailadresse = 'Bitnugger@sagichnicht.de' ; <<<=== Adresse anpassen!!!
    
    _Mail_senden()
    
    Func _Mail_senden() ;Funtion Mail_senden
        Local $oOutlook = _OL_Open()
        If @error <> 0 Then Exit MsgBox(16, "", "_OL_Open: Error creating a connection to Outlook. @error = " & @error & ", @extended = " & @extended)
        Local $sBetreff = "Telefonnummern Kunden Tour 1 " & _NowDate()
        Local $aTermine = [['Tour', 'Vorname Name', 'Straße', 'PLZ', 'Ort', 'Telefonnr 1', 'Telefonnr 2', 'Handy'],  _
            ['Tour 1', 'Vorname Name 1', 'Straße 1', 'PLZ 1', 'Ort 1', 'Telefonnr 1', 'Telefonnr 2', 'Handy 1']]
        Local $sBody = "<html><body>"
        For $i = 1 To UBound($aTermine) - 1
            If $aTermine[$i][0] <> "" Then     ; ignoriere leere Zeilen
                $sBody &= "<P><b><u>" & $aTermine[$i][1] & "</u></b><br>"    ; Vorname Name
                $sBody &= $aTermine[$i][2] & "<br>"    ; Straße
                $sBody &= StringRight("0" & $aTermine[$i][3], 5) & " " & $aTermine[$i][4] & "<br>"   ; PLZ Ort 4 stellig mit 0
                If $aTermine[$i][5] <> "" Then $sBody &= "Privat: " & $aTermine[$i][5] & "<br>"    ; Telefonnr 1
                If $aTermine[$i][6] <> "" Then $sBody &= "Firma:  " & $aTermine[$i][6] & "<br>"    ; Telefonnr 2
                If $aTermine[$i][7] <> "" Then $sBody &= "Mobil:  " & $aTermine[$i][7] & "<br>"    ; Handy
            EndIf
        Next
        $sBody &= "</html></body>"
        Local $oItem = _OL_ItemCreate($oOutlook, $olMailItem, "", "", "Subject=" & $sBetreff, "BodyFormat=" & $olFormatHTML, "HTMLBody=" & $sBody)
        If @error <> 0 Then Exit MsgBox(16, "", "_OL_ItemCreate: @error = " & @error & ", @extended = " & @extended)
        _OL_ItemRecipientAdd($oOutlook, $oItem, Default, $olTo, $sMeineMailadresse)
        If @error <> 0 Then Exit MsgBox(16, "", "_OL_ItemRecipientAdd: @error = " & @error & ", @extended = " & @extended)
        ;$oItem.display ; zeigt die Mail Kontrolle
        _OL_ItemSend($oOutlook, $oItem)      ; sendet ohne nachfrage
         If @error Then
            Exit MsgBox(16, "", "_OL_ItemSend: Mail an " & $sMeineMailadresse & " konnte nicht gesendet werden!")
        Else
            Exit MsgBox(64, "", "_OL_ItemSend: Mail versendet an " & $sMeineMailadresse)
        EndIf
        _OL_ItemSendReceive($oOutlook, True) ; Initiiert die sofortige Zustellung aller nicht zugestellten Nachrichten und den sofortigen Empfang von E-Mails für alle Konten im aktuellen Profil.
         If @error Then Exit MsgBox(16, "", "_OL_ItemSendReceive: Initiierung der sofortige Zustellung fehlgeschlagen!")
        _OL_Close($oOutlook)
    EndFunc   ;==>_Mail_senden
    Alles anzeigen

    ...und die Mail kommt an!

    So sieht der Inhalt dann aus:

    Vorname Name 1

    Straße 1

    PLZ 1 Ort 1

    Privat: Telefonnr 1

    Firma: Telefonnr 2

    Mobil: Handy 1

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™