PowerShell break een functie

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Hoi Heb een script gemaakt die naar een patroon in een text bestand moet zoeken.
Dat text bestand word door een applicatie aangemaakt en op het moment dat die applicatie klaar is met verwerken, plaatst hij een bepaalde regel er in. Dit gebeurt met meerdere bestanden die ook gecontroleerd moeten worden.

Het powershell script moet daar op wachten voordat hij verder mag gaan.

Nu checkt het script dat prima, alleen door een break er in stop hij met het script en worden de andere bestanden niet gecontroleerd

Dit is het script waat ik gemaakt hebt. Heb al aardig wat opgezocht op het internet en weet dat het probleem die break is, alleen kom ik er nog niet achter hoe ik dat anders moet oplossen.

Ben daar voor nog lerende met PowerShell. :)

PowerShell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<#
.SYNOPSIS
Lees de PPQ Controle files uit
.DESCRIPTION
Dit script leest de door StreamServe aangemaakte PPQ log files uit, hier wordt in aangegeven dat de aangeleverde PPQ file klaer is met het verwerken.
.PARAMETER Folder
De locatie van het bestand
.PARAMETER FileName
De naam van het bestand wat uitgelezen dient te worden.
.PARAMETER Pattern
De naam van het pattroon waar op gecontroleerd dient te worden.
.EXAMPLE
.\Check-PCLLogs -Folder "C:\Test\" -FileName "test.txt" -Pattern "Ik en klaar met werken"
#>
Function CheckPPQCTRL {
    [CmdletBinding()]
        Param(
           [string]$Folder = "C:\Temp\StreamTest",
           [string]$FileName,
           [string]$Pattern 
    )
    
        If (-not $folder.EndsWith('\')) { 
            $Folder += '\'
        }
    
        $FullPath = $Folder + $FileName
        
        Write-Host "Check if Pattern exsists"
        
        Get-Content $FullPath -wait | ForEach-Object {if($_ -eq "$Pattern") {Break}}
    
    } # End Function
    
    Function CheckFileExists {
        [CmdletBinding()]
            Param(
               [string]$Folder = "C:\Temp\StreamTest",
               [string]$FileName
              
        )
        
            If (-not $folder.EndsWith('\')) { 
                $Folder += '\'
            }
        
            $FullPath = $Folder + $FileName
            Write-Host "CHeck for File exsists"
        
            While (!(Test-Path $FullPath)) {Start-Sleep -s 1}
            Write-Host "File Exsists"
        }        

# Lees PDF_1_Nota_Prod01 Log file
Write-Host "Verwerk PDF_1"
CheckFileExists -FileName "PDF_1_nota_prod01.txt"
CheckPPQCTRL -FileName "PDF_1_nota_prod01.txt" -Pattern "Input PDF_1_nota_prod01.ppq is verwerkt"

# Lees PDF_2_Rappel_Prod01 Log file
Write-Host "Verwerk PDF_2"
CheckFileExists -FileName "PDF_2_rappel_prod01.txt"
CheckPPQCTRL -FileName "PDF_2_rappel_prod01.txt" -Pattern "Input PDF_2_rappel_prod01.ppq is verwerkt"

PS5 User ;-) ...

Beste antwoord (via supernova op 07-04-2019 14:29)


  • downtime
  • Registratie: Januari 2000
  • Niet online

downtime

Everybody lies

supernova schreef op zaterdag 6 april 2019 @ 16:58:
[...]


Waarom die wait er in zit, de log file moet gemonitord worden totdat de $pattern er in staat. Dan pas weet ik dat het proces klaar is waar ik op wacht.
Probeer dit eens. Als ik de documentatie goed interpreteer zit het zo:
  • Get-Content blijft die file monitoren zolang de file bestaat door de -Wait parameter. Wachtend op nieuwe input die dan door de pipeline wordt verwerkt.
  • Break breekt weliswaar uit de ForEach loop maar omdat die onderdeel is van een pipeline spring je feitelijk terug naar het laatste statement vóór ForEach en wordt er gewacht op nieuwe output van het Get-Content statement. En die output komt nooit.
Je hebt nu wat extra code nodig om verder terug te springen in de code en daarvoor kun je labels gebruiken. En schijnbaar kan dat alleen in combinatie met een extra loop. Vandaar dat er hier een extra While loop toegevoegd is.
PowerShell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Function CheckPPQCTRL {
    [CmdletBinding()]
    Param(
        [string]$Folder = "C:\Temp\StreamTest",
        [string]$FileName,
        [string]$Pattern 
    )
    
    $FullPath = Join-Path -Path $Folder -ChildPath $FileName
        
    Write-Host "Check if pattern exists"

    $ContinueLoop = $true

    :StartLoop While ($ContinueLoop) {

        Get-Content $FullPath -Wait | ForEach-Object {

            If ($_ -eq $Pattern) {
                $ContinueLoop = $false
                Break StartLoop
            }
        }
    }
} # End Function

Alle reacties


Acties:
  • 0 Henk 'm!

  • Ursamajor
  • Registratie: Juli 2002
  • Laatst online: 19-06 13:15

Ursamajor

Astrofotograaf

Waarom zou je een bestand dat door de ene applicatie wordt aangemaakt steeds laten controleren door een andere applicatie?
Wat moet er uiteindelijk gebeuren als het bestand gereed is?

In jouw script controleer je een set bestanden op de $pattern en als ie er niet is, ga je uit de loop, dus wordt de rest ook niet gecontroleerd.

Gadgets FTW!


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Ursamajor schreef op vrijdag 5 april 2019 @ 11:24:
Waarom zou je een bestand dat door de ene applicatie wordt aangemaakt steeds laten controleren door een andere applicatie?
Wat moet er uiteindelijk gebeuren als het bestand gereed is?

In jouw script controleer je een set bestanden op de $pattern en als ie er niet is, ga je uit de loop, dus wordt de rest ook niet gecontroleerd.
DIt is een onderdeel van meerdere stappen, die de verwerking van een applicatie laat starten en moet controleren of die verwerkingen klaar zijn voordat het proces verder mag.

Die log bestanden zijn belangrijk en bestaan uit meerdere verwerkings bestanden.

Elke log wordt aangemaakt door de applicatie en het is dan wachten tot de applicatie in de log aangeeft dat hij klaar is.

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • Ursamajor
  • Registratie: Juli 2002
  • Laatst online: 19-06 13:15

Ursamajor

Astrofotograaf

Wellicht moet je naast de break nog een actie uitvoeren / parameter zetten. Nu stopt het script inderdaad.
Zelf net ook even mee zitten stoeien.
code:
1
2
3
4
write-host 'checking'
Get-Content stream.txt -wait | ForEach-Object {if($_ -eq "einde") {
write-host 'klaar'
Break}}

Gadgets FTW!


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Ursamajor schreef op vrijdag 5 april 2019 @ 11:59:
Wellicht moet je naast de break nog een actie uitvoeren / parameter zetten. Nu stopt het script inderdaad.
Zelf net ook even mee zitten stoeien.
code:
1
2
3
4
write-host 'checking'
Get-Content stream.txt -wait | ForEach-Object {if($_ -eq "einde") {
write-host 'klaar'
Break}}
Dat maakt dus niet veel uit. De volgende check voert hij niet uit. Na de break komt hij gewoon weer in het console terecht. :-(

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • Ursamajor
  • Registratie: Juli 2002
  • Laatst online: 19-06 13:15

Ursamajor

Astrofotograaf

Wellicht is het maken van 1 job per file iets? En anders denk ik dat je zelf een loopje moet maken die het bestand controleert totdat de pattern gevonden is.
Ben natuurlijk wel benieuwd naar je oplossing, daar ik ook nog niet heel ervaren ben met Powershell :9

Gadgets FTW!


Acties:
  • 0 Henk 'm!

  • Heroic_Nonsense
  • Registratie: Januari 2015
  • Laatst online: 11:24

Heroic_Nonsense

bartonsontheweb.nl

Je kunt in de outputlaag van StreamServe scripten dat hij de PPQ's verplaatst naar een andere map als hij klaar is (met de functie fileMove() of fileCopy() als je gelijk een backup wil). Dan kun je periodiek de tweede applicatie naar nieuw PPQ's laten checken en het op laten pakken.

Syntax:
http://onlinehelp.streams...ptingFunctions.2.020.html

(manual is voor 5.6.2, maar in oudere versies en in ExStream werkt dit net zo)

Such Heroic Nonsense - Proud admin of https://www.bartonsontheweb.nl and owner of https://netstek.nl


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Heroic_Nonsense schreef op vrijdag 5 april 2019 @ 12:37:
Je kunt in de outputlaag van StreamServe scripten dat hij de PPQ's verplaatst naar een andere map als hij klaar is (met de functie fileMove() of fileCopy() als je gelijk een backup wil). Dan kun je periodiek de tweede applicatie naar nieuw PPQ's laten checken en het op laten pakken.

Syntax:
http://onlinehelp.streams...ptingFunctions.2.020.html

(manual is voor 5.6.2, maar in oudere versies en in ExStream werkt dit net zo)
Het is inderdaad StreamServe, maar dat stukje van de PPQ bestanden wordt al gedaan.
Er gebeuren nog wat andere zaken die afhankelijk zijn van het klaar zijn van de PPQ bestanden. En daar moet ik opwachten. Vandaar dit stukje script. Ik ben verder geen beheerder van de applicatie.

Heb al een VBScript draaien, maar ben die nu langzaam aan het omzetten naar PowerShell. Maar dat stukje VBScript doet iets te veel en te langzaam.

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • Heroic_Nonsense
  • Registratie: Januari 2015
  • Laatst online: 11:24

Heroic_Nonsense

bartonsontheweb.nl

supernova schreef op vrijdag 5 april 2019 @ 12:50:
[...]


Het is inderdaad StreamServe, maar dat stukje van de PPQ bestanden wordt al gedaan.
Er gebeuren nog wat andere zaken die afhankelijk zijn van het klaar zijn van de PPQ bestanden. En daar moet ik opwachten. Vandaar dit stukje script. Ik ben verder geen beheerder van de applicatie.

Heb al een VBScript draaien, maar ben die nu langzaam aan het omzetten naar PowerShell. Maar dat stukje VBScript doet iets te veel en te langzaam.
Heb je wel contact met de afdeling/partner die StreamServe beheert? Want als je iemand zo lief kunt krijgen dat hij de scripting op de outputlaag aanpast, kun je ook om dat probleem heen.

Je zou StreamServe namelijk in de lead kunnen zetten voor alle taken die na het gereedkomen van de PPQ's moeten gebeuren. Vanuit de scripting kun je namelijk OS-commando's afvuren (ook PowerShell-scripts) en executables starten; compleet met parameters. Dat moet wel allemaal op dezelfde applicatieserver uitgevoerd worden als waar StreamServe op draait.

Zelf gebruik ik CURL.exe, 7zip en nog wat andere zaken veel.

Maar ik redeneer nu wel heel erg vanuit StreamServe :)

Such Heroic Nonsense - Proud admin of https://www.bartonsontheweb.nl and owner of https://netstek.nl


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Heroic_Nonsense schreef op vrijdag 5 april 2019 @ 12:57:
[...]


Heb je wel contact met de afdeling/partner die StreamServe beheert? Want als je iemand zo lief kunt krijgen dat hij de scripting op de outputlaag aanpast, kun je ook om dat probleem heen.

Je zou StreamServe namelijk in de lead kunnen zetten voor alle taken die na het gereedkomen van de PPQ's moeten gebeuren. Vanuit de scripting kun je namelijk OS-commando's afvuren (ook PowerShell-scripts) en executables starten; compleet met parameters. Dat moet wel allemaal op dezelfde applicatieserver uitgevoerd worden als waar StreamServe op draait.

Zelf gebruik ik CURL.exe, 7zip en nog wat andere zaken veel.

Maar ik redeneer nu wel heel erg vanuit StreamServe :)
Helaas niet meer. Ze willen geen veranderingen meer aan StreamServe, Dus moet het daar mee doen.
Voor nu laat ik de controle door het VBScript doen, wat ik 5 jaar geleden heb gemaakt. Maar dat is het enige stukje nog, vandaar dat ik probeer het naar PowerShell om te zetten.

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Denk dat ik het op de volgende manier op ga lossen. Door aparte modules er van te maken... :-)

