InvalidOperationException using PFX w/ Windows Forms - c#

I have two exceptions here. Not sure why they occur because I use Form.Invoke to run UI updates on the UI thread. So first,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Xml;
using System.Windows.Forms;
namespace Toplr
{
using System.Collections.Specialized;
using System.Xml.XPath;
using System.Xml.Linq;
using System.Text;
using System.ServiceModel.Web;
using System.ServiceModel.Syndication;
using System.Net;
using System.Web;
using System.Xml.Schema;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
public partial class ToplrForm : Form
{
private readonly Uri SearchBase = new Uri(#"http://www.twine.com/feed/atom/entries/");
private readonly UriTemplate SearchTemplate = new UriTemplate(#"search?type={type}&author={author}");
public ToplrForm()
{
InitializeComponent();
Exiting = false;
TaskContext = new TaskManager();
Items = new AsyncBindingList<Twine>(this);
twineBindingSource.DataSource = Items;
}
private void ToplrForm_Load(object sender, EventArgs e)
{
}
private readonly TaskManager TaskContext;
private readonly AsyncBindingList<Twine> Items;
private bool Exiting;
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Close()");
Close();
}
private void ToplrForm_FormClosing(object sender, FormClosingEventArgs e)
{
MessageBox.Show("Exiting = tru");
Exiting = true;
//TaskContext.Dispose();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{
ValidateNames = true
};
if (sfd.ShowDialog() == DialogResult.OK)
{
using (var xtw = new XmlTextWriter(sfd.FileName, Encoding.UTF8))
{
var xw = XmlWriter.Create(xtw);
xw.WriteStartDocument();
xw.WriteStartElement("opml");
xw.WriteAttributeString("version", "1.1");
xw.WriteStartElement("head");
xw.WriteElementString("title", userNameComboBox.Text);
xw.WriteEndElement();
xw.WriteStartElement("body");
foreach (var row in twineDataGridView.SelectedRows)
{
var twine = (Twine)((DataGridViewRow)row).DataBoundItem;
if (twine != null)
{
xw.WriteStartElement("outline");
xw.WriteAttributeString("text", twine.Title);
xw.WriteAttributeString("type", "link");
xw.WriteAttributeString("url", twine.HtmlAddress);
xw.WriteStartElement("outline");
xw.WriteAttributeString("text", twine.Title);
xw.WriteAttributeString("type", "atom");
xw.WriteAttributeString("url", twine.AtomAddress);
xw.WriteEndElement();
xw.WriteEndElement();
}
}
xw.WriteEndElement();
xw.WriteEndElement();
xw.WriteEndDocument();
xw.Close();
}
}
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Copyright (C) 2009 Bent Rasmussen");
}
private void accessButton_Click(object sender, EventArgs e)
{
var user = userNameComboBox.Text;
Task.Create(x => ProcessAccount(user));
}
public void ProcessAccount(string user)
{
this.Invoke((Action)(() =>
{
userNameComboBox.Enabled = false;
accessButton.Enabled = false;
toolStripStatusLabel1.Text = "Processing...";
}));
var param = new NameValueCollection();
param.Add("type", "Twine");
param.Add("author", user);
var source = SearchTemplate.BindByName(SearchBase, param);
var wc = new WebClient();
using (var feedStream = wc.OpenRead(source))
{
var reader = XmlReader.Create(feedStream);
var feed = SyndicationFeed.Load(reader);
int c = 0, i = 0;
foreach (var item in feed.Items)
{
this.Invoke((Action)(() =>
{
toolStripProgressBar1.Increment(1);
toolStripStatusLabel1.Text = "Processing...";
}));
if (item.Links.Count != 0)
{
//try
{
ProcessTwine(item);
i++;
}
//catch (Exception)
{
c++;
}
}
if (Exiting)
break;
}
}
this.Invoke((Action)(() =>
{
userNameComboBox.Enabled = true;
accessButton.Enabled = true;
}));
}
private Twine ProcessTwine(SyndicationItem item)
{
var result = new Twine();
result.Title = item.Title.Text;
result.HtmlAddress = item.Links[0].Uri.ToString();
result.AtomAddress = "";
var wc = new WebClient();
var data = wc.DownloadData(result.HtmlAddress);
var stream = new MemoryStream(data);
var readerSettings = new XmlReaderSettings()
{
ProhibitDtd = false,
ValidationType = ValidationType.None,
ValidationFlags = XmlSchemaValidationFlags.None,
};
var reader = XmlReader.Create(stream, readerSettings);
var doc = XDocument.Load(reader);
var htmlNs = (XNamespace)"http://www.w3.org/1999/xhtml";
var root = doc.Root;
var atom = from r in root.Descendants(htmlNs + "head").Descendants(htmlNs + "link")
where r.Attribute("rel").Value == "alternate" && r.Attribute("type").Value == "application/atom+xml"
select r.Attribute("href");
foreach (var e in atom)
{
if (e.Value != "")
{
result.AtomAddress = e.Value;
this.BeginInvoke((Action)(() =>
{
Items.Add(result);
toolStripProgressBar1.Increment(1);
}));
}
break;
}
return result;
}
}
}
This triggers the exception "Cannot access a disposed object" on this fragment
this.Invoke((Action)(() =>
{
toolStripProgressBar1.Increment(1);
toolStripStatusLabel1.Text = "Processing...";
}));
If this fragment is commented out, I run into the next problem - a TargetInvocationException on Program level.
The inner exception of this is an InvalidOperationException.
The code is quite simple, so it should not be hard to implement this, I just new a few hints to move on.
Visual Studio project files.

