I'm working on making a program give the ability to allow the user to set a target of an active window.
I have two problems with my code, perhaps someone can let me know if the path i've chosen is wrong or there is a better path.
The Window output is only showing 16 characters of the name of the process.
I have the check box listed but don't know how to dynamically assign them to do the change where it will make the TextBox.Text Change.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace Workspace
{
public partial class Form5 : Form
{
string target = File.ReadAllText("./target.txt");
public Form5()
{
InitializeComponent();
//Shows current target in textbox.
string target = File.ReadAllText("./target.txt");
textBox1.Text = target;
// Sets a starting point.
int total_processes = 0;
// Captures proccesses.
Process[] processlist = Process.GetProcesses();
//looks at all proccess to separate with titles.
foreach (Process process in processlist)
{
//calculates total proccess with titles.
if (!String.IsNullOrEmpty(process.MainWindowTitle))
{
total_processes = total_processes + 1;
}
}
// Sets up string array total by number of processes with name.
string[] stringArray = new string[total_processes];
//Names each proccess array.
int loopnum = 0;
foreach (Process process in processlist)
{
if (!String.IsNullOrEmpty(process.MainWindowTitle))
{
stringArray[loopnum] = process.MainWindowTitle;
loopnum = loopnum + 1;
}
}
// Generates # of Radio buttons per proccess with name.
System.Windows.Forms.RadioButton [] radioButtons = new System.Windows.Forms.RadioButton[total_processes];
for (int i = 0; i < total_processes; ++i)
{
radioButtons[i] = new RadioButton();
radioButtons[i].Text = stringArray[i];
radioButtons[i].Location = new System.Drawing.Point(10, 10 + i * 20);
radioButtons[i].CheckedChanged += new EventHandler(this.radioButtons_CheckChanged);
this.Controls.Add(radioButtons[i]);
}
}
private void radioButtons_CheckChanged(object sender, EventArgs e)
{
// Dynamic Check box if checked changes textBox1.Text to radioButtons[i].Text
}
private void button1_Click(object sender, EventArgs e)
{
System.IO.StreamWriter file = new System.IO.StreamWriter("./target.txt");
file.WriteLine(textBox1.Text);
file.Close();
}
}
}
Use ((System.Windows.Forms.RadioButton)sender).Text to get the text property of your radio button:
private void radioButtons_CheckChanged(object sender, EventArgs e)
{
textBox1.Text= ((System.Windows.Forms.RadioButton)sender).Text;
}
When an event raises, the sender cotains a reference to your control that raised the event, so you can access properties of sender control.
Related
I am getting an error that my textfile that is used to create and save my dictionary is being used by another process, I have used Process explorer to no result on what could be using my file. Below is my code and the code throwing this error.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace meade_9_10
{
public partial class Form1 : Form
{
private Dictionary<string, string> names = new Dictionary<string, string>()
{
};
public Form1()
{
//Make sure Form1 is loaded and ran on program open
InitializeComponent();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
//Grab myfile.txt and convert to array
StreamReader sr = new StreamReader("myfile.txt");
string line;
while ((line = sr.ReadLine()) != null)
{
string[] arr = line.Split(',');
int i = 0;
//Add array objects to names dictionary
while (i < arr.Length)
{
names[arr[i]] = arr[i + 1];
i += 2;
}
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
//declare variables
string nameAdd;
string emailAdd;
//Put user input into variable
nameAdd = txtNameAdd.Text;
emailAdd = txtEmailAdd.Text;
//Declare new dictionary key pair as user input
names[emailAdd] = nameAdd;
//clear the textbox controls
txtNameAdd.Text = "";
txtEmailAdd.Text = "";
}
private void btnDelete_Click(object sender, EventArgs e)
{
string emailDel;
emailDel = txtEmailDel.Text;
//Remove key pair that is inputted by user
names.Remove(emailDel);
}
private void btnChange_Click(object sender, EventArgs e)
{
//Declare variables
string emailDel;
string nameAdd;
string emailAdd;
//Assign values to variables
emailDel = txtEmailChange.Text;
nameAdd = txtNameNew.Text;
emailAdd = txtEmailNew.Text;
//Delete the user inputted email to change
names.Remove(emailDel);
//Add the new key pair values to dictionary
names.Add(emailAdd, nameAdd);
}
private void btnLookUp_Click(object sender, EventArgs e)
{
//Declare variable
string email = txtEmail.Text;
//If statement to check if dictionary contains key value
if (names.ContainsKey(email))
{
outputName.Text = names[email];
outputEmail.Text = email;
}
}
private void btnExit_Click(object sender, EventArgs e)
{
//writes the names dictioanry to array inside text file
File.WriteAllLines("myfile.txt",
names.Select(x => x.Key + "," + x.Value ).ToArray());
//Closes the program
this.Close();
}
}
}
The part of my code giving me the error
System.IO.IOException: 'The process cannot access the file 'C:\Users\Adrian\Desktop\ALL SCHOOL FILES\Fall 2021\C#\meade_9_10\bin\Debug\myfile.txt' because it is being used by another process.'
is
names.Select(x => x.Key + "," + x.Value ).ToArray());
I just cannot figure out what process is using my text file that is breaking this program, it was working earlier and I haven't made any changes except for removing redundant white space between functions.
Try using the
StreamReader.Close() method after your innermost while loop:
Closes the StreamReader object and the underlying stream, and releases any system resources associated with the reader.
Alternatively, you can use the using statement:
Provides a convenient syntax that ensures the correct use of IDisposable objects.
I am able to read my text file however when I go and click my edit button it moves all the current rows in the text file to the top row and doesn't update anything. Also how would I go about adding a row to the text file without moving the rows?
private void btnEdit_Click(object sender, EventArgs e)
{
BugTrackers cs = Bugs[index];
// DisplayBugs();
// Update datafile
UpdateBugsInfo();
}
private void UpdateBugsInfo()
{
if (lstBugs.SelectedIndex > -1)
{
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt", false);
for (int i = 0; i <= Bugs.Count - 1; i++)
{
sw.Write(Bugs[i].BugsName);
sw.Write(",");
sw.Write(Bugs[i].BugsDesc);
}
sw.Close();
}
}
The StreamWriter object you are creating is having wrong parameter value for append. You need to set that as true OR just remove that parameter since it’s default value is true.
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt", true);
OR
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt");
Here is the link from Microsoft.
https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.-ctor?view=netframework-4.7.2#System_IO_StreamWriter__ctor_System_String_System_Boolean_
You are also not using the using statement, which ensures the StreamWriter object is removed from memory when no longer needed. Please go through this article to understand it better.
https://www.dotnetperls.com/streamwriter
Hope this helps!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace BugTracker
{
struct BugTrackers
{
public string BugsName;
public string BugsDesc;
}
public partial class YoungKidsBugTracker : Form
{
// Field to hold a list of BugTrackers objects
private List<BugTrackers> Bugs = new List<BugTrackers>();
private int index; // index fo selected bugs in combobox
public YoungKidsBugTracker()
{
InitializeComponent();
}
private void ReadFile()
{
try
{
//Declare a varialble to hold Bugs Name
StreamReader inputFile; // To Read the file
string line; // To hold a line from the file
// Create an instance of the Bug Accounts
BugTrackers entry = new BugTrackers();
// Create a delimeter array
char[] delim = { ',' };
// Open the file and get a StreamReader Object
inputFile = File.OpenText("smBugs.txt");
// Read the file's contents
while (!inputFile.EndOfStream)
{
// Read a line from the file
line = inputFile.ReadLine();
// Tokenize the line
string[] tokens = line.Split(delim);
// Stores the tokens in the entry object
entry.BugsName = tokens[0];
entry.BugsDesc = tokens[1];
// Add the entry object to the combobox
Bugs.Add(entry);
}
// Close the File
inputFile.Close();
}
catch (Exception ex)
{
// Display an error message
MessageBox.Show(ex.Message);
}
}
private void lstBugs_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the index of the sselected item
index = lstBugs.SelectedIndex;
// Display Bug Information
DisplayBugs();
}
private void DisplayBugs()
{
//Show Data
txtBugsName.Text = Bugs[index].BugsName;
rtxtBugDesc.Text = Bugs[index].BugsDesc.ToString();
}
private void YoungKidsBugTracker_Load(object sender, EventArgs e)
{
// Read the Bugs.txt file
ReadFile();
// Display Bug Information
BugNameDisplay();
}
private void btnEdit_Click(object sender, EventArgs e)
{
BugTrackers cs = Bugs[index];
// DisplayBugs();
// Update datafile
UpdateBugsInfo();
}
private void UpdateBugsInfo()
{
if (lstBugs.SelectedIndex > -1)
{
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt");
for (int i = 0; i <= Bugs.Count - 1; i++)
{
sw.Write(Bugs[i].BugsName);
sw.Write(",");
sw.WriteLine(Bugs[i].BugsDesc);
// sw.Write(Environment.NewLine);
}
sw.Close();
}
}
private void BugNameDisplay()
{
// Display the list of Bug Names in the List Control
foreach (BugTrackers entry in Bugs)
{
lstBugs.Items.Add(entry.BugsName );
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
}
}
}
This is the code in its entirety. I have a list box with 2 text boxes to hold the bug name and description. I have 3 buttons Add, Edit and Delete. If an item is selected from the listbox it will display the bugname and description. If the entry needs updated changes are made and will change the information needed. If a new bug is added you would use the add button same for the delete button.
I am creating a clock for clocking into a business. Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
String Code;
String Name;
String InOut;
Boolean Luke = true;
String csvPath = "C:/users/luke/documents/C#/csvProject.csv";
StringBuilder Header = new StringBuilder();
StringBuilder csvData = new StringBuilder();
public Form1()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
TopMost = true;
Header.AppendLine("Timestamp, Name");
File.AppendAllText(csvPath, Header.ToString());
textBox1.Font = new Font("Arial", 30, FontStyle.Bold);
}
private void button_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
Code = Code + button.Text;
textBox1.Text = Code;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
FormBorderStyle = FormBorderStyle.Sizable;
WindowState = FormWindowState.Normal;
TopMost = false;
}
}
private void button13_Click(object sender, EventArgs e)
{
//clear
Code = null;
textBox1.Text = Code;
}
private void button10_Click(object sender, EventArgs e)
{
//in or out
DateTime timeStamp = DateTime.Now;
if (Code == "123")
{
Name = "Luke";
}
Button button = (Button)sender;
csvData.AppendLine(timeStamp + "," + Name + "," + button.Text);
File.AppendAllText(csvPath, csvData.ToString());
Code = null;
textBox1.Text = Code;
}
private void button14_Click(object sender, EventArgs e)
{
}
}
}
My layout consists of a number pad, in button, and out button. When the user presses the in button after they enter their code, the program should write in the CSV file: Timestamp, Name, In. When I tested the code by clocking in, the program writes one row correctly. When I clock in and then clock out, it creates two rows of me clocking in and one row of me clocking out. I was wondering if anyone could help me find what is going wrong in the code. Thanks.
You need to empty csvData after writing it to the file.
I have this Code in Form1. Im doing a search for xml files. When i find them im using listBox1 selected index changed event and i want to do that when i select item in the lixtBox it will consider it as a file will parse it content and show me the parsed content.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using System.IO;
using System.Collections;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
DirectoryInfo dirinf = new DirectoryInfo(#"C:\");
List<FileSystemInfo> fsi = new List<FileSystemInfo>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
button1.Enabled = false;
}
private void ParseAndDisplayXml(string filename)
{
XDocument document = XDocument.Load(filename);
var list = document.Root.Elements("Message")
.Select(
e => new
{
Date = e.Attribute("Date").Value.ToString(),
Time = e.Attribute("Time").Value.ToString(),
Text = e.Element("Text").Value.ToString()
}
);
string result="";
foreach (var item in list)
{
result += string.Format("Date--{0},Time--{1},Text--{2}", item.Date, item.Time, item.Text + Environment.NewLine);
}
}
public void Search(string strExtension,
DirectoryInfo di,
List<FileSystemInfo> pResult)
{
try
{
foreach (FileInfo fi in di.GetFiles())
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => label2.Text = fi.Name));
}
if (fi.Name == "MessageLog.xsl")
{
foreach (FileInfo fii in di.GetFiles())
{
if (fii.Extension == strExtension)
pResult.Add(fii);
}
if (InvokeRequired)
{
BeginInvoke(new Action(() => label4.Text = pResult.Count.ToString() + Environment.NewLine));
}
}
}
foreach (DirectoryInfo diChild in di.GetDirectories())
Search(strExtension, diChild, pResult);
}
catch (Exception e)
{
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Search(".xml", dirinf, fsi);
backgroundWorker1.ReportProgress(100);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
for (int i = 0; i < fsi.Count; i++)
{
listBox1.Items.Add(fsi[i].Name + Environment.NewLine);
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label2.Text = listBox1.SelectedItem.ToString();
}
}
}
Im starting the search from C:\
Then when the search so over completed im adding the items it found to the listBox1.
For example now in my listBox1 i have 4 files:
danny.xml
adi.xml
sharon.xml
yoval.xml
In the selectedindexchanged i added option so the user can move between the items.
Now what i want to do is when the user select some index for example index [1] in the listBox and only if he clicked enter with the keyboard or clicked with the mouse left click it will call/use the function: ParseAndDisplayXML.
Then it will parse the selected index wich need to be translated to a file so in the backgroundWorker1_RunWorkerCompleted event i madding the files to the listBox as items but only with the names of the files. If i did .FullName instead .Name it was adding the files names with the directories too.
So i need somehow to get the FullName of the files in the completed event i think then when selecting one of the FullName items to parse it and display it in the listBox.
The parse function should take the specific content from the xml files and it worked i checked this function before alone.
The problem is how do i make that the user will select the index by click/key enter and how to parse and display it ?
When you add something to a listbox.
It expects an object, and sets the text to object.ToString()
e.g.
MyListBox.Add(100);
Would box 100 and display "100"
Couldn't find if FileSystemInfo's ToString() method has been overridden but first thing to try would be
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
// newline is unnecesary and you should be using foreach
foreach(FileSystemInfo f in fsi)
{
listBox1.Items.Add(f);
}
}
// display full name of file
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label2.Text = ((FileSystemInfo)listBox1.SelectedItem).Fullname;
}
If FileSystemInfo.ToString() doesn't return Name, there are a few ways to deal with that.
If you don't want to hold on to the FileSystemInfo instances, we can deal with that too.
I'm trying to make an auto shutdown application that will shutdown the computer when multiple processes close.
Example: The user has a checklistbox that lists all of the current running processes. The user check marks all desired processes that they wish to monitor.Once all of these processes close then the computer is supposed to shutdown. I am having trouble doing this, I don't know how to make the program check to see if the checked process items have closed. Here is some code that I have right now, I would appreciate all the help anyone can give me.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int counter;
Process[] p = Process.GetProcesses();
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 100;
foreach (Process plist in p)
{
checkedListBox1.Items.Add(plist.ProcessName);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
counter = 0;
checkedListBox1.Items.Clear();
Process[] p = Process.GetProcesses();
foreach (Process plist in p)
{
checkedListBox1.Items.Add(plist.ProcessName);
counter = counter + 1;
}
if (counter == 0)
{
MessageBox.Show("works");
}
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
timer1.Start();
}
}
}
Thanks,
-Angel Mendez
Assuming you have a List<string> representing your checkboxes, try:
List<string> checkProcs = new List<string>(); // All monitored process names
var allProcesses = Process.GetProcesses().Select(p => p.ProcessName);
// Now use:
allProcesses.Except(checkProcs)
That should give a list of monitored processes that don't exist any more.
using System;
using System.Collections;
using System.Windows.Forms;
using System.Diagnostics;
namespace testprocessapp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Process[] p = Process.GetProcesses();
timer1.Interval = 10000;
checkedListBox1.Items.Clear();
foreach (Process plist in p)
{
checkedListBox1.Items.Add(plist.ProcessName);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
int counter = 0;
Process[] p = Process.GetProcesses();
foreach (Process process in p)
{
foreach (var item in checkedListBox1.Items)
{
if (item.ToString() == process.ProcessName)
{
counter = counter + 1;
}
}
}
MessageBox.Show(counter == 0 ? "Your process has been terminated" : "Your process is still there");
}
private void button1_Click(object sender, EventArgs e)
{
ArrayList arrayList = new ArrayList();
foreach (var checkedItem in checkedListBox1.CheckedItems)
{
arrayList.Add(checkedItem);
}
checkedListBox1.DataSource = arrayList;
//button1.Enabled = false;
button1.Text = "Monitoring...";
timer1.Start();
}
}
}
I have now created a replica of the application. This code works.