Dat gaat natuurlijk ook niet werken, omdat hij het script afbreekt voordat hij de tweede optie kan doen.

[ Voor 38% gewijzigd door supernova op 05-04-2019 13:52 ]

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • downtime
  • Registratie: Januari 2000
  • Niet online

downtime

Everybody lies

Moet daar waar nu Break staat niet gewoon Return $_ staan?

Acties:
  • 0 Henk 'm!

  • Sandor_Clegane
  • Registratie: Januari 2012
  • Niet online

Sandor_Clegane

Fancy plans and pants to match

Loop door alle bestanden via een scheduled task, staat er niet de magic string in, niks doen. Anders verwerken?

En dat dat elke 5 minuten laten runnen?

En Return ipv Break klinkt mij ook beter in de oren.

Less alienation, more cooperation.


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
downtime schreef op zaterdag 6 april 2019 @ 11:39:
Moet daar waar nu Break staat niet gewoon Return $_ staan?
Als je Return $_ gebruikt i.p.v. break, dan blijft hij staan wachten en komt nooit de functie meer uit.

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Sandor_Clegane schreef op zaterdag 6 april 2019 @ 13:41:
Loop door alle bestanden via een scheduled task, staat er niet de magic string in, niks doen. Anders verwerken?

En dat dat elke 5 minuten laten runnen?

