היי,
להלן פתרון תרגיל הבית שחברת גאגא נותנת לאחר מרכז ההערכה בSQLink למשרת C# Automation
בהצלחה! (הבחור שבחן אותי בתרגיל היה מתנסה ולא נעים בכלל, אבל תשפטו אותו אתם).
ללא טיפול בקבצים:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.AccessControl;
namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        private static FileSystemWatcher watcher;
        
        private static string targetFolder;
 
        
        public Form1()
        {
            InitializeComponent();
        }
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        private void sourcePath_TextBox(object sender, EventArgs e)
        {
            if (sourcePathValidation(true))
            {
                // Create a new FileSystemWatcher and set its properties.
                watcher = new FileSystemWatcher();
                watcher.Path = sourcePath.Text;
            }
           
            
        }
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        private void targetPath_TextBox(object sender, EventArgs e)
        {
            bool message= true;
            targetFolder = targetPath.Text;
            if (!sourcePathValidation(false))
                message = false;
            if (targetPathValidation(message) && !Directory.Exists(targetFolder) )
            {
                Directory.CreateDirectory(targetFolder);
            }
        }
        private void stopButton_Click(object sender, EventArgs e)
        {
            if (!sourcePathValidation(false) || !targetPathValidation(false) || watcher==null)
            {
                MessageBox.Show("The program did not record anything yet, please press the start button first");
                return;
            }
            if (watcher != null )
            {
                watcher.EnableRaisingEvents = false;
                watcher.Dispose();
                MessageBox.Show("Stop listening");
            }
        }
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        private void startButton_Click(object sender, EventArgs e)
        {
            sourcePath_TextBox(sender, e);
            targetPath_TextBox(sender, e);
            if (!sourcePathValidation(false) || !targetPathValidation(false))
            {
                return;
            }
            removeReadOnlyAttr();
            /* Watch for changes in LastAccess and LastWrite times, and
                the renaming of files or directories. */
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                    | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            // All files.
            watcher.Filter = "*.*";
            watcher.IncludeSubdirectories = true;
            // Add event handlers.
            
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.Deleted += new FileSystemEventHandler(OnDeleted);
            watcher.Renamed += new RenamedEventHandler(OnRenamed);
            
                  
            // Begin watching.
            watcher.EnableRaisingEvents = true;  
            MessageBox.Show("Start listening");
        }
        // Define the event handlers. 
        private static void OnCreated(object source, FileSystemEventArgs e)
        {
        }
        // Define the event handlers. 
        private static void OnChanged(object source, FileSystemEventArgs e)
        {
            string fileNewName;
            fileNewName = e.Name;
            string fileExt = Path.GetExtension(e.Name);
            //Path.GetFileName(e.Name)
            if (fileExt != ".TXT")
            {
                fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt;
            }
            string fullSourcePath = Path.Combine(watcher.Path, e.Name);
            string fullTargetPath = Path.Combine(targetFolder, fileNewName);
            if (!File.Exists(fullSourcePath))
            {
                return;
            }
            /*if (File.Exists(fullTargetPath))
            {
                return;
            }*/
            if (!e.Name.Contains("~") || Path.GetExtension(e.Name) != ".tmp"/*   e.Name.Substring(0, 1) != "~"*/)
            {
                try
                {
                    // get the file attributes for file or directory
                    FileAttributes attr = File.GetAttributes(fullSourcePath);
                    //detect whether its a directory or file
                    if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
                    {
                        if (!e.Name.Contains("~") || Path.GetExtension(e.Name) != ".tmp")
                        {
                            WaitReady(fullSourcePath);
                        }
                        copyFolderFromSourceToTarget(fullSourcePath, fullTargetPath);
                        MessageBox.Show("directory");
                    }
                    else
                    {
                        WaitReady(fullSourcePath);
                        
                        copyFileFromSourceToTarget(fullSourcePath, fullTargetPath);
                    }
                }
                catch (FileNotFoundException) { }
                
            }
            deleteAllTmpFilesInWantedFolder(targetFolder);
            // Specify what is done when a file is changed, created.
            System.Diagnostics.Debug.WriteLine("File: " + e.Name + " " + e.ChangeType);
            System.Diagnostics.Debug.WriteLine("File: " + fullTargetPath + " has been updated");
        }
        // Define the event handlers. 
        private static void OnDeleted(object source, FileSystemEventArgs e)
        {
            if (e.Name.Contains("~") /*e.Name.Substring(0, 1) == "~"*/ || Path.GetExtension(e.Name)==".tmp" ||
                e.Name.Contains(".pptx")) 
                
            {
                return;
            }
           // WaitReady(Path.Combine(watcher.Path,e.Name));
            string fileNewName;
            string fileExt = Path.GetExtension(e.Name);
            fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_deleted" + fileExt;
            //string noExt =  Path.GetFileNameWithoutExtension(e.Name);
            if (!findFileInFolder(targetFolder, e.Name, ".TXT"))
            {
                if (fileExt != ".TXT")
                {
                    fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_deleted_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt;
                }
                string deletedFile = Path.Combine(targetFolder, fileNewName);
                File.Create(deletedFile).Close();
            }
            else
            {
                findOldFileInTargetAndChangeHisName(targetFolder, e.Name, fileNewName, ".TXT");
            }
            deleteAllTmpFilesInWantedFolder(targetFolder);
            // Specify what is done when a file is deleted.
            System.Diagnostics.Debug.WriteLine("File: " + e.Name + " " + e.ChangeType);
            //System.Diagnostics.Debug.WriteLine("File: " + fullTargetPath + " has been deleted");
        }
        private static void OnRenamed(object source, RenamedEventArgs e)
        {
            if(/*e.Name.Substring(0, 1) == "~" */e.Name.Contains("~") || Path.GetExtension(e.Name) == ".tmp")
            {
                return;
            }
            //string fileNewName;
            string fileNewName = e.Name;
            
            string fileExt = Path.GetExtension(e.Name);
               
            if (fileExt != ".TXT")
            {
                fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt;
            }
           /* if (File.Exists(Path.Combine(watcher.Path, e.Name)))
            {
                WaitReady(Path.Combine(watcher.Path, e.Name));
            }*/
            if (findOldFileInTargetAndChangeHisName(targetFolder, e.OldName, e.Name, ".TXT"))
                return;
            string fullSourcePath = Path.Combine(watcher.Path, e.Name);
            string fullTargetPath = Path.Combine(targetFolder, fileNewName);
            try
            {
                // To copy a file to another location and  
                // overwrite the destination file if it already exists.
                File.Copy(fullSourcePath, fullTargetPath, true);
            }
            catch(FileNotFoundException){}
            deleteAllTmpFilesInWantedFolder(targetFolder);
            // Specify what is done when a file is renamed.
            //System.Diagnostics.Debug.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
            //System.Diagnostics.Debug.WriteLine("File: "+ fullTargetPath +" has been updated");
        }
        private bool sourcePathValidation(bool message)
        {
            if (sourcePath.Text == "" || sourcePath.Text == null)
            {
                if (message)
                {
                    MessageBox.Show("Source path is empty!");
                }
                return false;
            }
            if (!isValidPath(sourcePath.Text))
            {
                if (message)
                {
                    MessageBox.Show("invalide source path");
                }
                return false;
            }
            if (!Directory.Exists(sourcePath.Text))
            {
                if (message)
                {
                    MessageBox.Show("Source Folder does not exist.");
                }
                return false;
            }
            return true;
        }
        private bool targetPathValidation(bool message)
        {
            if (targetPath.Text == "" || targetPath.Text == null)
            {
                if (message)
                {
                    MessageBox.Show("Target path is empty!");
                }
                return false;
            }
            if (!isValidPath(targetPath.Text))
            {
                if (message)
                {
                    MessageBox.Show("invalide target path");
                }
                return false;
            }
            if (targetPath.Text == sourcePath.Text)
            {
                if (message)
                {
                    MessageBox.Show("Source and target paths are identical");
                }
                return false;
            }
            return true;
        }
        private void removeReadOnlyAttr()
        {
            //Target
            FileAttributes targetAttr = File.GetAttributes(targetFolder);
            targetAttr = RemoveAttribute(targetAttr, FileAttributes.ReadOnly);
           
          /*  | FileAttributes.Archive |
                FileAttributes.Compressed | FileAttributes.Device | FileAttributes.Directory);*/
            File.SetAttributes(targetFolder, targetAttr);
            // Source
            FileAttributes sourceAttr = File.GetAttributes(watcher.Path);
            sourceAttr = RemoveAttribute(sourceAttr, FileAttributes.ReadOnly);
            File.SetAttributes(watcher.Path, sourceAttr);
        }
        private static bool findOldFileInTargetAndChangeHisName(string folder, string oldFileName, string newFileName,string fileExtension)
        {
            
            if ( /*newFileName.Substring(0, 1) == "~" */newFileName.Contains("~") || Path.GetExtension(oldFileName) == ".tmp" || Path.GetExtension(newFileName) == ".tmp")
            {
                return false;
            }
            if (Directory.Exists(folder))
            {
                string[] files = Directory.GetFiles(folder);
                foreach (string s in files)
                {
                    deleteTmpFile(s);
                    string fileInDir = Path.GetFileNameWithoutExtension(s);
                    string fileExt = Path.GetExtension(s);
                    if (Path.GetFileNameWithoutExtension(oldFileName) == fileInDir)
                    {
                        string destFile = Path.Combine(folder, newFileName);
                        try
                        {
                            if (!File.Exists(destFile))
                            {
                                //File.Create(destFile);
                                File.Move(s, destFile);
                            }
                            else
                            {
                                MessageBox.Show("update last deleted file with the same file name");
                                File.Delete(destFile);
                                File.Move(s, destFile);
                            }
                        }
                        catch (FileNotFoundException) { }
                        catch (IOException) { }
                        return true;
                    }
                    if (fileExt != fileExtension)
                    {
                        if (Path.GetFileNameWithoutExtension(oldFileName) == fileInDir.Substring(0, fileInDir.Length - 5))
                        {
                            fileInDir = Path.GetFileNameWithoutExtension(newFileName) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt;
                            string destFile = Path.Combine(folder, fileInDir);
                            if (!File.Exists(destFile))
                            {
                                try
                                {
                                   
                                    File.Move(s, destFile);
                                    
                                }
                                catch (UnauthorizedAccessException)
                                {
                                }
                            }
                            else
                            {
                                MessageBox.Show("update last deleted file with the same file name");
                                try
                                {
                                    WaitReady(destFile);
                                    File.Delete(destFile);
                                    File.Move(s, destFile);
                                }
                                catch(FileNotFoundException){}
                            }
 
                            return true;
                        }
                    }
                }
                return false; //file not found.
            }
            return false; //folder does not exist.
        }
        private static bool findFileInFolder(string folder, string FileName,  string fileExtension)
        {
            if (Directory.Exists(folder))
            {
                string[] files = Directory.GetFiles(folder);
                foreach (string s in files)
                {
                    string fileInDir = Path.GetFileNameWithoutExtension(s);
                    string fileExt = Path.GetExtension(s);
                    if (Path.GetFileNameWithoutExtension(FileName) == fileInDir)
                    {
                        return true;
                    }
                    if (fileExt != fileExtension)
                    {
                        if (Path.GetFileNameWithoutExtension(FileName) == fileInDir.Substring(0, fileInDir.Length - 5))
                        {
                            return true;
                        }
                    }
                }
                return false; //file not found.
            }
            return false; //folder does not exist.
        }
        private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
        {
            return attributes & ~attributesToRemove;
        }
        private static void deleteFileFromTargetFile(string fileName)
        {
            string fullTargetPath = Path.Combine(targetFolder, fileName);
            // Delete a file by using File class static method... 
            if (File.Exists(fullTargetPath))
            {
                // Use a try block to catch IOExceptions, to 
                // handle the case of the file already being 
                // opened by another process.
                try
                {
                    System.IO.File.Delete(fullTargetPath);
                }
                catch (System.IO.IOException ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                    return;
                }
            }
        }
        private static bool isValidPath(string path)
        {
            try
            {
                path = path.Replace(@"\\", ":"); // to cancel out c:\\\\test.text
                string temp = Path.GetPathRoot(path); //For cases like: \text.txt
                if (temp.StartsWith(@"\"))
                    return false;
                string pt = Path.GetFullPath(path);
            }
            catch //(Exception NotSupportedException) // catch specific exception here or not if you want
            {
                return false;
            }
            return true;
        }
        private static void copyFileFromSourceToTarget(string fullSourcePath,string fullTargetPath)
        {
            if (!File.Exists(fullTargetPath) )
            {
                File.Create(fullTargetPath).Close();
                if (File.Exists(fullSourcePath))
                {
                    try
                    {
                        /*using (FileStream fs = File.Create(fullSourcePath))
                        {
                            fs.Close();
                        }*/
                        File.Copy(fullSourcePath, fullTargetPath, true);
                        //File.Open(fullSourcePath, FileMode.Open, FileAccess.Write, FileShare.None).Close();
                    }
                    catch (IOException)
                    { 
                        
                    }
                    
                }
            }
            else
            {
                if (File.Exists(fullSourcePath))
                {
                    try
                    {
                        File.Delete(fullTargetPath);
                        File.Copy(fullSourcePath, fullTargetPath, true);
                    }
                    catch (UnauthorizedAccessException)
                    {
                    }
                    catch (IOException) { }
                }
            }
        }
        private static void copyFolderFromSourceToTarget(string fullSourcePath, string fullTargetPath)
        {
            if (!Directory.Exists(fullTargetPath))
            {
                Directory.CreateDirectory(fullTargetPath);
            }
        }
        /// <summary>
        /// Waits until a file can be opened with write permission
        /// </summary>
        public static void WaitReady(string fileName)
        {
            deleteTmpFile(fileName);
            for (int i = 0; i < 4; i++)
            {
                try
                {                                                                                //FileShare.ReadWrite
                    using (Stream stream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
                    {
                        if (stream != null)
                        {
                            
                            System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} ready.", fileName));
                            break;
                        }
                    }
                }
                catch (FileNotFoundException ex)
                {
                    System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
                }
                catch (IOException ex)
                {
                    System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
                }
                catch (UnauthorizedAccessException ex)
                {
                    System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
                }
                System.Threading.Thread.Sleep(3000);
            }
            //File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite).Dispose();
        }
        private static void deleteTmpFile(string tmpFile)
        {
            try
            {
                tmpFile = Path.GetTempFileName();
                // Use temporary file.
            }
            finally
            {
                if (tmpFile != null)
                {
                    try
                    {
                        File.Delete(tmpFile);
                    }
                    catch (IOException)
                    {
                    }
                    catch (UnauthorizedAccessException)
                    {
                    }
                }
            }
        }
        private static void deleteAllTmpFilesInWantedFolder(string folder)
        {
            string[] files = Directory.GetFiles(folder);
            foreach (string s in files)
            {
                if (Path.GetExtension(s) == ".tmp" || s.Contains("~"))
                {
                    File.Delete(s);
                }
                
            }
        }
        
        private void targetPath_TextChanged(object sender, EventArgs e)
        {
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }
    }
}
/*
if (Directory.Exists(targetFolder))
{
    string[] files = Directory.GetFiles(targetFolder);
    foreach (string s in files)
    {
        string fileInDir = Path.GetFileNameWithoutExtension(s);
        fileExt = Path.GetExtension(s);
        if (Path.GetFileNameWithoutExtension(e.OldName) == fileInDir)
                         
        {
            string destFile = Path.Combine(targetFolder, e.Name);
            File.Move(s, destFile);
            return;
        }
        else if (fileExt!=".TXT")
        {
            if (Path.GetFileNameWithoutExtension(e.OldName) == fileInDir.Substring(0, fileInDir.Length - 5))
            {
                fileInDir = Path.GetFileNameWithoutExtension(e.Name) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt;
                string destFile = Path.Combine(targetFolder, fileInDir);
                File.Move(s, destFile);
                return;
            }
        }
    }
}*/