FileSystemWatcher Not Observing Changes in Program Files (x86) Folder - c#

I'm trying to write a simple C# service to watch a folder and notify my app when that folder is updated. I found some great examples using FileSystemWatcher, but it does not work at all when I set the path to a folder beneath c:\Program Files (x86).
My code works fine when I set the path to other folders. I thought perhaps it was failing to read the path because of the parenthesis in the name. I tried naming a folder in root of C drive and used parenthesis and that did not work either. I'm not sure what exactly the issue is here or how to workaround it. Is it a permissions issue? Is there some way to escape characters in the path even though they are technically "legal"?
private void InitializeComponent()
{
this.watchReflectAssetFolder = new System.IO.FileSystemWatcher();
((System.ComponentModel.ISupportInitialize)(this.watchReflectAssetFolder)).BeginInit();
//
// watchReflectAssetFolder
//
this.watchReflectAssetFolder.EnableRaisingEvents = true;
this.watchReflectAssetFolder.IncludeSubdirectories = true;
this.watchReflectAssetFolder.Path = "C:\\Program Files (x86)\\Reflect Systems\\ReflectDistributor\\Cache\\WEBCASTS";
this.watchReflectAssetFolder.Changed += new System.IO.FileSystemEventHandler(this.watchReflectAssetFolder_Changed);
//
// LevisAssetCopyService
//
this.ServiceName = "LevisAssetCopyService";
((System.ComponentModel.ISupportInitialize)(this.watchReflectAssetFolder)).EndInit();
}
private void watchReflectAssetFolder_Changed(object sender, System.IO.FileSystemEventArgs e)
{
string ChangeType = e.ChangeType.ToString();
//write a log entry for the appropriate changetype.
levisLog.WriteEntry("File Watch Type: " + ChangeType);
if (ChangeType == "Created")
{
levisLog.WriteEntry("File: " + e.FullPath + " " + e.Name + " Created");
}
else if (ChangeType == "Deleted")
{
levisLog.WriteEntry("File: " + e.FullPath + " " + e.Name + " Deleted");
}
else if (ChangeType == "Changed")
{
levisLog.WriteEntry("File: " + e.FullPath + " " + e.Name + " Changed");
}
}

Related

C# Get files Outlook Attachments single-multiple selected files Win 7, Win 10

