Right I have the following code:
public partial class Form1 : Form
{
delegate void UpdateUI();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if (!Fiddler.CertMaker.rootCertExists())
{
if (!Fiddler.CertMaker.createRootCert())
{
throw new Exception("Unable to create cert for FiddlerCore.");
}
}
if (!Fiddler.CertMaker.rootCertIsTrusted())
{
if (!Fiddler.CertMaker.trustRootCert())
{
throw new Exception("Unable to install FiddlerCore's cert.");
}
}
Fiddler.FiddlerApplication.OnNotification += delegate (object snder, NotificationEventArgs oNEA) { MessageBox.Show("** NotifyUser: " + oNEA.NotifyString); };
Fiddler.FiddlerApplication.Log.OnLogString += delegate (object snder, LogEventArgs oLEA) { MessageBox.Show("** LogString: " + oLEA.LogString); };
Fiddler.FiddlerApplication.AfterSessionComplete += FiddlerApplication_OnAfterSessionComplete;
Fiddler.FiddlerApplication.Startup(0, FiddlerCoreStartupFlags.Default & FiddlerCoreStartupFlags.DecryptSSL);
}
void FiddlerApplication_OnAfterSessionComplete(Session oSession)
{
if(oSession.fullUrl.Contains("google.com"))
richTextBox1.Invoke(new UpdateUI(() =>
{
richTextBox1.AppendText(oSession.GetResponseBodyAsString());
}));
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Fiddler.FiddlerApplication.Shutdown();
}
}
The thing is with DecryptSSL flag set on startup the on aftersesssion complete never fires, I also never get any messages from either the notification or logs callbacks.
Any ideas?
I think port 0 might be a problem in the Startup(), I tried with port 8888:
Fiddler.FiddlerApplication.Startup(8888, FiddlerCoreStartupFlags.Default & FiddlerCoreStartupFlags.DecryptSSL);
I tried with these before response and before request handlers instead of OnAfterSessionComplete. In your Form1_Load():
Fiddler.FiddlerApplication.BeforeRequest += new SessionStateHandler(HandleBeforeRequest);
Fiddler.FiddlerApplication.BeforeResponse += new SessionStateHandler(HandleBeforeResponse);
And the handlers:
private void HandleBeforeRequest(Session oSession)
{
oSession.bBufferResponse = true;
}
private void HandleBeforeResponse(Session oSession)
{
if(oSession.fullUrl.Contains("google.com"))
{
richTextBox1.Invoke(new UpdateUI(() =>
{
richTextBox1.AppendText(oSession.GetResponseBodyAsString());
}));
}
}
By the way, don't know if you omitted them from your sample but I needed to add these in the constructor:
Load += Form1_Load;
FormClosing += Form1_FormClosing;
Might also be good to add this before Shutdown():
FiddlerApplication.oProxy.Detach();
Related
I run user defined scripts in my WPF application using CS-Script library. How can I cancel a script if it runs endless? As my users write the script I can't rely on a cancel flag that is checked inside the script.
Here is a simplified code snippet showing the problem:
public partial class MainWindow : Window
{
public string MessageFromScript
{
get { return (string)GetValue(MessageFromScriptProperty); }
set { SetValue(MessageFromScriptProperty, value); }
}
public static readonly DependencyProperty MessageFromScriptProperty =
DependencyProperty.Register("MessageFromScript", typeof(string), typeof(MainWindow), new PropertyMetadata(null));
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
BackgroundWorker worker = null;
private void OnStart(object sender, RoutedEventArgs e)
{
if(worker != null)
{
return;
}
worker = new BackgroundWorker();
worker.DoWork += RunScript;
worker.RunWorkerCompleted += ScriptCompleted;
worker.WorkerSupportsCancellation = true;
worker.RunWorkerAsync();
}
private void ScriptCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Cancelled)
MessageFromScript = "Script cancelled";
else
MessageFromScript = e.Result.ToString();
}
private void RunScript(object sender, DoWorkEventArgs e)
{
dynamic script = CSScript.Evaluator.LoadCode(#"using System;
using System.Threading;
public class Script
{
public string Test()
{
{int count=0; while(true) { count++; Console.WriteLine(count.ToString()); Thread.Sleep(200); }}
return ""Message from script"";
}
}");
e.Result = script.Test();
}
private void OnStop(object sender, RoutedEventArgs e)
{
if(worker == null)
{
return;
}
//TODO: How do I stop the script here?
worker = null;
}
}
In your Test() method add a parameter where you pass a CancellationToken to the script. Then design the loops in your script to check the canellation token if abort has been requested and break out. To stop the script just call the Cancel() method of your CancellationTokenSource which token you passed to the script on invocation.
I have this situation: a class that contains a background worker that do some thing in a while cycle:
public class CControls
{
public delegate void ControlChangedEventHandler();
public event ControlChangedEventHandler ControlChangedEvent;
private readonly BackgroundWorker worker;
bool bClose = false;
public CControls(IntPtr hwnd)
{
worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bClose = true;
}
public void enable(bool bEnable)
{
if (bEnable && !worker.IsBusy)
{
worker.RunWorkerAsync();
}
else
{
bClose = true;
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
while (!bClose)
{
// my job
// ..............................................
//
if (ControlChangedEvent != null)
{
ControlChangedEvent();
}
}
}
}
I have my form that create an instance of this class and set the listener of ControlChangedEvent:
CControls ct = new CControls();
ct.ControlChangedEvent += ct_ControlChangedEvent;
int changes = 0;
void ct_ControlChangedEvent()
{
Dispatcher.Invoke(DispatcherPriority.Background, (Action)delegate
{
changes ++;
infoLabel.Content = string.Format("changes: {0}", changes);
});
}
but the infoLabel changes only if my program have the focus, otherwise is not fired...
any ideas?
thanks ;)
I am trying to run a function in a different class than the dispatcher through a backgroundworker and have it update the progress on every iteration. I am getting no errors and the backgroundworker is functioning properly, but my textbox never updates...
public partial class MainWindow : Window
{
public BackgroundWorker worker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(workerDoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(workerProgressChanged);
}
private void myButtonClick(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
void workerDoWork(object sender, DoWorkEventArgs e)
{
yv_usfm.convert(worker);
}
void workerProgressChanged(object sender, ProgressChangedEventArgs e)
{
myTextBox.Text = "some text";
}
}
public class yv_usfm
{
public static void convert(BackgroundWorker worker)
{
int i = 1;
while (i < 100)
{
worker.ReportProgress(i);
i++;
}
}
}
What makes you say the BackgroundWorker is functioning properly? I see no call to worker.RunWorkerAsync(), and without that it will never start.
You're not starting the worker!
worker.RunWorkerAsync();
Try This:
void DoWork(...)
{
YourMethod();
}
void YourMethod()
{
if(yourControl.InvokeRequired)
yourControl.Invoke((Action)(() => YourMethod()));
else
{
//Access controls
}
}
Hope This help.
I have a form to ask for some data. At leaving of an input field (TextBox, DGV) the appropriate _Validating methode or _CellValueChanged methode is called.
If I want to end the program this methode is called, too - before the _FormClosing methode is called.
How can I fin out whether the program branches into the _FormClosing methode or not?
private void txb_Validating(object sender, CancelEventArgs e)
{
doLog("Text 1");
}
private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
doLog("Text 2");
}
private void doLog(string txt)
{
// this is first called at closing...
if( [FormClosing is active] )
{
// Do something
}
else
{
// Do someting different
}
}
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
// ... and this but later
// Write the Logfile
}
How have I to replace [FormClosing is active] to get to the right result?
I tried so
if ( this.FormClosing== true )
and so
this.FormClosing +=new FormClosingEventHandler(MyForm_FormClosing);
and so
FormClosingEventHandler cl = new FormClosingEventHandler(MyForm_FormClosing);
but I always was in a dead end.
This would do the trick:
public class YourForm : Form
{
private bool bIsClosing = false;
public YourClass()
{
InitializeComponent();
this.FormClosing +=
new FormClosingEventHandler(MyForm_FormClosing);
}
private void txb_Validating(object sender, CancelEventArgs e)
{
doLog("Text 1");
}
private void dgv_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
doLog("Text 2");
}
private void doLog(string txt)
{
// this is first called at closing...
if( bIsClosing )
{
// Do something
}
else
{
// Do someting different
}
}
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
bIsClosing = true;
// Write the Logfile
doLog("whatever");
}
}
this.FormClosing is an event that gets triggered once your form starts closing (like clicking the close button), hence the name. You need your application to register that event like so:
this.FormClosing +=new FormClosingEventHandler(MyForm_FormClosing);
This insures that once the FormClosing event gets triggered, your MyForm_FormClosing will be called.
You can create a flag like bool bIsFormClosing and set that flag once your closing function get called.
Edit:
As I understand now by reviewing your answer and your comments, you want to know in your doLog function if the form is closing.
Here is another approach
`
public class YourForm : Form
{
private bool bIsClosing = false;
Private bool bClosingHandled = false;
public YourClass()
{
InitializeComponent();
this.FormClosing +=
new FormClosingEventHandler(MyForm_FormClosing);
}
private void txb_Validating(object sender, CancelEventArgs e)
{
doLog("Text 1");
}
private void dgv_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
doLog("Text 2");
}
private void doLog(string txt)
{
// this is first called at closing...
if( bIsClosing )
{
// Do something
bClosingHandled = true;
this.close();
}
else
{
// Do someting different
}
}
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
If(!bClosingHandled)
{
bIsClosing = true;
e.Cancel = true;
return;
}
// Write the Logfile
doLog("whatever");
}
}`
This approach uses two flags... When you first receive a close event, you set the bIsClosing flag to true, cancels the event and return. Then once your dolog function get called, you force the close operation.
I wrote some class:
public class A
{
public A()
{
serviceAdapter.CompletedCallBackEvent += new EventHandler( foo );
.
.
.
}
void foo(object sender, EventArgs e)
{
serviceAdapter.CompletedCallBackEvent -= new EventHandler( foo );
}
}
Now, i want to change this callback listener with some anonymous - but i don't know how to remove the callback listener in the anonymous method .
class A
{
public A()
{
serviceAdapter.CompletedCallBackEvent += delegate( object sender, EventArgs ee )
{
... need to remove the listener to the event.
}
}
}
You could simply assign your delegate/handler to a private variable.
private EventHander _handler = null;
public A()
{
_handler = delegate( object sender, EventArgs ee)
{
ServiceAdapter.CompletedCallBackEvent -= _handler;
};
ServiceAdapter.CompletedCallBackEvent += _handler;
}
You can't remove the anonymous delegate like that. See MSDN article on anonymous delegates. Also worth reading this article
You may be able to do:
public A()
{
EventHandler myHandler = null;
myHandler = new EventHandler(delegate(object s, EventArgs e)
{
serviceAdapter.CompletedCallbackEvent -= myHandler;
});
serviceAdapter.CompletedCallBackEvent += myHandler;
}