En Return ipv Break klinkt mij ook beter in de oren.
Dit stukje maakt een onderdeel uit van een grotere verwerking en die word ook d.m.v. een task scheduler gedaait. Alleen op dit moment draait het met VBScript en ik wil het naar Powershell omzetten.

Het is ook de bedoeling dat het script blijft wachten tot hij de waarde ziet en moet dan het volgende log bestand uitlezen, om te kijken of hij weer verder mag met het script.

Dat geld voor 10 log files.

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • downtime
  • Registratie: Januari 2000
  • Niet online

downtime

Everybody lies

supernova schreef op zaterdag 6 april 2019 @ 15:37:
[...]

Als je Return $_ gebruikt i.p.v. break, dan blijft hij staan wachten en komt nooit de functie meer uit.
Er zitten dan ook twee of drie fouten in het script. Dit werkt bij mij:

PowerShell:
1
2
3
4
5
6
    Get-Content $FullPath | ForEach-Object {
        If ($_ -eq $Pattern) {
            Write-Host "Hebbes!"
            Return 
        }
    }

Ik vroeg me al af waar die -Wait voor nodig was. Door die weg te halen, en de Break door Return te vervangen, loopt het script bij mij gewoon door. Ik heb ook de quotes rond $Pattern verwijderd. Die zijn zinloos op die plek.

