k0lljj
Goto Top

PowerShell Script mit Anwendung

Guten Morgen zusammen!

Ich benötige mal eure Hilfe.
Ich brauche ein PowerShell Script was folgendes erledigt.

- Sobald ein Word oder Excel Dokument geschlossen wird, soll sich eine Anwendung starten, die ich in dem Script hinterlegen kann. Wichtig ist das die Anwendung mit dem geschlossenen Dokument geöffnet wird (als würde man auf dem Desktop die Word Datei in die Anwendung schieben.)

Bei Fragen meldet euch gerne!

Vielen Dank für eure Unterstützung. face-smile

Content-Key: 1135371877

Url: https://administrator.de/contentid/1135371877

Printed on: May 3, 2024 at 11:05 o'clock

Member: accessViolation
accessViolation Jan 29, 2024 at 07:17:56 (UTC)
Goto Top
Moin,

Bei Fragen meldet euch gerne!
Gerne: was ist Dir das gewünschte Tool denn wert? Klingt so nach Anforderung.

Viele Grüße
Member: TK1987
TK1987 Jan 29, 2024 at 07:35:10 (UTC)
Goto Top
Moin,

# Quelldatei und Anwendung
$source = "<Dateipfad>"  
$app    = "<Programmpfad>"  

try {
  if (!([System.IO.FileInfo]$source).Exists) {throw "Die Quelldatei existiert nicht. "}  
  
  do {
    try {
      $stream = [System.IO.File]::OpenWrite($source)
    } catch {
      Write-Host -NoNewLine ("`r[{0:HH:mm:ss}] Wird gewartet, bis die Datei geschlossen wurde... " -f ([datetime]::get_Now()))  
      sleep 10
    }
  } until ($stream)
  $stream.close()
  Write-Host -ForegroundColor green "ok."  
  &$app $source
  
} catch {
  Write-Host -ForegroundColor red $_.Exception.Message
}

Gruß Thomas
Member: watIsLos
watIsLos Jan 29, 2024 at 07:35:36 (UTC)
Goto Top
Kennst Du dich gar nicht mit Powershell aus, schon mal was selber ausprobiert?
Hast Du ein Code, dann zeig doch mal wo Du stehst...
Ich meine, wir sind hier nicht bei Wünsch dir was!
Member: Crusher79
Crusher79 Jan 29, 2024 at 07:39:14 (UTC)
Goto Top
Member: K0LLJJ
K0LLJJ Jan 29, 2024 at 07:43:44 (UTC)
Goto Top
Hi Thomas,

vielen lieben Dank für deine Mühe.

Ich werde es zeitnah Testen. face-smile

Beste Grüße
Member: K0LLJJ
K0LLJJ Jan 29, 2024 at 08:43:48 (UTC)
Goto Top
Hi zusammen,

hat leider nicht geklappt.

Ich habe folgendes ausprobiert, funktioniert aber nicht:

function OnProcessStop {
$global:watcher.Stop()

$applicationPath = "Pfad zur Anwendung"


$closedFilePath = $global:closedFile.Path


Start-Process -FilePath $applicationPath -ArgumentList $closedFilePath
}

$filter = "TargetInstance ISA 'Win32_Process' AND (TargetInstance.Name = 'WINWORD.EXE' OR TargetInstance.Name = 'EXCEL.EXE')"
$query = "SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE $filter"
$watcher = New-Object ManagementEventWatcher -Query $query
Register-ObjectEvent -InputObject $watcher -EventName EventArrived -Action {
$global:closedFile = Get-Item $event.SourceEventArgs.NewEvent.TargetInstance.Handle
OnProcessStop
} -SourceIdentifier ProcessStopEvent

$watcher.Start()

Write-Host "Warte auf das Schließen von Word oder Excel. Drücke Ctrl+C, um das Skript zu beenden."
try {
while ($true) {
Start-Sleep -Seconds 1
}
}
finally {
$watcher.Stop()
Unregister-Event -SourceIdentifier ProcessStopEvent
}
Member: accessViolation
accessViolation Jan 29, 2024 updated at 08:54:26 (UTC)
Goto Top
Hi.

Ja, das dachte ich mir.

$applicationPath = "Pfad zur Anwendung"
.. hier sollte der Pfad zu deiner Anwendung stehen ..

Copy&Pasta vom Feinsten.

Benutze bitte Codetages.