I have re-edited my question since the problem lies elsewhere.
I have this piece of code to drop the files from outlook (single or multiple) at specific win form. On windows 7 stations the copy is made, but on windows 10 cannot get the list of filename from class.
public class OutlookDataObject : System.Windows.Forms.IDataObject
Class shown on this post
This class is working on Working code for win 7 but no filename return on windwos 10. This huge class is way over my understanding.
There is a simple way to get from outlook the selected attachements to prepare them to drop ?
private void btn_Home_DragDrop(object sender, DragEventArgs e)
{
bool debug = true;
if (debug) { txt_FileInfo.AppendText("Entering drop method " + Environment.NewLine); }
folderBrowserDialog1.SelectedPath = LastSelectedFolder.GlobalVar;
if (debug)
{ txt_FileInfo.AppendText("Get last path " + Environment.NewLine); }
folderBrowserDialog1.Description = "Drop the files";
if (debug)
{ txt_FileInfo.AppendText("Show folder dialog " + Environment.NewLine); }
if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
{
return;
}
LastSelectedFolder.GlobalVar = folderBrowserDialog1.SelectedPath.ToString();
if (debug)
{ txt_FileInfo.AppendText("Path is selected " + LastSelectedFolder.GlobalVar + Environment.NewLine); }
string[] fileNames = null;
if (debug)
{ txt_FileInfo.AppendText("Prepare to transfer " + Environment.NewLine); }
if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
{
if (debug)
{ txt_FileInfo.AppendText("DataFormats.FileDrop " + Environment.NewLine); }
fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string fileName in fileNames)
{
// do what you are going to do with each filename
string destinationFile = Path.Combine(folderBrowserDialog1.SelectedPath, Path.GetFileName(fileName));
if (debug)
{ txt_FileInfo.AppendText("Destination File " + destinationFile + Environment.NewLine); }
if (Operation.CopyFile(fileName, destinationFile, ci))
{
txt_FileInfo.AppendText("File have been copied to " + destinationFile + Environment.NewLine);
}
}
}
else if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
if (debug)
{ txt_FileInfo.AppendText("FileGroupDescriptor " + Environment.NewLine); }
OutlookDataObject dataObject = new OutlookDataObject(e.Data);
string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");
for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
{
if (debug)
{ txt_FileInfo.AppendText("Files in attachement " + filenames[fileIndex] + Environment.NewLine); }
string path = Path.GetTempPath();
// put the zip file into the temp directory
string theFile = path + filenames[fileIndex].ToString();
// create the full-path name
if (debug)
{ txt_FileInfo.AppendText("Get temp Path " + theFile + Environment.NewLine); }
//
// Second step: we have the file name.
// Now we need to get the actual raw
// data for the attached file and copy it to disk so we work on it.
//
// get the actual raw file into memory
MemoryStream ms = (MemoryStream)e.Data.GetData(
"FileContents", true);
// allocate enough bytes to hold the raw data
byte[] fileBytes = new byte[ms.Length];
// set starting position at first byte and read in the raw data
ms.Position = 0;
ms.Read(fileBytes, 0, (int)ms.Length);
// create a file and save the raw zip file to it
FileStream fs = new FileStream(theFile, FileMode.Create);
fs.Write(fileBytes, 0, (int)fileBytes.Length);
fs.Close(); // close the file
FileInfo tempFile = new FileInfo(theFile);
// always good to make sure we actually created the file
if (tempFile.Exists == true)
{
// for now, just delete what we created
string fileName = tempFile.FullName;
string destinationFile = Path.Combine(folderBrowserDialog1.SelectedPath, Path.GetFileName(fileName));
if (debug)
{ txt_FileInfo.AppendText("destinationFile " + destinationFile + Environment.NewLine); }
if (debug)
{ txt_FileInfo.AppendText("Prepare to copy " + destinationFile + Environment.NewLine); }
if (Operation.CopyFile(fileName, destinationFile, ci))
{
txt_FileInfo.AppendText("File have been copied to " + destinationFile + Environment.NewLine);
}
else
{
if (debug)
{ txt_FileInfo.AppendText("Copy failed " + " Source " + fileName + " Destination " + destinationFile + Environment.NewLine); }
}
tempFile.Delete();
if (debug)
{ txt_FileInfo.AppendText("Delete temp file " + tempFile + Environment.NewLine); }
}
else
{ Trace.WriteLine("File was not created!"); }
// catch (Exception ex)
//{
// Trace.WriteLine("Error in DragDrop function: " + ex.Message);
// // don't use MessageBox here - Outlook or Explorer is waiting !
//}
}
}
}
I will replay here quote from here. For above class to work on win 8 + couple of line to be changed (from int to long)
from:
IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
to
IntPtr fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
from:
fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
to
fileDescriptorPointer = (IntPtr)((long)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
Use this:
MemoryStream ms = (MemoryStream)dataObject.GetData("FileContents", fileIndex);
Instead of this:
MemoryStream ms = (MemoryStream)dataObject.GetData("FileContents", true);
So it parses every files.
EDIT:
Actually, it doesn't work neither unless program is compiled in Debug rather than Release... It will only work in Debug for some reason

Permissions on a folder

I have been looking for some time now and have not been able to find this. How can I set my program up to write or update a file from multiple users but only one group is allowed to open the read what is in the folder?
class Log_File
{
string LogFileDirectory = #"\\server\boiseit$\TechDocs\Headset Tracker\Weekly Charges\Log\Log Files";
string PathToXMLFile = #"\\server\boiseit$\scripts\Mikes Projects\Headset-tracker\config\Config.xml";
string AdditionToLogFile = #"\Who.Did.It_" + DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Year + ".txt";
XML XMLFile = new XML();
public void ConfigCheck()
{
if (!File.Exists(PathToXMLFile))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
}
}
public void CreateLogFile()
{
if (Directory.GetFiles(LogFileDirectory).Count() == 0)
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
else if (!File.Exists(XMLFile.readingXML(PathToXMLFile)))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
else
{
FileInfo dateOfLastLogFile = new FileInfo(XMLFile.readingXML(PathToXMLFile));
DateTime dateOfCreation = dateOfLastLogFile.CreationTime;
if (dateOfLastLogFile.CreationTime <= DateTime.Now.AddMonths(-1))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
}
}
public void CreateFileOrAppend(string whoDidIt)
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetStore((IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.User), null, null))
{
using (StreamWriter myWriter = new StreamWriter(XMLFile.readingXML(PathToXMLFile), true))
{
if (whoDidIt == "")
{
}
else
{
myWriter.WriteLine(whoDidIt);
}
}
}
}
This is my path where it needs to go. I have the special permission to open and write to the folder but my co workers do not. I am not allow to let them have this permission.
If I where to set up a database how would i change this code
LoggedFile.CreateFileOrAppend(Environment.UserName.ToUpper() + "-" + Environment.NewLine + "Replacement Headset To: " + AgentName + Environment.NewLine + "Old Headset Number: " + myDatabase.oldNumber + Environment.NewLine + "New Headset Number: " + HSNumber + Environment.NewLine + "Date: " + DateTime.Now.ToShortDateString() + Environment.NewLine);
I need it to pull current user, the agents name that is being affected the old headset and the new headset, and the time it took place.
While you create file, you have to set access rules to achieve your requirements. .
File.SetAccessControl(string,FileSecurity)
The below link has example
https://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol(v=vs.110).aspx
Also the "FileSecurity" class object, which is an input parameter, has functions to set access rules, including group level control.
Below link has example
https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesecurity(v=vs.110).aspx
This question will be opened under a new question since I am going to take a different route for recording the data I need Thank you all for the help