Acties:
  • 0 Henk 'm!

  • Sandor_Clegane
  • Registratie: Januari 2012
  • Niet online

Sandor_Clegane

Fancy plans and pants to match

supernova schreef op zaterdag 6 april 2019 @ 15:40:
[...]

Dit stukje maakt een onderdeel uit van een grotere verwerking en die word ook d.m.v. een task scheduler gedaait. Alleen op dit moment draait het met VBScript en ik wil het naar Powershell omzetten.

Het is ook de bedoeling dat het script blijft wachten tot hij de waarde ziet en moet dan het volgende log bestand uitlezen, om te kijken of hij weer verder mag met het script.

Dat geld voor 10 log files.
Wat bedoel je met "wachten"? Het script blijft draaien en zit letterlijk te wachten? Of bedoel je de volgende run?

Ik zou het script gewoon het bestand laten skippen bij het ontbreken van de "magic string" en in de volgende run weer te kijken of de "magic string" erin staat. Zo ja dan verder processen, zo nee skippen.

Less alienation, more cooperation.


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Sandor_Clegane schreef op zaterdag 6 april 2019 @ 16:20:
[...]


Wat bedoel je met "wachten"? Het script blijft draaien en zit letterlijk te wachten? Of bedoel je de volgende run?

Ik zou het script gewoon het bestand laten skippen bij het ontbreken van de "magic string" en in de volgende run weer te kijken of de "magic string" erin staat. Zo ja dan verder processen, zo nee skippen.
Dat is het probleem. Script moet wachten tot de string aanwezig is in de log file, dan pas mag het verder.