If the user hits the exit button, the Close() method is called, and the UI starts getting torn down. However, your worker code keeps running and attempts to update the UI, which it can no longer do.
If you centralise all those invoke calls:
public void UpdateUI(Action action) {
if(!Exiting) this.Invoke(action);
}
you can call:
UpdateUI(() =>
{
toolStripProgressBar1.Increment(1);
toolStripStatusLabel1.Text = "Processing...";
});
(etc - all the this.Invoke calls should use UpdateUI instead)
and it should work. Also, make Exiting volatile.

Related

Background worker still freezing ui

Even tho I setup a background worker, I can't seem to make it not freeze the UI.
I looked around online but could not find a fix. I have tried creating basic threads and that worked but I need to also update UI stuff as it runs so thats why I switched to backgroundworkers, but if you could help me figure out how to use a basic thread and get that working that would be ok.
using MediaToolkit;
using MediaToolkit.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using VideoLibrary;
namespace ConsoleApp1
{
public partial class Form1 : Form
{
private List<VideoInfo> vids = new List<VideoInfo>();
private List<VideoInfo> failedVids = new List<VideoInfo>();
private int threads = 0;
BackgroundWorker worker;
private delegate void DELEGATE();
static void Main(string[] args)
{
Form1 form = new Form1();
form.ShowDialog();
}
public Form1()
{
InitializeComponent();
worker = new BackgroundWorker();
}
private void button1_Click(object sender, EventArgs e)
{
if(threads == 0)
{
progressBar1.Maximum = vids.Count;
progressBar1.Value = 0;
failedVids.Clear();
worker.DoWork += doWork;
worker.RunWorkerAsync();
//downloadVid();
}else
{
Console.WriteLine("Waiting for threads" + threads);
}
/*Thread thread1 = new Thread(new ThreadStart(downloadVid));
thread1.Start();*/
}
private void button1_Click_1(object sender, EventArgs e)
{
VideoInfo vid = new VideoInfo(tbLink.Text, tbTitle.Text, tbArtist.Text);
vids.Add(vid);
tbLink.Clear();
tbTitle.Clear();
listView1.Items.Add(vid.getLink());
}
private int downloadThread(int i)
{
Console.WriteLine(i);
var source = #"C:\Users\derri\Downloads\DownloadTest\";
var youtube = YouTube.Default;
VideoInfo vidInfo = vids[(int) i];
var vid = youtube.GetVideo(vidInfo.getLink());
Console.WriteLine(vidInfo.getLink());
try
{
File.WriteAllBytes(source + vid.FullName, vid.GetBytes());
}
catch (Exception e)
{
failedVids.Add(vids[(int)i]);
Console.WriteLine(e);
goto End;
}
var inputFile = new MediaFile { Filename = source + vid.FullName };
var outputFile = new MediaFile { Filename = $"{source + vidInfo.getArtist() + " - " + vidInfo.getTitle()}.mp3" };
using (var engine = new Engine())
{
engine.GetMetadata(inputFile);
engine.Convert(inputFile, outputFile);
}
File.Exists(outputFile.Filename);
File.Delete(inputFile.Filename);
setTags(vidInfo.getArtist(), vidInfo.getTitle());
End:
threads--;
return 1;
}
private void doWork(object sender, DoWorkEventArgs e)
{
Delegate del = new DELEGATE(downloadVid);
this.Invoke(del);
}
private void downloadVid()
{
int prog = 0;
for (int i = 0; i < vids.Count; i++)
{
Console.WriteLine(i);
while ((threads > 5)) { }
Thread thread = new Thread(() => { prog += downloadThread(i); });
thread.Start();
threads++;
System.Threading.Thread.Sleep(1000);
//thread.Join();
/*ParameterizedThreadStart start = new ParameterizedThreadStart(downloadThread);
Thread t = new Thread(start);
t.Start(i);
progressBar1.Value++;
threads++;*/
}
while (threads > 0){}
foreach (VideoInfo failedVid in failedVids)
{
listView2.Items.Add(failedVid.getLink());
}
listView1.Clear();
vids.Clear();
}
private void setTags(string artist, string title)
{
TagLib.File file = TagLib.File.Create("C:\\Users\\derri\\Downloads\\DownloadTest\\" + artist + " - " + title + ".mp3");
file.Tag.Artists = (new String[] { artist });
file.Tag.Title = (title);
file.Save();
}
}
}
this.Invoke will run on the UI thread.
Look into how to use either ReportProgress or RunWorkerCompleted events of the BackgroundWorker class. The both allow you to pass data from the background thread to the UI thread.