Gruß
Member: K0LLJJ
K0LLJJ Jan 29, 2024 at 09:11:42 (UTC)
Goto Top
Den Pfad habe ich bereits eingetragen. Habe dies nur für den Post eingetragen.
Member: accessViolation
accessViolation Jan 29, 2024 at 09:51:53 (UTC)
Goto Top
funktioniert aber nicht
Schön und wir sollen nun raten, warum es nicht funktioniert?

Bitte Fehlermeldung posten und auch, wie Du das Script verändert hast....

Montagmorgen, fast wie Freitag.

Gruß
Member: K0LLJJ
K0LLJJ Jan 29, 2024 at 11:53:16 (UTC)
Goto Top
Ayayay.. du scheinst ja heute wirklich schlechte Laune zu haben.

Ich denke ich suche in einem anderen Forum nach Unterstützung.

Vielen Dank an die anderen für die nette und konstruktive Hilfestellung. @accessViolation: Wie sagt man so schön? Du hast teilgenommen.

Schöne Woche.
Member: watIsLos
watIsLos Jan 30, 2024 at 08:27:17 (UTC)
Goto Top
Kauf dir ein Powershell Buch und befasse dich mal damit, sonst verstehst Du nicht wirklich was...

https://www.amazon.de/PowerShell-Core-Dummies-Andreas-Dittfurth/dp/35277 ...
Member: accessViolation
accessViolation Jan 30, 2024 at 08:40:11 (UTC)
Goto Top
du scheinst ja heute wirklich schlechte Laune zu haben.
Nach deinem Post, schon. Ja.

Jetzt denk' Dich mal in uns hinein: Wie sollen wir Dir helfen, wenn Du uns nicht mal die Fehlermeldung mitteilst? "funktioniert aber nicht" ist semihilfreich für uns.

Und: wenn Du uns auch mitteilen würdest, WAS genau Du in dem Script Du geändert hast, könnte man auch hier helfen.

Habe dies nur für den Post eingetragen
:facepalm: Ist halt quatsch um vernünftig unterstützen zu können...

Wie sagt man so schön?
Wieso sollte ich mein Hirn anstrengend, wenn ich mühelos andere dazu bewegen kann?

Kauf dir ein Powershell Buch und befasse dich mal damit, sonst verstehst Du nicht wirklich was...
Achtung: unfreundlicher Kommentar seitens TOs incomming ...

Najaa.