Die logs zijn onderdeel van een groter proces. Die logs mogen niet over geslagen worden.

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
downtime schreef op zaterdag 6 april 2019 @ 16:20:
[...]

Er zitten dan ook twee of drie fouten in het script. Dit werkt bij mij:

PowerShell:
1
2
3
4
5
6
    Get-Content $FullPath | ForEach-Object {
        If ($_ -eq $Pattern) {
            Write-Host "Hebbes!"
            Return 
        }
    }

Ik vroeg me al af waar die -Wait voor nodig was. Door die weg te halen, en de Break door Return te vervangen, loopt het script bij mij gewoon door. Ik heb ook de quotes rond $Pattern verwijderd. Die zijn zinloos op die plek.
Waarom die wait er in zit, de log file moet gemonitord worden totdat de $pattern er in staat. Dan pas weet ik dat het proces klaar is waar ik op wacht.

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • Sandor_Clegane
  • Registratie: Januari 2012
  • Niet online

Sandor_Clegane

Fancy plans and pants to match

supernova schreef op zaterdag 6 april 2019 @ 16:55:
[...]


Dat is het probleem. Script moet wachten tot de string aanwezig is in de log file, dan pas mag het verder.

Die logs zijn onderdeel van een groter proces. Die logs mogen niet over geslagen worden.
Maar dat worden ze toch ook niet? Bij de volgende run worden ze dan wel meegenomen.

Of hou je files constant open?

Blijkbaar zoek je iets dat een tail doet op de files, op zoek is naar een specifieke string en zo gauw deze gevonden worden moet hij er iets mee doen.

Je zal dus meerdere get-contents moeten doen, een per file die hij moet checken.

Zie dit voor een workflow achtige oplossing:
https://stackoverflow.com...ell-for-particular-string

[ Voor 34% gewijzigd door Sandor_Clegane op 06-04-2019 17:30 ]

Less alienation, more cooperation.


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • downtime
  • Registratie: Januari 2000
  • Niet online

downtime

Everybody lies

supernova schreef op zaterdag 6 april 2019 @ 16:58:
[...]


Waarom die wait er in zit, de log file moet gemonitord worden totdat de $pattern er in staat. Dan pas weet ik dat het proces klaar is waar ik op wacht.
Probeer dit eens. Als ik de documentatie goed interpreteer zit het zo:
  • Get-Content blijft die file monitoren zolang de file bestaat door de -Wait parameter. Wachtend op nieuwe input die dan door de pipeline wordt verwerkt.
  • Break breekt weliswaar uit de ForEach loop maar omdat die onderdeel is van een pipeline spring je feitelijk terug naar het laatste statement vóór ForEach en wordt er gewacht op nieuwe output van het Get-Content statement. En die output komt nooit.
Je hebt nu wat extra code nodig om verder terug te springen in de code en daarvoor kun je labels gebruiken. En schijnbaar kan dat alleen in combinatie met een extra loop. Vandaar dat er hier een extra While loop toegevoegd is.
PowerShell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Function CheckPPQCTRL {
    [CmdletBinding()]
    Param(
        [string]$Folder = "C:\Temp\StreamTest",
        [string]$FileName,
        [string]$Pattern 
    )
    
    $FullPath = Join-Path -Path $Folder -ChildPath $FileName
        
    Write-Host "Check if pattern exists"

    $ContinueLoop = $true

    :StartLoop While ($ContinueLoop) {

        Get-Content $FullPath -Wait | ForEach-Object {

            If ($_ -eq $Pattern) {
                $ContinueLoop = $false
                Break StartLoop
            }
        }
    }
} # End Function

