Pfad zur Datei, die gerade am Bildschirm angezeigt wird auslesen

  • Hallo,

    folgendes Problemchen quält mich gerade:

    Ist es möglich, den Pfad zu einer beliebigen Datei, die gerade in einem Fenster eines beliebigen Programmes angezeigt wird auszulesen oder ist das zu "programmspezifisch"?

    Beispiel:
    Ich hab eine Excel-Datei geöffnet und das Fenster ist aktiv (also focussiert).
    Nun möchte ich irgendwie über winactive (oder eben das Objekt bzw, die Methode von dem/der ich nicht weiß, ob es ihn gibt) herausfinden, welche Datei gerade geöffnet ist - in diesem Fall den Pfad zur Excel-Datei.

    Das Ganze soll aber auch mit Internetseiten, Powerpoint, Word, Emails, usw. funktionieren, also quasi Programmunabhängig.
    Bei Webseiten wärs natürlich kein Problem: Einfach die Adresszeile auslesen und fertig. Aber bei Excel, Word, Photoshop, etc. wüsst ich eben nicht, wie ich an den Pfad der geöffneten Datei kommen könnte...

    Gibts da irgend ne Möglichkeit?

    Ich hoff, ihr könnt mit der Frage was anfangen ansonsten versuch ichs nochmal klarer zu formulieren ;)

    Bin für jede Anregung dankbar.

    Viele Grüße

  • Den Pfad zur der ausgeführten Datei oder den Pfad des geöffneten Dokuments?
    Den Pfad zu der ausgeführten Datei ist einfach
    aber von einem geöffneten Dokument? na ich weis nicht, wär nicht leicht

    Sind TV-Quizfragen zu einfach? A) Ja B) Harry Potter

    Spoiler anzeigen

    Ich gebe zu dieser Post hat wahrscheinlich nicht viel geholfen,
    aber ich versuche wenigstens zu helfen :rolleyes:

  • Hi,

    ich mein eigentlich schon den Pfad zum geöffneten Dokument.
    Also wenn ich ein Word Dokument geöffnet habe nicht zum Pfad der Word.exe sondern eben zum Pfad des in Word geöffneten Dokumentes.

    Ich denk auch, dass es eher schwer bzw. unmöglich ist, das überhaupt zu machen.

    Irgendne Idee oder zumindest einen Ansatz...? Ich für meinen Teil im Moment nicht ;(

    Grüßen

    Daniel

  • Hallo basementmedia,

    da die meisten Porogramme ja die geöffnete Datei mit im Titel haben kannst du bei diesen

    [autoit]

    #Include <String.au3>
    $aVars= WinList("[ACTIVE]")
    $aPath = _StringBetween($aVars[1][0],""," -")
    ConsoleWrite($aPath[0]&@CRLF)

    [/autoit]

    die geöffnete Datei heruasfinden. Ist die Angabe wie bei Scite ein kompletter Pfad bist du schon fertig, ansonsten musst du mit einer rekursiven Suche die Datei auf deiner Festplatte suchen (hoffentlich gibt es sie nur einmal). Es gibt sicher auch noch andere Wege z.B über den gefunden Fenstertitel den Prozess bestimmen und dann mit _WinApi-Funktionen versuchen die Datei herauszufinden,

    mfg autoBert

  • RegExp kann dann weiterhelfen

    Sind TV-Quizfragen zu einfach? A) Ja B) Harry Potter

    Spoiler anzeigen

    Ich gebe zu dieser Post hat wahrscheinlich nicht viel geholfen,
    aber ich versuche wenigstens zu helfen :rolleyes:

  • Hi,

    das mit dem Fenstertitel auslesen wird nicht funktionieren, da im Fenstertitel bei den meisten Programmen ja nur der Dokumentenname steht und ich ja dann den Fall, dass es zwei Dokumente mit dem gleichen Dateinamen gibt aber in unterschiedlichen Pfaden schon mal nicht abdecken kann...
    Außerdem steht bei vielen Programmen nicht nur der Dateiname im Fenstertitel sondern auch noch anderes Zeugs (Microsoft Internet Explorer oder Ähnliches) und da das Tool, dass ich programmieren will mit allen möglichen Programmen zusammenarbeiten soll, die ich aber vorher nicht kenne, kann ich Programmiermäßig dann gar nicht unterscheiden, welcher teil des Fenstertitels Programmname und welcher Dokumentenname ist...

    BugFix : Ich möchte halt, dass die Funktion für jedes beliebige Programm funktioniert und dachte eben, dass die Info, welches Dokument geöffnet ist, vielleicht in irgendeinem Objekt drin steht.

    Dann wird mein Vorhaben wohl nicht möglich sein, oder?

    Viele Grüße

    Daniel

  • Hab jetzt gerade gesehen, dass es anscheinend unter C++ (das ich leider nicht kann ;( möglich ist.
    Denn der ProcessExplorer von https://autoit.de/www.sysinternals.com kann genau das: Eine Auflistung aller Dateien, die von einem bestimmten Prozess (z.B. Word.exe) geöffnet wurden.

    Geht sowas in der Art auch irgendwie mit Autoit?
    Hab mir schon mal die WinAPI Extension runtergeladen, werde aber nicht schlauer...

    Viele Grüße

    Daniel

  • c++ kann eig alles^^
    kannst ja mal ein c++ coder fragen ob er die eine dll zusammen bastelt
    aber nunja, leichter gesagt als getan

    sons in Autoit denk ich nicht möglich

    Sind TV-Quizfragen zu einfach? A) Ja B) Harry Potter

    Spoiler anzeigen

    Ich gebe zu dieser Post hat wahrscheinlich nicht viel geholfen,
    aber ich versuche wenigstens zu helfen :rolleyes:

    • Offizieller Beitrag

    Ich habe doch schon gesagt, wie es einfach geht. Einfach den Pfad auslesen über das Objekt:

    [autoit]

    $oExcel = ObjGet("","Excel.Application") ; Referenz auf die offene Excelanwendung
    $oBook = $oExcel.ActiveWorkbook() ; das aktive Workbook ermitteln
    ConsoleWrite('Pfad des aktuellen Workbooks: ' & $oBook.Path() & '\' & $oBook.Name() & @CRLF)

    [/autoit]


    Analaog gilt das auch für Word und Access. Welche Methoden/Eigenschaften verwendet werden, verrät uns Tante Google (Suchbegriff: Anwendung Objekt Methoden) ;)

    Damit es multiprogrammfähig ist, brauchst du doch nur versuchen Referenzen auf die unterschiedlichen Objekte zu erhalten. Klappt es nicht, ist auch die Anwendung nicht offen. Kannst du dann einfach per Switch durchwandern.

    Edit:

    Ich hab mal schnell solche Funktion erstellt, kannst du ja noch erweitern. Infos zu den Objekten findest du hier.

    Spoiler anzeigen
    [autoit]

    ConsoleWrite(_GetPathFromApp('Powerpoint') & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetPathFromApp($_sApp)
    Local $o
    Switch $_sApp
    Case 'Word'
    $o = ObjGet("","Word.Application")
    If Not IsObj($o) Then Return ''
    Return $o.ActiveDocument.Path() & '\' & $o.ActiveDocument.Name()
    Case 'Excel'
    $o = ObjGet("","Excel.Application")
    If Not IsObj($o) Then Return ''
    Return $o.ActiveWorkbook.Path() & '\' & $o.ActiveWorkbook.Name()
    Case 'Access'
    $o = ObjGet("","Access.Application")
    If Not IsObj($o) Then Return ''
    Return $o.CurrentProject.FullName() ; kann ich mangels Access nicht testen
    Case 'Powerpoint'
    $o = ObjGet("","Powerpoint.Application")
    If Not IsObj($o) Then Return ''
    Return $o.ActivePresentation.FullName()
    EndSwitch
    EndFunc

    [/autoit]
  • Damit es multiprogrammfähig ist, brauchst du doch nur versuchen Referenzen auf die unterschiedlichen Objekte zu erhalten. Klappt es nicht, ist auch die Anwendung nicht offen.

    Das funktioniert doch nur mit Programmen welche auch explizit und bewusst ein COM-Objekt zur Verfügung stellen.
    Außer ein paar Microsoft-Programmen sind das nicht wirklich viele.

    Denn der ProcessExplorer von https://autoit.de/www.sysinternals.com kann genau das: Eine Auflistung aller Dateien, die von einem bestimmten Prozess (z.B. Word.exe) geöffnet wurden.

    Du wolltest doch aber wissen welche Datei z.B. gerade Notepad geöffnet hat oder was wolltest du nun genau?
    Weil der Process Explorer kann einem die offenen File-Handles eines Prozesses anzeigen. Da findest du aber deutlich mehr Dateien als nur die die du bewusst mit dem Programm geöffnet hast.
    Vor allem viele Dll-Dateien und ähnliches.
    Prinzipiell kannst derartige Infos z.B. über die Funktion NtQuerySystemInformation abrufen.
    Ist allerdings nicht ganz unaufwändig und hat meiner Meinung nach auch nicht wirklich viel mit deiner Eingangsfrage zu tun.

    Kurz und knapp: Es ist nicht allgemeingültig umsetzbar weil kein einheitlicher Standard existiert/genutzt wird bei dem ein Programm irgendwo hinterlegt welche Datei es nun genau bewusst geöffnet hat.

  • Hi,

    Offene Dateihandles findet man mit den von Aspirinjunkie und BugFix beschriebenen Einschränkungen per WMI, AutoIt Scriptomatic erstellt z.B. folgendes Script:

    Spoiler anzeigen
    [autoit]

    ; Generated by AutoIt Scriptomatic

    [/autoit] [autoit][/autoit] [autoit]

    $wbemFlagReturnImmediately = 0x10
    $wbemFlagForwardOnly = 0x20
    $colItems = ""
    $strComputer = "localhost"

    [/autoit] [autoit][/autoit] [autoit]

    $Output=""
    $Output = $Output & "Computer: " & $strComputer & @CRLF
    $Output = $Output & "==========================================" & @CRLF
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_FileSpecification", "WQL", _
    $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    [/autoit] [autoit][/autoit] [autoit]

    If IsObj($colItems) then
    For $objItem In $colItems
    $Output = $Output & "Attributes: " & $objItem.Attributes & @CRLF
    $Output = $Output & "Caption: " & $objItem.Caption & @CRLF
    $Output = $Output & "CheckID: " & $objItem.CheckID & @CRLF
    $Output = $Output & "CheckMode: " & $objItem.CheckMode & @CRLF
    $Output = $Output & "CheckSum: " & $objItem.CheckSum & @CRLF
    $Output = $Output & "CRC1: " & $objItem.CRC1 & @CRLF
    $Output = $Output & "CRC2: " & $objItem.CRC2 & @CRLF
    $Output = $Output & "CreateTimeStamp: " & WMIDateStringToDate($objItem.CreateTimeStamp) & @CRLF
    $Output = $Output & "Description: " & $objItem.Description & @CRLF
    $Output = $Output & "FileID: " & $objItem.FileID & @CRLF
    $Output = $Output & "FileSize: " & $objItem.FileSize & @CRLF
    $Output = $Output & "Language: " & $objItem.Language & @CRLF
    $Output = $Output & "MD5Checksum: " & $objItem.MD5Checksum & @CRLF
    $Output = $Output & "Name: " & $objItem.Name & @CRLF
    $Output = $Output & "Sequence: " & $objItem.Sequence & @CRLF
    $Output = $Output & "SoftwareElementID: " & $objItem.SoftwareElementID & @CRLF
    $Output = $Output & "SoftwareElementState: " & $objItem.SoftwareElementState & @CRLF
    $Output = $Output & "TargetOperatingSystem: " & $objItem.TargetOperatingSystem & @CRLF
    $Output = $Output & "Version: " & $objItem.Version & @CRLF
    if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
    $Output=""
    Next
    Else
    Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_FileSpecification" )
    Endif

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WMIDateStringToDate($dtmDate)

    [/autoit] [autoit][/autoit] [autoit]

    Return (StringMid($dtmDate, 5, 2) & "/" & _
    StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
    & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
    EndFunc

    [/autoit]


    Bissl umbauen bzw auf eigene Bedürfnisse anpassen sollte man können^^