S
Sefner
Hey everyone. I have a program that watches a .txt log file from a chat
client or a game and based on each line, triggers events. One thing I
am trying to do is send the contents of a text file to the clipboard,
then paste it to the program... Here is the code I am using...
namespace Project1
{
public partial class Form1 : Form
{
//Variable, fileStreams, FileReaders, Voice thing, and Regexes go here!
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
InitializeComponent();
}
//opens FileStream after making sure the user has opened a file
public void StreamCaller(object sender, EventArgs e)
{
if (logName!=null)
{
FileStreamer();
}
else
{
textBox1.Text = "No Log Selected";
}
}
//opens the FileStream, StreamReader, and FileSystemWatcher.
public void FileStreamer()
{
fs = new FileStream(logName, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
sr = new StreamReader(fs);
watch = new FileSystemWatcher(logDir, "*.txt");
if (newsDialog.FileName.Length > 2)
// if it exists
{
newsFile = newsDialog.FileName;
newsStream = new FileStream(newsFile, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
newsReader = new StreamReader(newsStream);
}
else
{
}
//FileSystemWatcher stuff...
watch.IncludeSubdirectories = true;
watch.EnableRaisingEvents = true;
watch.NotifyFilter = NotifyFilters.Size;
watch.Changed += new FileSystemEventHandler(OutputIt);
//Sets position of Stream to the end. This is so it only reads new
lines.
fs.Position = fs.Length;
textBox1.Text = "Watching...";
button2.Enabled = true;
}
//This method is called when the log file is modified. It uses Regexes
and the Contains() //method to see if the new line in the file matches
anything the should trigger something.
public void OutputIt(object source, FileSystemEventArgs e)
{
//Reads the new line.
string compare = sr.ReadToEnd();
//if statements for different things go here...
//This is the line that gives me trouble. the Clipboard.SetText() line
more specifically.
//It throws the "Current thread must be set to single thread apartment
(STA) mode before //OLE calls can be made. Ensure that your Main
function has STAThreadAttribute marked on //it." Exception. But notice
I do have the attribute on Main()
//if the line contains the string "/news" - which is the command to
bring up the news - the
//text file is read to the end, copied to clipboard, then pasted with
SendKeys. The Stream
//then goes back to the beginning of the text file and waits for the
next command.
else if (compare.Contains("/news"))
{
newsOutput = newsReader.ReadToEnd();
Clipboard.SetText(newsOutput, TextDataFormat.Text);
SendKeys.SendWait("^v");
newsStream.Position = 0;
}
else
{
}
}
//Closes all streams when a button is clicked.
public void EndStream(object sender, EventArgs e)
{
watch.EnableRaisingEvents = false;
textBox1.Text = "Not Watching";
button2.Enabled = false;
fs.Close();
sr.Close();
watch.EnableRaisingEvents = false;
newsStream.Close();
newsReader.Close();
}
//opens file dialogs so user can chose files.
private void openNewsDialog(object sender, EventArgs e)
{
newsDialog.ShowDialog();
}
private void openLogDialog(object sender, EventArgs e)
{
logDialog.ShowDialog();
}
//sets the files the user chose to strings so the Streams can open
them.
private void logSetter(object sender, CancelEventArgs e)
{
logName = logDialog.FileName;
fi = new FileInfo(logName);
logDir = fi.DirectoryName;
}
}
}
Thanks for all your help!
client or a game and based on each line, triggers events. One thing I
am trying to do is send the contents of a text file to the clipboard,
then paste it to the program... Here is the code I am using...
namespace Project1
{
public partial class Form1 : Form
{
//Variable, fileStreams, FileReaders, Voice thing, and Regexes go here!
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
InitializeComponent();
}
//opens FileStream after making sure the user has opened a file
public void StreamCaller(object sender, EventArgs e)
{
if (logName!=null)
{
FileStreamer();
}
else
{
textBox1.Text = "No Log Selected";
}
}
//opens the FileStream, StreamReader, and FileSystemWatcher.
public void FileStreamer()
{
fs = new FileStream(logName, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
sr = new StreamReader(fs);
watch = new FileSystemWatcher(logDir, "*.txt");
if (newsDialog.FileName.Length > 2)
// if it exists
{
newsFile = newsDialog.FileName;
newsStream = new FileStream(newsFile, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
newsReader = new StreamReader(newsStream);
}
else
{
}
//FileSystemWatcher stuff...
watch.IncludeSubdirectories = true;
watch.EnableRaisingEvents = true;
watch.NotifyFilter = NotifyFilters.Size;
watch.Changed += new FileSystemEventHandler(OutputIt);
//Sets position of Stream to the end. This is so it only reads new
lines.
fs.Position = fs.Length;
textBox1.Text = "Watching...";
button2.Enabled = true;
}
//This method is called when the log file is modified. It uses Regexes
and the Contains() //method to see if the new line in the file matches
anything the should trigger something.
public void OutputIt(object source, FileSystemEventArgs e)
{
//Reads the new line.
string compare = sr.ReadToEnd();
//if statements for different things go here...
//This is the line that gives me trouble. the Clipboard.SetText() line
more specifically.
//It throws the "Current thread must be set to single thread apartment
(STA) mode before //OLE calls can be made. Ensure that your Main
function has STAThreadAttribute marked on //it." Exception. But notice
I do have the attribute on Main()
//if the line contains the string "/news" - which is the command to
bring up the news - the
//text file is read to the end, copied to clipboard, then pasted with
SendKeys. The Stream
//then goes back to the beginning of the text file and waits for the
next command.
else if (compare.Contains("/news"))
{
newsOutput = newsReader.ReadToEnd();
Clipboard.SetText(newsOutput, TextDataFormat.Text);
SendKeys.SendWait("^v");
newsStream.Position = 0;
}
else
{
}
}
//Closes all streams when a button is clicked.
public void EndStream(object sender, EventArgs e)
{
watch.EnableRaisingEvents = false;
textBox1.Text = "Not Watching";
button2.Enabled = false;
fs.Close();
sr.Close();
watch.EnableRaisingEvents = false;
newsStream.Close();
newsReader.Close();
}
//opens file dialogs so user can chose files.
private void openNewsDialog(object sender, EventArgs e)
{
newsDialog.ShowDialog();
}
private void openLogDialog(object sender, EventArgs e)
{
logDialog.ShowDialog();
}
//sets the files the user chose to strings so the Streams can open
them.
private void logSetter(object sender, CancelEventArgs e)
{
logName = logDialog.FileName;
fi = new FileInfo(logName);
logDir = fi.DirectoryName;
}
}
}
Thanks for all your help!