Acties:
  • 0 Henk 'm!

  • Sandor_Clegane
  • Registratie: Januari 2012
  • Niet online

Sandor_Clegane

Fancy plans and pants to match

Omdat Unity liep te klooien en ik daar wel een beetje klaar mee was en ik het wel een uitdaging vond:

F#
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Learn more about F# at http://fsharp.org

open System
open System.IO

let fileDir = """C:\FSWatcher"""

let foundDir = """C:\FSFound"""

let files = ["file1.txt"; "file2.txt"; "file3.txt"]

let createFiles dir files =
    files
    |> Seq.iter(fun file -> 
        let path = Path.Combine(dir,file)
        match File.Exists path with
                            | true -> ()
                            | false ->
                                use outStream = new FileStream(path, FileMode.Create, FileAccess.Write)
                                outStream.Flush()
                                outStream.Close()                    
                )

let createDir dir =
    match Directory.Exists dir with
    | false ->
        Directory.CreateDirectory(dir)
        |> ignore
        
    | true -> ()

let getFiles path =
    Directory.GetFileSystemEntries(path, "*.txt")
    |> Array.map(fun entry -> FileInfo(entry).Name)
    |> List.ofArray


let rec addStringToFile timeout dir filename iterations current =
    let file = Path.Combine(dir, filename)
    let muggleString = "Dit zoek ik dus niet"
    let magicString = "een magic string"
    async {
        match File.Exists file with
        | true ->
            match iterations = current with
            | true ->
                use file = new StreamWriter(new FileStream(file, FileMode.Open, FileAccess.ReadWrite,FileShare.ReadWrite))
                file.BaseStream.Position <- file.BaseStream.Length
                file.WriteLine(magicString)
                file.Flush()

            | false ->    
                    use file = new StreamWriter(new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                    file.BaseStream.Position <- file.BaseStream.Length
                    file.WriteLine(muggleString)
                    file.Flush()
        | false ->
            ()
        do! Async.Sleep timeout
        do! addStringToFile timeout dir filename iterations (current + 1)
    }


    

type FsProcessor(files:string List, searchString:string, foundDirectory:string) =
    let processor =
         new MailboxProcessor<FileSystemEventArgs>(fun inbox ->
            let rec loop(fileMap:Map<string,StreamReader>) = 
                async {
                    let! e = inbox.Receive()
                    let result = fileMap.[e.Name].ReadToEnd()
                    match result with
                    | result when result.Contains(searchString) -> 
                        printfn "gevonden"
                        fileMap.[e.Name].Close()
                        File.Copy(e.FullPath, Path.Combine(foundDirectory,e.Name))
                        File.Delete(e.FullPath)
                        return! loop(fileMap.Remove(e.Name))
                    | _ -> 
                        return! loop(fileMap)
                }
            loop(files
                 |> List.map(fun x -> (x, new StreamReader(new FileStream(Path.Combine(fileDir, x), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))))
                 |> Map.ofList)
            )
    member this.Post(msg) = processor.Post(msg)
    member this.Start() = processor.Start()
    

let fswatcher(processor:FsProcessor) = 
    let watcher = new FileSystemWatcher(fileDir, "*.txt")
    watcher.EnableRaisingEvents <- true
    watcher.Changed.Add(fun event -> processor.Post(event))
    watcher


[<EntryPoint>]
let main argv =
    createDir fileDir
    createDir foundDir
    createFiles fileDir files
    let fsEntries = getFiles fileDir
    let processor = FsProcessor(fsEntries, "een magic string", foundDir)
    processor.Start()
    fswatcher(processor) |> ignore
    [addStringToFile 1000 fileDir files.[0] 15 0; addStringToFile 2000 fileDir files.[1] 16 0; addStringToFile 3000 fileDir files.[2] 5 0]
    |> Async.Parallel
    |> Async.RunSynchronously
    |> ignore
    Console.ReadLine() |> ignore
    0 // return an integer exit code


Maakt twee directories aan, een watch directory en een found directory. In de watch directory worden 3 files aangemaakt en hierin worden strings geschreven met een interval. Na een aantal iteraties zet hij de magic string erin.

Verder wordt een FileSystem watcher aangemaakt en deze luistert naar Changed events. Deze changed events checked hij op de magic string staat ie erin dan kopieert hij de file naar de found directory en delete het origineel.

Zou het nog zo kunnen maken dat hij ook nieuwe files in de gaten gaat houden, maar ja. Het werkt :)