File transfer error

I'm making an application, and at some point it does the following: Checks if a file that will be created, already exists in a directory (output), if it exists, he sends for the Errors folder, if not, it sends to the output folder. But comes a point where the program transfers the file to the folder errors, and buga, saying that the file does not exist, for example, he just transfer it t file (49) .png, and he again read the same file ! Funny is only in some cases it
if (System.IO.File.Exists(entrada + "t (" + i + ").png")){
string[] datas1 = Spire.Barcode.BarcodeScanner.Scan(#"C:\\QTRACK\\Entrada\\PNG\\t (" + i + ").png");
this.textBox1.Text = datas1[0];
foreach (string code in datas1)
{
DirectoryInfo exit = new DirectoryInfo(#"C:/QTRACK/Erro/");
FileInfo[] teste = exit.GetFiles("*.png");
x = teste.Length +1;
for (c = x; c <= 1000000000; c++)
{
if (System.IO.File.Exists(saida + code + ".png"))
{
System.IO.File.Move(entrada.ToString() + "t (" + i + ").png", erro + "e" + c + ".png");
}
else
{
System.IO.File.Move(entrada.ToString() + "t(" + i + ").png", saida + code + ".png");
}
}
}
}
else
{
}
}
}
It gives the error FileNotFoundExecption, however, was himself who changed the file and're trying to change again. Please help.

C# File only copies once

With my filesystemwatcher I check when a file needs to be copied to a 2nd directory. Everytime. So for example I put in test.txt in dir1 and it automatically copies or cuts the file to dir2. Now when I put in test2.txt in dir1, nothing happens. Why is nothing happening the 2nd time?
Edit: It's a Windows Service
Here is my code:
private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
variable_reset();
cut_copy = ConfigurationManager.AppSettings[#"cut"];
logger("File created> " + e.FullPath + " -Date:" + DateTime.Now);
filepath = Path.Combine(source, e.Name);
name = Path.GetFileNameWithoutExtension(filepath);
extension = Path.GetExtension(e.FullPath);
size = e.Name.Length;
strSelectCmd = "INSERT INTO files (name,size,last_edit,extension) VALUES('" + name + "','" + size + "',now(),'" + extension + "')";
readquery = "select * from files where name='" + name + "'";
Mysql();
postgresql();
Record();
if (string.IsNullOrEmpty(filename) == false)
{
if (Directory.Exists(e.FullPath))
{
copyfolder();
Directory.CreateDirectory(target);
}
else
{
if (WaitForFileAvailable(e.FullPath, TimeSpan.FromSeconds(10)))
{
var file = Path.Combine(source, e.Name);
var copy_file = Path.Combine(target, e.Name);
var destination = Path.Combine(target, Path.ChangeExtension(source, Path.GetExtension(source)));
if ((String.Compare(cut_copy, "cut"))==0)
{
if (File.Exists(file))// Check to see if the file exists.
{ //If it does delete the file in the target and copy the one from the source to the target.
File.Delete(copy_file);
}
File.Move(e.FullPath, Path.Combine(target, e.Name));
}
if ((String.Compare(cut_copy, "copy"))==0)
{
if (File.Exists(file))// Check to see if the file exists.
{ //If it does delete the file in the target and copy the one from the source to the target.
File.Delete(copy_file);
}
File.Copy(e.FullPath, Path.Combine(target, e.Name));
}
}
else // The file failed to become available within 10 seconds.
{
logger("Copy has failed reason: File is being used by another program");
}
}
}
else
{
query = "INSERT INTO files (name,size,last_edit,extension) VALUES('" + name + "','" + size + "',now(),'" + extension + "')";
Mysql();
}
}