How to fix a problem with threads which are trying work at the same time?

I have a problem. I made a service which monitoring printing jobs in real time. It didn't worked perfect, but I had no big problem. Now I need to change service into Windows Forms program. And I've got a problem with threads.
Error:
System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
This error appears on string "PrintQueue.Refresh()".
I can't find where the other thread tries to run.
I tried to set the other thread and start it with MonitoringJobs() procedure but it doesn't work.
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;
using System.Collections.Concurrent;
using System.Data.SqlClient;
using System.Diagnostics;
using System.ServiceProcess;
using System.Management;
using System.Windows;
using System.Printing;
using System.Configuration;
using System.Collections.Specialized;
using System.Threading;
namespace MonitoringPrintJobs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer.Elapsed += GetJobs;
timer.AutoReset = true;
timer.Enabled = true;
}
System.Timers.Timer timer = new System.Timers.Timer(5);
int writeInterval = 1000;
int DefaultWriteInterval = 1000;
bool Logging;
SelectPrinter fSelectPrinter = new SelectPrinter();
ConcurrentDictionary<string, string> QueueJobs = new ConcurrentDictionary<string, string>();//declaration printers jobs dictionary
ConcurrentDictionary<string, DateTime> PrintedJobs = new ConcurrentDictionary<string, DateTime>();
PrintServer printServer = null;
PrintQueueCollection QueuesOnLocalServer = null;
List<PrintQueue> queues = new List<PrintQueue>();
public void MonitoringJobs()
{
//if(queues != null)
foreach (var PrintQueue in queues)
{
PrintQueue.Refresh();
using (var jobs = PrintQueue.GetPrintJobInfoCollection())//wait until collection updates!!!
foreach (var job in jobs)
{
if (!QueueJobs.ContainsKey(job.Name))//if list with printer jobs doesn't contain found job (name)
{//then put name in list with printer jobs
QueueJobs.TryAdd(job.Name, job.JobStatus.ToString());
if (Logging == true)
{
File.AppendAllText(#"D:\Logs\Logging.txt", String.Format("{0} - {1} - {2}{3}", DateTime.Now, job.Name, job.JobStatus, Environment.NewLine));
}
}
else//if list with printer jobs contains found job name
{
if (QueueJobs[job.Name] != job.JobStatus.ToString() && !QueueJobs[job.Name].ToLower().Contains("error"))//if status for this job doesn't exist
{
QueueJobs[job.Name] = job.JobStatus.ToString();//replace job's status
if (Logging == true)
{
File.AppendAllText(#"D:\Logs\Logging.txt", String.Format("{0} - {1} - {2}{3}", DateTime.Now, job.Name, job.JobStatus, Environment.NewLine));
}
}
if (job.JobStatus.ToString().ToLower().Contains("error") && PrintedJobs.ContainsKey(job.Name))
{
var someVar = new DateTime();
PrintedJobs.TryRemove(job.Name, out someVar);
}
}
if (QueueJobs[job.Name].ToLower().Contains("print") && !QueueJobs[job.Name].ToLower().Contains("error"))//if successfully printed
{
PrintedJobs.TryAdd(job.Name, DateTime.Now);
}
}
}
}
private void GetJobs(Object source, System.EventArgs e)
{
writeInterval--;
MonitoringJobs();
if (writeInterval <= 0)
{
writeInterval = DefaultWriteInterval;
PrintedJobs.Clear();
QueueJobs.Clear();
}
}
protected void OnStart()
{
QueuesOnLocalServer = printServer.GetPrintQueues();
writeInterval = 120000;
foreach (var item in fSelectPrinter.SelectetPrinters)
Logging = true;
foreach (var printer in fSelectPrinter.SelectetPrinters)
{
if (string.IsNullOrEmpty(printer))
{
timer.Stop();
Environment.Exit(0);
}
var queue = QueuesOnLocalServer.FirstOrDefault(o => o.FullName.ToUpper() == printer.ToUpper());
if (queue == null)
{
timer.Stop();
Environment.Exit(0);
}
queues.Add(queue);
}
timer.Start();
}
private void button2_Click(object sender, EventArgs e)
{
fSelectPrinter.ShowDialog();
}
private void Form1_Load(object sender, EventArgs e)
{
printServer = new PrintServer();
foreach (PrintQueue pq in printServer.GetPrintQueues())
fSelectPrinter.listBox1.Items.Add(pq.Name);
}
private void button1_Click_1(object sender, EventArgs e)
{
bool StartPrinting = button2.Enabled = false;//turn of select printers form button
if (StartPrinting == false)//StartPrinting == monitoring == true
{
OnStart();
}
else
{
StartPrinting = true;//StartPrinting == monitoring == false
timer.Stop();
}
}
}
}
In this program I tried to get printing jobs statuses and output them in listbox1 and write results with string.Format in file.
On Form1_Load event you are adding things to your fSelectedPrinter.Listbox.
If you items you are adding are coming from a different thread, that will cause an error. Only UI thread can update objects on a form without using SynchornizationContext.
private readonly SynchronizationContext synchronizationContext;
InitializeComponent();
synchronizationContext = SynchronizationContext.Current;
Here is an example:
private async void btnListFiles1_Click(object sender, EventArgs e)
{
if (txtDirectory1.Text == "")
{
MessageBox.Show(InfoDialog.SELECT_DIRECTORY,PROGRAM_NAME);
return;
}
if (!Directory.Exists(txtDirectory1.Text))
{
MessageBox.Show(InfoDialog.DIRECTORY_NOT_EXIST, PROGRAM_NAME);
return;
}
try
{
string fileTypes = (txtFileTypes1.Text == "") ? "" : txtFileTypes1.Text;
string[] files = Directory.GetFiles(txtDirectory1.Text.TrimEnd(),
(fileTypes == "") ? "*.*" : fileTypes,
(chkSub1.Checked) ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
listBoxFiles.Items.Clear();
progressBar.Step = 1;
progressBar.Value = 1;
progressBar.Maximum = files.Length + 1;
listBoxFiles.BeginUpdate();
if (txtSearchPattern1.Text != "")
{
string searchPattern = txtSearchPattern1.Text.ToLower();
await System.Threading.Tasks.Task.Run(() =>
{
foreach (string file in files)
{
if (file.ToLower().Contains(searchPattern))
{
AddToListBox(file);
}
}
});
}
else
{
await System.Threading.Tasks.Task.Run(() =>
{
foreach(string file in files)
{
AddToListBox(file);
}
});
}
listBoxFiles.EndUpdate();
progressBar.Value = 0;
}
private void AddToListBox(string item)
{
synchronizationContext.Send(new SendOrPostCallback(o =>
{
listBoxFiles.Items.Add((string)o);
progressBar.Value++;
}), item);
}

File I/O Exceptions

i am currently working on a Windows Forms App in c# which will allow the user to add or delete records. when i hit the button to display all the records written to the file the files appear, but when i try to delete by transact number i get an exception saying that "The process cannot access the the because it is being used somewhere else". i have tried putting it in a try-catch block to make sure the reader/writer will close and still not working code will be attached any help is greatly appreciated. p.s im not looking for code to finish this project just help getting by this exception and make it work like it is suppose.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MMFileIO
{
public partial class MMAssignment3 : Form
{
StreamWriter writer;
StreamReader reader;
string record = "";
public MMAssignment3()
{
InitializeComponent();
}
private void MMAssignment3_Load(object sender, EventArgs e)
{
txtFile.Text = #"c:\burnable\assignment3.txt";
if (!Directory.Exists(txtFile.Text.Substring
(0, txtFile.Text.LastIndexOf('\\'))))
MessageBox.Show("File path does not exist");
}
private void btnAdd_Click(object sender, EventArgs e)
{
try
{
if (radNew.Checked)
writer = new StreamWriter(txtFile.Text, append: false);
else
writer = new StreamWriter(txtFile.Text, append: true);
}
catch(Exception ex)
{
if (writer != null)
writer.Close();
MessageBox.Show($"exception adding new record: {ex.Message}");
return;
}
record = $"{txtTransact.Text}::{txtDate.Text}::{txtSerial.Text}::" +
$"{txtToolPurchased.Text}::${txtPrice.Text}::{txtQty.Text}::" +
$"${txtAmount.Text}";
try
{
writer.WriteLine(record);
lblMessage.Text = ($"Record added");
txtTransact.Text = txtDate.Text = txtSerial.Text =
txtToolPurchased.Text = txtPrice.Text = txtQty.Text =
txtAmount.Text = "";
}
catch(Exception ex)
{
MessageBox.Show($"exception adding a new record: {ex.Message}");
}
finally
{
writer.Close();
}
}
private void btnDelete_Click(object sender, EventArgs e)
{
reader = new StreamReader(txtFile.Text);
List<string> records = new List<string>();
while (! reader.EndOfStream)
{
record = reader.ReadLine();
records.Add(record);
}
if (records.Count == 0)
MessageBox.Show("No records left in file");
reader.Close();
writer = new StreamWriter(txtFile.Text, append: false);
foreach (string item in records)
{
}
}
private void btnCloseFile_Click(object sender, EventArgs e)
{
txtDataDisplay.Text = "";
reader.Close();
}
private void btnDisplay_Click(object sender, EventArgs e)
{
reader = new StreamReader(txtFile.Text);
txtDataDisplay.Text = $"{"#".PadRight(10)}\t" +
$"{"Purchase-Date".PadRight(10)}\t{"Serial #".PadRight(10)}\t" +
$"{"Manufacturing Tools".PadRight(10)}\t{"Price".PadRight(10)}\t" +
$"{"Qty".PadRight(10)}\t{"Amount".PadRight(10)}\n{"".PadRight(50)}\n";
while (!reader.EndOfStream)
{
record = reader.ReadLine();
string[] fields = record.Split(new string[] { "::" }, StringSplitOptions.None);
txtDataDisplay.Text += $"{fields[0].PadRight(10)}\t" +
$"{fields[1].PadRight(10)}\t{fields[2].PadRight(10)}\t" +
$"{fields[3].PadRight(30)}\t{fields[4].PadRight(10)}\t" +
$"{fields[5].PadRight(10)}\t{fields[6].PadRight(10)}\n";
}
reader.Close();
}

How do i loop for the next 25 results next page using facebook api?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Facebook;
using System.Net;
using System.IO;
namespace WebSite_Login_And_Browsing
{
class Posts
{
public string PostId { get; set; }
public string PostStory { get; set; }
public string PostMessage { get; set; }
public string PostPicture { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
}
class FacebookPosts
{
static string accesstoken;
//static string token = "2f89d691b5f39";
static string token = "1186840401345424|GoJRCpM";
static string mytoken = "CAACEdEose0cBACPu39NSSalHCGFGDGRKZAvwiTuzG8PHlNRJwbyMVugovDxgL7CT3a1QbRuVDZALXxWU0ntwSrDyq75LIIuzFpBtx47cJYCY2OiA21lpTRKt2bB0t5HrsQYIXHXhmU7GnavWZCzqN8yeuv5NWXxTIOfVCZAZArjYNiPWhZBqZAZAO03s6FKNIulm4kjzXvp4QKiahAlcyaZBg";
static string mytokenaslip = "CAACEdEose0cBABmWuBI9p9dpPxEsMJoFZAG3kScx61kZAImNBgt52kVrd8WWPRpwjWP8nCPX69zdLuFyVQHzxYfMk85ZBZC4BIajVWXNLo7OI7yaCbNIwqkcdwpabQVFZBRWt0rzTQrQr6ZBij45XnrQyEUqFKP4gADeO4Fl9yRaZAZCOFtV3b84sWUFEgwaKbZAPY4BCljVjWQZDZD";
public static void RetrievePosts()
{
try
{
var client = new FacebookClient(mytokenaslip);
dynamic result = client.Get("/me/posts");
List<Posts> postsList = new List<Posts>();
//all the posts and their information (like pictures and links) is strored in result.data not in result
for (int i = 0; i < result.data.Count; i++)
{
Posts posts = new Posts();
posts.PostId = result.data[i].id;
if (object.ReferenceEquals(result.data[i].story, null))
posts.PostStory = "this story is null";
else
posts.PostStory = result.data[i].story;
if (object.ReferenceEquals(result.data[i].message, null))
posts.PostMessage = "this message is null";
else
posts.PostMessage = result.data[i].message;
posts.PostPicture = result.data[i].picture;
posts.UserId = result.data[i].from.id;
posts.UserName = result.data[i].from.name;
postsList.Add(posts);
}
}
catch (Exception err)
{
//throw;
string myerr = err.ToString();
}
}
}
}
I'm getting 25 results in the List postsList
How do i loop now asgain to get the next page with the next 25 results and add it to postsList and loop over and over again untill there are no more results ?
What i want to do is to delete automatic every 50 minutes the last old 25 posts.
In my other class in my project i'm posting automatic to my wall a post every minute. After 50 minutes i want to delete the last old 25 posts so on my wall will be all the time with 25 posts only.
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 mshtml;
using HtmlAgilityPack;
using System.Net;
using System.IO;
namespace WebSite_Login_And_Browsing
{
public partial class Facebook_Post : Form
{
WebBrowser wb = new WebBrowser();
int postsCounter = 0;
StreamWriter w = new StreamWriter(#"e:\posts.txt");
WebBrowser webBrowser1;
public Facebook_Post()
{
InitializeComponent();
webBrowser1 = new WebBrowser();
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
webBrowser1.ScriptErrorsSuppressed = true;
webBrowser1.Navigate("https://www.facebook.com/");
label4.Text = DateTime.Now.ToString();
w.WriteLine(label4.Text.ToString());
w.WriteLine(Environment.NewLine);
label5.Visible = false;
label2.Visible = false;
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
try
{
if (e.Url.AbsoluteUri != webBrowser1.Url.AbsoluteUri)
{
return;
}
wb = webBrowser1;
foreach (HtmlElement he in wb.Document.All.GetElementsByName("xhpc_message"))
{
he.SetAttribute("value", RandomString(10));
}
var elems = wb.Document.GetElementsByTagName("button");
foreach (HtmlElement elem in elems)
{
if (elem.InnerText == "Post")
{
elem.InvokeMember("click");
}
}
sent = true;
postsCounter += 1;
label2.Text = postsCounter.ToString();
label2.Visible = true;
timer1.Enabled = true;
webBrowser1.Dispose();
if (postsCounter == 720)
{
w.WriteLine(postsCounter.ToString());
w.WriteLine(Environment.NewLine);
label5.Text = DateTime.Now.ToString();
label5.Visible = true;
w.WriteLine(label5.Text.ToString());
w.Close();
}
}
catch(Exception err)
{
string myerr = err.ToString();
}
}
private void button1_Click(object sender, EventArgs e)
{
List<string> results = new List<string>();
HtmlElementCollection elems = wb.Document.GetElementsByTagName("INPUT");
foreach (HtmlElement elem in elems)
{
String nameStr = elem.GetAttribute("value");
results.Add(nameStr);
}
}
bool sent = false;
int count = 0;
private void timer1_Tick(object sender, EventArgs e)
{
try
{
count += 1;
if (sent == true && count >= 60)
{
count = 0;
timer1.Enabled = false;
webBrowser1 = new WebBrowser();
if (webBrowser1.IsBusy == false)
{
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
webBrowser1.Navigate("https://www.facebook.com/");
}
sent = false;
}
}
catch(Exception err)
{
string myerr = err.ToString();
}
}
private StringBuilder builder;
private static Random random = new Random((int)DateTime.Now.Ticks);
private string RandomString(int size)
{
try
{
builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
}
catch(Exception err)
{
string myerr = err.ToString();
}
return builder.ToString();
}
}
}
I believe this is what you're looking for:
var client = new FacebookClient(mytokenaslip);
//1-25
dynamic result = client.Get("/me/posts", new { limit = "25", offset = "0"});
//26-50
dynamic result = client.Get("/me/posts", new { limit = "25", offset = "25"});
You can also chose to get more than 25 posts at once.
//51-100
dynamic result = client.Get("/me/posts", new { limit = "50", offset = "50"});
You can use a "recursive function" to get all entries, and the "next" parameter in the API result includes the API call for the next batch of results: https://developers.facebook.com/docs/graph-api/using-graph-api#paging
Be careful though, you may hit an API limit if you try to do this too fast and if there are too many results. Also, since you want to delete old entries and deleting one entry is one API call, you should try with a timeout after each call just to make sure not to hit a limit.
Make sure you learn and understand how recursive functions work, hereĀ“s one of countless threads about that: Help with Creating a Recursive Function C#

No Book Results from ISBNDB with Valid ISBN

I've got a weird issue here. I'll start by explaining my program:
I have a C# application. The main goal of the program is to get information about a book based on its ISBN. The ISBN is passed to the program via a TCP/IP scanner on an Android device. The ISBN is then put into a valid URL which is used to grab the XML data from ISBNDB.com.
The issue that I am having is this:
When I query an ISBN typed into a TextBox, the program works fine. When I query an ISBN scanned from the reader, it returns 'No Results'
I have implemented various ways to try and get to the bottom of this case. Right before the XML is read, I have a message box show me the XML that it received:
As you can see, it shows no results. However, when I visit the URL (Also gotten from within the program):
I get this in Microsoft Edge:
Which, is exactly what I would think the application would get as well.
Does anyone know what is going on? If so, what can I do to fix it and how can my code be improved to eliminate this error?
For those interested, here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Threading;
using System.Diagnostics;
namespace LibraryBookLister
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string XML = "";
private void btnQuery_Click(object sender, EventArgs e)
{
GetXMLBarcodeData();
}
private void GetXMLBarcodeData()
{
string Barcode4 = textBarcode.Text;
MessageBox.Show(Barcode4);
string barcode = Barcode4;
StringBuilder output = new StringBuilder();
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Set the reader settings object to use the resolver.
if(barcode.Length > 13)
{
barcode = barcode.Remove(14);
MessageBox.Show(barcode);
}
string xmlString = #"?access_key=IDC057UX&results=details&index1=isbn&value1=" + barcode;
MessageBox.Show("GEttting book info for : " + barcode);
Uri baseUri = new Uri("https://isbndb.com/api/books.xml");
Uri fulluri = resolver.ResolveUri(baseUri, xmlString);
MessageBox.Show("Now Getting The URL: " + fulluri.ToString());
Process.Start(fulluri.ToString());
StringBuilder sb = new StringBuilder();
XmlReader readesr = XmlReader.Create(fulluri.ToString());
MessageBox.Show("REading data from " + fulluri.ToString());
while (readesr.Read())
{
sb.AppendLine(readesr.ReadOuterXml());
}
string XMLs = sb.ToString();
XML = XMLs;
MessageBox.Show("XML : " + XML);
GetXMLStuff();
}
public void GetXMLStuff()
{
tcplistener.Stop();
XmlDocument doc = new XmlDocument();
doc.LoadXml(XML);
XmlNodeList nodes = doc.DocumentElement.SelectNodes("/ISBNdb/BookList");
List<Book> books = new List<Book>();
foreach (XmlNode node in nodes)
{
Book book = new Book();
try
{
if (node.SelectSingleNode("BookData/AuthorsText").InnerText == null)
{
MessageBox.Show("Could not find this book. Please enter data by hand.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
textBarcode.Clear();
return;
}
}
catch
{
MessageBox.Show("Could not find this book. Please enter data by hand.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
// textBarcode.Clear();
return;
}
book.author = node.SelectSingleNode("BookData/AuthorsText").InnerText;
book.title = node.SelectSingleNode("BookData/Title").InnerText;
book.ISBN = node.SelectSingleNode("BookData").Attributes["isbn"].Value;
books.Add(book);
MessageBox.Show(book.author);
addInfo(book.author, book.title, book.ISBN);
textBarcode.Clear();
}
// MessageBox.Show("Total books: " + books.Count);
}
private void addInfo(string Author, string Title, string ISBN)
{
textAuthor.Text = Author;
textTitle.Text = Title;
textISBN.Text = ISBN;
}
class Book
{
public string ISBN;
public string title;
public string author;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
int time = 10;
bool cancel = false;
private void timer1_Tick(object sender, EventArgs e)
{
if(time > 0)
{
labelTime.Text = time.ToString();
button1.Text = "Change Data";
cancel = true;
labelTime.Visible = true;
time--;
// MessageBox.Show(time.ToString());
}
if(time <= 0)
{
cancel = false;
button1.Text = "Add to List";
timer1.Stop();
time = 10;
labelTime.Visible = false;
MessageBox.Show("Submitting");
}
}
private void button1_Click(object sender, EventArgs e)
{
if(cancel)
{
timer1.Stop();
labelTime.Visible = false;
time = 10;
cancel = false;
button1.Text = "Add to List";
}
else
{
timer1.Start();
}
}
private void button2_Click(object sender, EventArgs e)
{
Thread tcpServer = new Thread(new ParameterizedThreadStart(TCPServerRun));
//TCPServerRun();
tcpServer.Start();
}
bool on = true;
TcpListener tcplistener = new TcpListener(IPAddress.Any, 5004);
private void TCPServerRun(object test)
{
try
{
MessageBox.Show("Starting Listener");
tcplistener.Start();
}
catch { MessageBox.Show("COULDNT START TPCSERVER"); return; }
while (on == true)
{
try
{
TcpClient client = tcplistener.AcceptTcpClient();
Thread tcpHandlerThread = new Thread(new ParameterizedThreadStart(tcpHandler));
// tcpHandlerThread.Start(client);
tcpHandler(client);
}
catch
{
tcplistener.Stop();
// MessageBox.Show("Stopping Listener");
}
}
}
string bCode = "";
private void tcpHandler(object client)
{
TcpClient mClient = (TcpClient)client;
NetworkStream stream = mClient.GetStream();
byte[] message = new byte[1024];
stream.Read(message, 0, message.Length);
bCode = Encoding.ASCII.GetString(message);
stream.Close();
mClient.Close();
MessageBox.Show(bCode);
this.textBarcode.Text = bCode;
GetXMLBarcodeData();
}
}
}
Possible Hint: Could it have something to do with how I have threads working?
*Edit: * **I have updated the code to have the barcode be put in a textBox and then used to fetch the data. This does not seem to work either because it 'Cannot access the control on a thread other than on which it was created'
If manual user input succeed while automated input fail, the simplest hack is just replacing the automated input to a call to manual control BeginInvoke. For your code this would be :
textBarcode.BeginInvoke(new Action(() => {
textBarcode.Text = bCode;
GetXMLBarcodeData();
}));

Categories

Resources