Less alienation, more cooperation.


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
downtime schreef op zaterdag 6 april 2019 @ 20:39:
[...]

Probeer dit eens. Als ik de documentatie goed interpreteer zit het zo:
  • Get-Content blijft die file monitoren zolang de file bestaat door de -Wait parameter. Wachtend op nieuwe input die dan door de pipeline wordt verwerkt.
  • Break breekt weliswaar uit de ForEach loop maar omdat die onderdeel is van een pipeline spring je feitelijk terug naar het laatste statement vóór ForEach en wordt er gewacht op nieuwe output van het Get-Content statement. En die output komt nooit.
Je hebt nu wat extra code nodig om verder terug te springen in de code en daarvoor kun je labels gebruiken. En schijnbaar kan dat alleen in combinatie met een extra loop. Vandaar dat er hier een extra While loop toegevoegd is.
PowerShell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Function CheckPPQCTRL {
    [CmdletBinding()]
    Param(
        [string]$Folder = "C:\Temp\StreamTest",
        [string]$FileName,
        [string]$Pattern 
    )
    
    $FullPath = Join-Path -Path $Folder -ChildPath $FileName
        
    Write-Host "Check if pattern exists"

    $ContinueLoop = $true

    :StartLoop While ($ContinueLoop) {

        Get-Content $FullPath -Wait | ForEach-Object {

            If ($_ -eq $Pattern) {
                $ContinueLoop = $false
                Break StartLoop
            }
        }
    }
} # End Function
Voor zo ver ik nu kan zien, is dit wat prefect werkt. Morgen op het werk ga ik het even verder uittesten. Thanks _/-\o_

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • supernova
  • Registratie: Augustus 2000
  • Laatst online: 22-06 20:37

supernova

Zabbix specialist 7 ;-)

Topicstarter
Sandor_Clegane schreef op zaterdag 6 april 2019 @ 22:09:
Omdat Unity liep te klooien en ik daar wel een beetje klaar mee was en ik het wel een uitdaging vond:

F#
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Learn more about F# at http://fsharp.org

open System
open System.IO

let fileDir = """C:\FSWatcher"""

let foundDir = """C:\FSFound"""

let files = ["file1.txt"; "file2.txt"; "file3.txt"]

let createFiles dir files =
    files
    |> Seq.iter(fun file -> 
        let path = Path.Combine(dir,file)
        match File.Exists path with
                            | true -> ()
                            | false ->
                                use outStream = new FileStream(path, FileMode.Create, FileAccess.Write)
                                outStream.Flush()
                                outStream.Close()                    
                )

let createDir dir =
    match Directory.Exists dir with
    | false ->
        Directory.CreateDirectory(dir)
        |> ignore
        
    | true -> ()

let getFiles path =
    Directory.GetFileSystemEntries(path, "*.txt")
    |> Array.map(fun entry -> FileInfo(entry).Name)
    |> List.ofArray