Gruß
Member: colinardo
colinardo Jan 30, 2024 updated at 10:01:27 (UTC)
Goto Top
Servus,
# function to get pathes of currently opened office files
Function Get-OpenedOfficeFiles {
    param(
        [parameter(mandatory=$false)][ValidateSet('All','Powerpoint','Visio','Excel','Word','Publisher','Acrobat')][string[]]$app = 'All'    
    )
    function Get-ExcelFiles {
        # Excel
        try{
            $excel = [System.Runtime.InteropServices.Marshal]::GetActiveObject('Excel.Application')    
            $excel.Workbooks | ?{Test-Path $_.FullName} | select -Expand Fullname
            [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel)
        }catch{}
    }
    function Get-PowerpointFiles {
        # Powerpoint
        try{
            $pp = [System.Runtime.InteropServices.Marshal]::GetActiveObject('Powerpoint.Application')    
            $pp.Presentations | ?{Test-Path $_.FullName} | select -Expand Fullname
            [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($pp)
        }catch{}
    }
    function Get-VisioFiles {
        # Visio
        try{
            $visio = [System.Runtime.InteropServices.Marshal]::GetActiveObject('Visio.Application')    
            $visio.Documents | ?{$_.ObjectType -eq 10 -and (Test-Path $_.Fullname)} | select -Expand Fullname
            [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($visio)
        }catch{}
    }
    function Get-WordFiles {
        # Word
        try{
            $word = [System.Runtime.InteropServices.Marshal]::GetActiveObject('Word.Application')    
            $word.Documents | ?{Test-Path $_.FullName} | select -Expand Fullname
            [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($word)
        }catch{}
    }
    function Get-PublisherFiles {
       # Publisher
        try{
            $pub = [System.Runtime.InteropServices.Marshal]::GetActiveObject('Publisher.Application')    
            $pub.Documents | ?{Test-Path $_.FullName} | select -Expand Fullname
            [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($pub)
        }catch{}
    }
    function Get-AcrobatFiles {
       # Acrobat
        try{
            $acro = New-Object -Com "AcroExch.App"    
            $numdocs = $acro.GetNumAVDocs()
            if ($numdocs){
                0..($numdocs-1) | %{
                    $js = $acro.GetAVDoc($_).GetPDDoc().GetJSObject()
                    [Type]::GetType($js).InvokeMember('Path',[System.Reflection.BindingFlags]::GetProperty,$null,$js,$null) -replace '^/' -replace '/','\' -replace '^(\w+)(?=\\)','$1:'    
                    [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($js)
                }
            }
            [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($acro)
        }catch{}
    }

    switch ($app){
        'All' {    
            Get-PowerpointFiles
            Get-ExcelFiles
            Get-WordFiles
            Get-PublisherFiles
            Get-VisioFiles
            Get-AcrobatFiles
        }
        'Powerpoint' {Get-PowerpointFiles}    
        'Visio' {Get-VisioFiles}    
        'Word' {Get-WordFiles}    
        'Excel' {Get-ExcelFiles}    
        'Publisher' {Get-PublisherFiles}    
        'Acrobat' {Get-AcrobatFiles}    
    }
    [gc]::collect()
    [gc]::WaitForPendingFinalizers()
}

function foreach-parallel {
    [CmdletBinding()]
    param(
        [parameter(mandatory=$true,ValueFromPipeline=$true)][ValidateNotNullOrEmpty()][object[]]$InputObject,
        [parameter(mandatory=$true)][ValidateNotNullOrEmpty()][scriptblock]$process,
        [parameter(mandatory=$false)][ValidateNotNullOrEmpty()][int]$ThrottleLimit = [System.Environment]::ProcessorCount,
        [parameter(mandatory=$false)][switch]$showprogress,
        [parameter(mandatory=$false)][object]$messagedata
        
    )
    begin{
        $rspool = [runspacefactory]::CreateRunspacePool(1,$ThrottleLimit)
        $rspool.ApartmentState = 'STA'    
        $rspool.Open()
        $jobs = New-Object System.Collections.ArrayList
        $objects = New-Object System.Collections.ArrayList
    }
    process{
        $InputObject | %{[void]$objects.Add($_)}
    }
    end{
        foreach ($obj in $objects){
            $ps = [Powershell]::Create()
            $ps.RunspacePool = $rspool
            [void]$ps.AddScript($process).AddParameter('_',$obj).AddParameter('MessageData',$messagedata)    
            $job = $ps.BeginInvoke()
            [void]$jobs.Add(([pscustomobject]@{Handle = $job; Powershell = $ps}))
        }

        write-verbose "Waiting for all jobs to complete."    
        $completed = 0
        while($jobs.Count){
            if ($showprogress.IsPresent){
                Write-Progress -Activity $PSCmdlet.MyInvocation.InvocationName -Status "Total of $($objects.Count) objects." -PercentComplete (($completed / $objects.Count) * 100) -CurrentOperation "Completed $completed of  $($objects.Count)."    
            }
            # process finished jobs and output their result
            $finished = @()
            foreach($job in $jobs | ?{$_.Handle.IsCompleted}){
                $job.Powershell.EndInvoke($job.handle)
                $job.Powershell.Dispose()
                $completed++
                $finished += $job
            }
            $finished | %{$jobs.Remove($_)}
        }
        # cleanup
        $rspool.Close();$rspool.Dispose()
    }
}


# get currently opened word and excel files
$openfiles = Get-OpenedOfficeFiles -app Word,Excel
if ($openfiles){
    write-host "Waiting until all files are closed ..." -F Green    
    #  process files in parallel
    $openfiles | foreach-parallel -showprogress -process {
        param($_)
        # Check file locked state function
        function Is-FileLocked([string]$filePath){
            $fileStream =  $null; $result = $true
            try{
                $fileStream = (New-Object System.IO.FileInfo $filePath).OpenWrite()
                # file is not locked by another process
                $result = $false
            }catch{
            }finally{
                if($filestream){
                    $fileStream.Close(); $fileStream.Dispose()
                }
            }
            return $result
        }
        # wait until file is unlocked
        while(Is-FileLocked $_){
            sleep 1
        }
        
        "File '$_' was closed"    
        # start application to process closed file
        start cmd -ArgumentList "/c echo File '$_' was closed. &pause"    
    }
}else{
    write-warning "No open office files found."    
}
Grüße Uwe