How to read a textbox from a thread other than the one it was created on?

I am fairly new to C# and I have written several functioning programs, but all of them have been single thread applications. This is my first multi-threaded application and I am struggling to resolve this "Cross-thread operation not valid: Control 'cbLogType' accessed from a thread other than the one it was created on" error. My application searches Windows Event viewer for a user defined Event ID in a user defined Event Log Source(cbLogType). I am using a backgroundworker process to do all the work and I am using the worker.reportprogress to update a label, however, I receive the above error when debugging. I have tried several Invoke methods, but none seem to resolve my error. I have also tried removing the combobox and setting the Log Source directly in the code, which works to an extent, but still fails. I have included my code and any help would be greatly appreciated. I suspect that I might not be using the Invoke method correctly. Thanks in advance!
CODE:
private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
{
if (File.Exists(#"C:\Events.log"))
MessageBox.Show("File 'Events.log' already exists. All new data will be appended to the log file!", "Warning!");
string message = string.Empty;
string eventID = (tbEventID.Text);
string text;
EventLog eLog = new EventLog();
Invoke((MethodInvoker)delegate() { text = cbLogType.Text; });
eLog.Source = (this.cbLogType.Text); // I am receiving the error here
eLog.MachineName = ".";
int EventID = 0;
string strValue = string.Empty;
strValue = tbEventID.Text.Trim();
//string message = string.Empty;
EventID = Convert.ToInt32(strValue); // Convert string to integer
foreach (EventLogEntry entry in eLog.Entries)
{
int entryCount = 1;
if (cbDateFilter.Checked == true)
{
if (entry.TimeWritten > dtPicker1.Value && entry.TimeWritten < dtPicker2.Value)
if (entry.InstanceId == EventID)
message = "Event entry matching " + (tbEventID.Text) + " was found in " + (cbLogType.Text);
using (StreamWriter writer = new StreamWriter(#"C:\Events.log", true))
writer.WriteLine("EventID: " + entry.InstanceId +
"\r\nDate Created: " + entry.TimeWritten +
"\r\nEntry Type: " + entry.EntryType +
"\r\nMachinename: " + entry.MachineName +
"\r\n" +
"\r\nMessage: " + entry.Message +
"\r\n");
if (entry.InstanceId != EventID)
message = "No event ids matching " + (tbEventID.Text) + " was found in " + (cbLogType.Text);
}
else
{
if (cbDateFilter.Checked == false)
{
if (entry.InstanceId == EventID)
using (StreamWriter writer = new StreamWriter(#"C:\Events.log", true))
writer.WriteLine("EventID: " + entry.InstanceId +
"\r\nDate Created: " + entry.TimeWritten +
"\r\nEntry Type: " + entry.EntryType +
"\r\nMachinename: " + entry.MachineName +
"\r\n" +
"\r\nMessage: " + entry.Message +
"\r\n");
else if (entry.InstanceId != EventID)
message = "No event ids matching " + (tbEventID.Text) + " was found in " + (cbLogType.Text);
}
bgWorker1.ReportProgress((entryCount) * 10, message);
entryCount++;
}
}
}
}
private void bgWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
lblStat.Text = e.UserState.ToString();
}
You're accessing cbLogType in a non-UI thread.
Change to
eLog.Source = text;

Categories

Resources