let rec addStringToFile timeout dir filename iterations current =
    let file = Path.Combine(dir, filename)
    let muggleString = "Dit zoek ik dus niet"
    let magicString = "een magic string"
    async {
        match File.Exists file with
        | true ->
            match iterations = current with
            | true ->
                use file = new StreamWriter(new FileStream(file, FileMode.Open, FileAccess.ReadWrite,FileShare.ReadWrite))
                file.BaseStream.Position <- file.BaseStream.Length
                file.WriteLine(magicString)
                file.Flush()

            | false ->    
                    use file = new StreamWriter(new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                    file.BaseStream.Position <- file.BaseStream.Length
                    file.WriteLine(muggleString)
                    file.Flush()
        | false ->
            ()
        do! Async.Sleep timeout
        do! addStringToFile timeout dir filename iterations (current + 1)
    }


    

type FsProcessor(files:string List, searchString:string, foundDirectory:string) =
    let processor =
         new MailboxProcessor<FileSystemEventArgs>(fun inbox ->
            let rec loop(fileMap:Map<string,StreamReader>) = 
                async {
                    let! e = inbox.Receive()
                    let result = fileMap.[e.Name].ReadToEnd()
                    match result with
                    | result when result.Contains(searchString) -> 
                        printfn "gevonden"
                        fileMap.[e.Name].Close()
                        File.Copy(e.FullPath, Path.Combine(foundDirectory,e.Name))
                        File.Delete(e.FullPath)
                        return! loop(fileMap.Remove(e.Name))
                    | _ -> 
                        return! loop(fileMap)
                }
            loop(files
                 |> List.map(fun x -> (x, new StreamReader(new FileStream(Path.Combine(fileDir, x), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))))
                 |> Map.ofList)
            )
    member this.Post(msg) = processor.Post(msg)
    member this.Start() = processor.Start()
    

let fswatcher(processor:FsProcessor) = 
    let watcher = new FileSystemWatcher(fileDir, "*.txt")
    watcher.EnableRaisingEvents <- true
    watcher.Changed.Add(fun event -> processor.Post(event))
    watcher


[<EntryPoint>]
let main argv =
    createDir fileDir
    createDir foundDir
    createFiles fileDir files
    let fsEntries = getFiles fileDir
    let processor = FsProcessor(fsEntries, "een magic string", foundDir)
    processor.Start()
    fswatcher(processor) |> ignore
    [addStringToFile 1000 fileDir files.[0] 15 0; addStringToFile 2000 fileDir files.[1] 16 0; addStringToFile 3000 fileDir files.[2] 5 0]
    |> Async.Parallel
    |> Async.RunSynchronously
    |> ignore
    Console.ReadLine() |> ignore
    0 // return an integer exit code


Maakt twee directories aan, een watch directory en een found directory. In de watch directory worden 3 files aangemaakt en hierin worden strings geschreven met een interval. Na een aantal iteraties zet hij de magic string erin.

Verder wordt een FileSystem watcher aangemaakt en deze luistert naar Changed events. Deze changed events checked hij op de magic string staat ie erin dan kopieert hij de file naar de found directory en delete het origineel.

Zou het nog zo kunnen maken dat hij ook nieuwe files in de gaten gaat houden, maar ja. Het werkt :)
FSharp is mij volledig onbekend... Maar zal er zeker eens naar kijken. Alleen gebruiken in de omgeving gaat helaas niet werken, alle collega's hebben hier geen ervaring mee (Of eigenlijk Kaas van gegeten)

Maar bedankt voor het meedenken. :*)

PS5 User ;-) ...


Acties:
  • 0 Henk 'm!

  • Sandor_Clegane
  • Registratie: Januari 2012
  • Niet online

Sandor_Clegane

Fancy plans and pants to match

supernova schreef op zondag 7 april 2019 @ 14:32:
[...]


FSharp is mij volledig onbekend... Maar zal er zeker eens naar kijken. Alleen gebruiken in de omgeving gaat helaas niet werken, alle collega's hebben hier geen ervaring mee (Of eigenlijk Kaas van gegeten)

Maar bedankt voor het meedenken. :*)
Ik vond het leuk om te maken. :)

In mijn bovenstaande post staat een link naar stack overflow waarin ze een parallel foreach workflow in powershell gebruiken. Dat zou ook moeten werken.

[ Voor 29% gewijzigd door Sandor_Clegane op 07-04-2019 16:34 ]

Less alienation, more cooperation.

Pagina: 1