היי,
להלן פתרון תרגיל הבית שחברת גאגא נותנת לאחר מרכז ההערכה ב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();
}
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;
}
}
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");
}
}
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;
}
}
}
}*/