FileSystemWatcher Renamed (C#)

FileSystemWatcher Renamed (C#)
2021-10-24T17:03:45+02:00
2021-11-02T22:22:18+01:00
2022-08-12T05:25:29+02:00
helloc
Sziasztok!

Az én gépemen minden rendben van (Windows 10).

A figyelt mappába letöltődik egy fájl.

Egy letöltetlen fájl: valami.mp4.part

Egy már letöltődött fájl átneveződik: valami.mp4

Ekkor elkapja a programom a fájlt mert figyeli a path_import (C:\videos) mappát és átnevezi: valami.mp4.firstapp

Az átnevezés után futtat egy ffmpeg.exe-t, ami az adott videót szerkesztés után elmenti a path_export (C:\videos2) mappába.

Az ffmpeg.exe elérési útvonala hozzá van adva a PATH-hoz, enélkül nem is működne.

Szóval ez nálam mind szépen működik, viszont egy másik gépen (Windows Server 2019) csak az első letöltött fájlt kapja el a programom. Azt át is nevezi, illetve le is fut az ffmpeg.exe. Tehát minden rendben, de a többi fájlt valamiért nem érzékeli, amikor azok *.mp4.part-ról átneveződnek *.mp4-ekké, akkor nem kapja el őket és nem nevezi át őket *.mp4.firstapp-ra.

Miért lehet ez?

Ha viszont manuálisan egy már letöltődött valami2.mp4 fájlt átnevezünk valami3.mp4 névre, akkor érzékeli a szoftver ezt a fájl átnevezést, el is kapja és minden rendben.

A lényeget bemásolom:

Form1.cs

using System; using System.IO; using System.Diagnostics; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Globalization; namespace FirstApp { public partial class Form1 : Form { public static string path_import = ""; public static string path_export = ""; FileSystemWatcher watcher; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button3_Click(object sender, EventArgs e) { this.watch(); } private void watch() { watcher = new FileSystemWatcher(); watcher.Path = Form1.path_import; watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; watcher.Filter = "*.mp4"; watcher.Renamed += OnRenamed; watcher.EnableRaisingEvents = true; } private void OnRenamed(object source, RenamedEventArgs e) { Thread.Sleep(1000); var lastPart = e.FullPath.Split('.').Last(); if (lastPart == "mp4") { File.Move(e.FullPath, e.FullPath + ".firstapp"); string nf = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(e.Name); Thread.Sleep(1000); Process prcExecuteFFMPEG = new Process(); prcExecuteFFMPEG.StartInfo.FileName = "ffmpeg.exe"; prcExecuteFFMPEG.StartInfo.Arguments = "-ss 00:00:30 -i "" + e.FullPath + ".firstapp" -c copy "" + path_export + "\" + nf + """; prcExecuteFFMPEG.StartInfo.UseShellExecute = false; prcExecuteFFMPEG.StartInfo.RedirectStandardOutput = true; prcExecuteFFMPEG.StartInfo.CreateNoWindow = true; prcExecuteFFMPEG.Start(); prcExecuteFFMPEG.WaitForExit(); string strOutput = prcExecuteFFMPEG.StandardOutput.ReadToEnd(); File.Delete(e.FullPath + ".firstapp"); } Thread.Sleep(1000); } } }
Mutasd a teljes hozzászólást!
Nem próbáltam ki, de valami ilyesmire gondoltam:

private void OnRenamed(object source, RenamedEventArgs e) { Task.Run(async() => { await Task.Delay(1000); ProcessRenaming(e.FullPath, e.Name); }); } private void ProcessRenaming(string fullPath, string name) { var lastPart = fullPath.Split('.').Last(); if (lastPart == "mp4") { File.Move(fullPath, fullPath + ".firstapp"); string nf = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name); Process prcExecuteFFMPEG = new Process(); prcExecuteFFMPEG.StartInfo.FileName = "ffmpeg.exe"; prcExecuteFFMPEG.StartInfo.Arguments = "-ss 00:00:30 -i "" + fullPath + ".firstapp" -c copy "" + path_export + "" + nf + """; prcExecuteFFMPEG.StartInfo.UseShellExecute = false; prcExecuteFFMPEG.StartInfo.RedirectStandardOutput = true; prcExecuteFFMPEG.StartInfo.CreateNoWindow = true; prcExecuteFFMPEG.Start(); prcExecuteFFMPEG.WaitForExit(); string strOutput = prcExecuteFFMPEG.StandardOutput.ReadToEnd(); File.Delete(fullPath + ".firstapp"); } }
Mutasd a teljes hozzászólást!

  • A TThread.Sleep-ek mire kellenek? Esetleg próbáld meg kiszedni őket...
    Mutasd a teljes hozzászólást!
  • Azt azért raktam bele mert hibára fut, ha nem késleltetem. Talán a fájlt nem találja vagy foglalt a fájl az átnevezés miatt vagy valami ilyesmi.
    Mutasd a teljes hozzászólást!
  • Akkor legalább futtasd egy task-ban, hogy ne blokkold az event-feldolgozást:

    Task.Run(async() => { await Task.Delay(1000); ProcessRenaming(e.FullPath); });
    Ahol a ProcessRenaming(string path) -ba teszed a kódot, ami most az OnRenamed-ben van.
    Mutasd a teljes hozzászólást!
  • Köszönöm, hogy írtál, de sajnos annyira kezdő vagyok, hogy nem értem. Esetleg kóddal kérhetném a segítséget?
    Mutasd a teljes hozzászólást!
  • Nem próbáltam ki, de valami ilyesmire gondoltam:

    private void OnRenamed(object source, RenamedEventArgs e) { Task.Run(async() => { await Task.Delay(1000); ProcessRenaming(e.FullPath, e.Name); }); } private void ProcessRenaming(string fullPath, string name) { var lastPart = fullPath.Split('.').Last(); if (lastPart == "mp4") { File.Move(fullPath, fullPath + ".firstapp"); string nf = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name); Process prcExecuteFFMPEG = new Process(); prcExecuteFFMPEG.StartInfo.FileName = "ffmpeg.exe"; prcExecuteFFMPEG.StartInfo.Arguments = "-ss 00:00:30 -i "" + fullPath + ".firstapp" -c copy "" + path_export + "" + nf + """; prcExecuteFFMPEG.StartInfo.UseShellExecute = false; prcExecuteFFMPEG.StartInfo.RedirectStandardOutput = true; prcExecuteFFMPEG.StartInfo.CreateNoWindow = true; prcExecuteFFMPEG.Start(); prcExecuteFFMPEG.WaitForExit(); string strOutput = prcExecuteFFMPEG.StandardOutput.ReadToEnd(); File.Delete(fullPath + ".firstapp"); } }
    Mutasd a teljes hozzászólást!
  • Csodálatosan működik mindkét gépen.
    Mutasd a teljes hozzászólást!
  • Örlülök, hogy megoldódott. A másik kérdésedre megoldás lehet a SemaphireSlim osztály:

    using System.Threading;
    ...

    SemaphoreSlim semaphore = new SemaphoreSlim(0, 3); // Egyszerre 3 feldolgozás futhat private void OnRenamed(object source, RenamedEventArgs e) { Task.Run(async() => { await Task.Delay(1000); await semaphore.WaitAsync(); try ProcessRenaming(e.FullPath, e.Name); finally semaphore.Release(); end; }); }
    Mutasd a teljes hozzászólást!
abcd