I hope I can get some help.
I’m trying to create an host based application using C# (in the simplest way) to monitor access to a web page from the computer that hosts the application, if this web page is accessed while the program is running an event should rise.
So far I have used the SHDocVw.ShellWindows() but it works only if the web page has already been accessed not while is being accessed.
It monitors Windows Internet Explorer
I have also researched the httplistener but to no avail.
Do you have any solution?
Please let me know if you require more details
This may or may not be valid for your situation, but I had to do something similar with an Intranet website (cross-browser so it was a little harder than just with IE) recently. My solution was to setup a client-side application which hosts a WCF service. Then, when the user clicks a link on the web page (or raises any event, such as, $(document).ready) it sends an message back to the server telling the server to connect to the IP address associated with the current session (really just the IP Address on the request) on a known port. This connection is made to the client side application which is listening at that IP address and port for instructions on what to do (in my case it is dynamically compiling code in the request and running it).
That of course will only work for Intranet websites. A more general approach that will work for IE across the internet, is to create a IE extension (or maybe a Silverlight application) that talks on localhost. I've never done it, so I can't tell you how or if it is actually possible (but in principle seems possible).
If you don't have access to the website at all then perhaps using SharpPCAP or the Fiddler API would work for you.
Assuming the question is "I want to know when a program on my local computer accesses a give web page": A transparent http proxy is likely approach you want to take. Check out Fiddler to see if it is exactly what you want.
If your question is more "I want to know when a particular page is hit on my remote server": There are plenty of monitoring tools that parse web server logs and event logs to know state of the server. If you want to do something yourself and control the server's code - collect hit information for the page you are interested and provide some page that reports this data.
After few hours of work I have found a solution, not the most elegant one so far,(and at times causes a memory dump) but it does what I need.
Thanks
Just last edit, I solved the crash issue by adding a time so it checks the page every sec or so.
once again thanks for your iterest in my question.
class wait
{
private static System.Timers.Timer aTimer;
public void timed1()
{
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//NetKeyLogger klog = new NetKeyLogger();
// Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
Kelloggs.Program KKA = new Kelloggs.Program();
SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows();
string filename;
foreach (SHDocVw.InternetExplorer ie in shellWindows)
{
filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();
if (filename.Equals("iexplore"))
{
string ddd = (ie.LocationURL);
// Console.WriteLine(ddd);
if (ie.LocationURL == "http://www.testPage.com/")
{
Console.WriteLine("Page found");
// Console.ReadLine();
aTimer.Enabled = false;
KKA.Maino();
}
}
Related
I am beginner in c# with a huge problem.
An application with datagridview in front (Termin plan for one work day) works on many PC's in LAN with MS Windows Server and with MySQL database.
How can I become the changes made on one workstation AUTOMATICALY on all other PC's WITHOUT any action on them (application only started).
I have a procedure for data and datagridview refresh, I must only know WHEN I must start this procedure, that means I must know WHEN any other workstation made any changes.
Thanks for any help!
A simple solution would be to use a timer and when it elapses you refresh you gridview. so on defined period of time it will be refreshed automatically. the problem can be that if you update to often there's a overload of accessing the db. to prevent this, you could make an serverapplication which handles all data
Let's say PC 1 is starting the client application.
First it connects to server application (the server stores the reference of the client e.g. in an list).
After that the user on PC1 makes changes and click on save, the software will send the changes to the server (e.g. a custom object with all needed information).
Server saves the changes to the DB
Serverapplication give a response to the specific client if it worked or not
If it worked, Send an custom object (for example named ChangesDoneEvent) to all clients that indicates that changes have been done.
All connected clients will receive that object and know now that the have to refresh their gridview.
For further information just search for C# Multi threaded Server Socket programming. For sending custom objects over network you will find many resources in the internet too, maybe this will help you Sending and receiving custom objects using Tcpclient class in C#
Declare Delegate on your form
public delegate void autocheck();
private System.Timers.Timer TTTimer = new System.Timers.Timer();
public void autofilldgv()
{
if (this.InvokeRequired)
{
this.Invoke(new autocheck(UpdateControls));
}
else
{
UpdateControls();
}
}
private void UpdateControls()
{
//call your method here
filldgv();
}
void TTTimer_Elapsed(object sender System.Timers.ElapsedEventArgs e)
{
mymethod();
}
public void mymethod()
{
//this method is executed by the background worker
autofilldgv();
}
private void frm_receptionView_Load(object sender, EventArgs e)
{
this.TTTimer.Interval = 1000; //1 sec interval
this.TTTimer.Elapsed += new System.Timers.ElapsedEventHandler(TTTimer_Elapsed);
this.TTTimer.Start();
}
The solution provided above is actually a good way to handle this scenario. Before implementing you might also want to think about the potential fall backs. It is possible that Client PC 's IP could change and since you are using sockets. The object reference added in the list could be faulted state. You might want to think of handling this pitfall.
I need some help from someone who has already use the webBrowser control along with a proxys.
What I need is the following.
1 - Set a proxy for a webBrowser control.
2 - Load a specific site.
3 - Execute a routine over the site.
4 - Set a diferent proxy for the webBrowser control.
5 - Load another site.
6 - Execute the same routine from point number 3.
And the process keeps in that way, looping from a list of proxys, until all of them had been used.
But. I'm having some problems with the app. to do that:
1 - I'm using the code attached to set the proxy into the webBrowser control, but seems to work only once during the execution, when I call it again in the loop it just doesn't work, I can get t ounderstand why.
2 - I'm having problems to determine when the page has loaded completely, I mean, when I set the first site to load, I need the program to wait until it has finish to load, and after that execute the routine over it, and continue with the process.
Hope some one could help me with this...
/// The function that I'm using -----------------------------
private void SetProxy(string Proxy)
{
MessageBox.Show("Setting :" + Proxy);
string key = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
RegistryKey RegKey = Registry.CurrentUser.OpenSubKey(key, true);
RegKey.SetValue("ProxyServer", Proxy);
RegKey.SetValue("ProxyEnable", 1);
}
// The app logic --------------------------------------
SetProxy("190.97.219.38:80");
webBrowser1.Navigate("http://www.whatismyip.com/");
ExecuteRoutine();
SetProxy("187.93.77.235:80");
webBrowser1.Navigate("http://www.whatismyip.com/");
ExecuteRoutine();
SetProxy("109.235.49.243:80");
webBrowser1.Navigate("http://www.whatismyip.com/");
ExecuteRoutine();
Perhaps this link is useful:
http://blogs.msdn.com/b/jpsanders/archive/2011/04/26/how-to-set-the-proxy-for-the-webbrowser-control-in-net.aspx
I tested the code and it seemed to work. But two points are important:
It's not compatible to projects in compile mode "Any CPU" (x86 works fine)
JUST for HTTP proxy servers ; not for SOCKS
1- I guess webBrowser control checks the proxy only while its is created, so create a new control after setting the proxy
2- Navigate is not a blocking call and does not wait till page it loaded, use webBrowser.DocumentCompleted event
Below code should work (Not tested)
void Exec(string proxy,string url)
{
var th = new Thread(() =>
{
SetProxy(proxy);
using (WebBrowser wb = new WebBrowser())
{
wb.DocumentCompleted += (sndr, e) =>
{
ExecuteRoutine();
Application.ExitThread();
};
wb.Navigate(url);
Application.Run();
}
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
th.Join();
}
I had a somewhat similar question in the past. The accepted answer for the question suggests to take a look at this Microsoft Knowledge Base article:
"How to programmatically query and set proxy settings under Internet Explorer"
Basically, you have to do some P/Invoke and call some WinInet DLL functions. Although I never tried it in a real-world project, I strongly assume that this is the way to go.
Just to let you all know, this guy has posted 5 question, all asking the same thing, and based on his first question and how badly he was knocked down, it seems he is trying to commit some type of cybercrime. Now, based on my reading of his intellect, he'll probably end up in prison really quickly, but I'm just thinking perhaps we can save him from that by letting him know that it's not possible to provide an imaginary IP address to services you are communicating with (since if you did, the service will not be able to reach you to provide a response). Here is his entertaining list:
https://stackoverflow.com/questions/12045317/how-to-hide-my-ip-address-c-net-3-5
Use a proxy with webBrowser control C#/.net 3.5
how to pass ip-address to webBrowser control
how to use custom ip address to browse a web page c#/.net
https://stackoverflow.com/questions/12019890/how-to-load-webpage-using-user-provided-ipaddress-webbrowser-control-c-net
And now, I think he has created a new username, user1563019, with more proxy/settings questions below:
https://stackoverflow.com/users/1563019/user1563019
I am working with an ASP site which requires a "reminder" email to be sent out every x, y and z minutes. I have attempted to start a timer upon an event (like a button click or page load) but this proved to be unreliable as the timers would be disposed of when the server performed an automatic backup or when the aspx.cs file was updated.
My new idea is to have a timer constantly running (a check is performed on a page load which ensures its running) and, when it elapses, it checks to see if either x, y or z minutes have elapsed. So if y elapses, it needs to send out a "reminder" email and then restart y's timer.
void ParentTimer_Elapsed(object sender, ElapsedEventArgs e)
{
foreach(Timer childTimer in ChildTimerList)
{
if(childTimer.Enabled == false) // And therefore has elapsed
{
sendReminderEmail(childTimer);
childTimer = checkAndSetCorrectInterval(childTimer);
childTimer.AutoReset = false;
childTimer.Enabled = true;
}
}
}
The list ChildTimerList would obviously contain x, y and z.
Can anybody forsee me running into any problems with this, or are there any better ways to approach it? My perfect solution would be a timer running costantly which doesn't need to be started upon an event but I don't think this is possible with ASP.
Furthermore, where should I initialise my parent timer and childlist variables? In a class within the App_Code folder or, statically, in a code-behind aspx.cs page?
Thanks in advance.
EDIT:
Yes, I do mean ASP.NET... :)
I would probably implement this with a simple console application (responsible for sending e-mails) and Task Scheduler in Windows (responsible for running the application on a schedule). Keep it simple. And robust.
Edit: Provided that you are in control of the server - it will probably not be the best solution in a shared hosting environment where you're only allowed to run web apps.
Background
My son likes to use his laptop when he's not supposed to and I just thought it would be handy if I could write an application that would email me whenever he opened / closed his laptop.
(I'd even settle for something that notified me when there was network traffic on the machine)
Question
How do you programmatically detect when an OS is waking up or going to sleep? I found this link from this related post. But that covers OS X. I'm looking for the same thing for Windows 7.
(I'd like to do this in Java, if possible, but I'd settle for C#/C++)
Easiest way is not to write any code at all, even though this is stack overflow. Click Start, type Schedule and choose Scheduled Tasks. Set one up (click Create Task) and set a Trigger when the machine is unlocked. For the Action, have it send you an email.
Repeat for startup and when a user logs in, if you want. Done.
You're going to want to create a window and watch for the WM_POWERBROADCAST message (http://msdn.microsoft.com/en-us/library/aa373248%28v=vs.85%29.aspx) and check the wParam for your desired action. For example, your window should receive a WM_POWERBROADCAST with PBT_APMSUSPEND as the wParam when the system is about to enter a suspended state (i.e. closing a laptop). Resuming seems to have a few different wParam values: PBT_APMRESUMESUSPEND, PBT_APMRESUMECRITICAL and PBT_APMRESUMEAUTOMATIC
I search for a long time and found that this was the best way, the 'Sleep'-event was never working before:
private ManagementEventWatcher managementEventWatcher;
private readonly Dictionary<string, string> powerValues = new Dictionary<string, string>
{
{"4", "Entering Suspend"},
{"7", "Resume from Suspend"},
{"10", "Power Status Change"},
{"11", "OEM Event"},
{"18", "Resume Automatic"}
};
public void InitPowerEvents()
{
var q = new WqlEventQuery();
var scope = new ManagementScope("root\\CIMV2");
q.EventClassName = "Win32_PowerManagementEvent";
managementEventWatcher = new ManagementEventWatcher(scope, q);
managementEventWatcher.EventArrived += PowerEventArrive;
managementEventWatcher.Start();
}
private void PowerEventArrive(object sender, EventArrivedEventArgs e)
{
foreach (PropertyData pd in e.NewEvent.Properties)
{
if (pd == null || pd.Value == null) continue;
var name = powerValues.ContainsKey(pd.Value.ToString())
? powerValues[pd.Value.ToString()]
: pd.Value.ToString();
Console.WriteLine("PowerEvent:"+name);
}
}
public void Stop()
{
managementEventWatcher.Stop();
}
A very simple, perhaps crude, but effective way may be to have a program with a timer firing every minute. If the timer fires and it's been, say, 5 minutes of real time since its last execution then you can likely assume that the computer was sleeping since it's unlikely that your thread was unable to be scheduled for so long.
The other reason for the difference may be a clock adjustment, like DST or a manual change, but that kind of "noise" should be very low, in your scenario.
You could write a simple app and register it as a Windows service, to be started automatically at system startup. This app could then do whatever you want when it starts. And if it's a proper Windows app, it can register to get notification about impending system shutdown too (I don't remember the details but I implemented this in a C++ MFC app many years ago).
If you prefer Java, you could register your app as a service via a suitable service wrapper like Tanuki (it seems they have a free Community License option). Although this might be overkill. And it may be possible to get notification about the JVM shutting down when the system is closing (but I have no concrete experience with this).
http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation - Check out the link. It has almost all win32api for all windows function. You can call power management feature directly in your windows 7 laptop. For that create a Windows Service , that will use these specific api to notify the machine state.
I'm developing an application (winforms C# .NET 4.0) where I access a lookup functionality from a 3rd party through a simple HTTP request. I call an url with a parameter, and in return I get a small string with the result of the lookup. Simple enough.
The challenge is however, that I have to do lots of these lookups (a couple of thousands), and I would like to limit the time needed. Therefore I would like to run requests in parallel (say 10-20). I use a ThreadPool to do this, and the short version of my code looks like this:
public void startAsyncLookup(Action<LookupResult> returnLookupResult)
{
this.returnLookupResult = returnLookupResult;
foreach (string number in numbersToLookup)
{
ThreadPool.QueueUserWorkItem(lookupNumber, number);
}
}
public void lookupNumber(Object threadContext)
{
string numberToLookup = (string)threadContext;
string url = #"http://some.url.com/?number=" + numberToLookup;
WebClient webClient = new WebClient();
Stream responseData = webClient.OpenRead(url);
LookupResult lookupResult = parseLookupResult(responseData);
returnLookupResult(lookupResult);
}
I fill up numbersToLookup (a List<String>) from another place, call startAsyncLookup and provide it with a call-back function returnLookupResult to return each result. This works, but I found that I'm not getting the throughput I want.
Initially I thought it might be the 3rd party having a poor system on their end, but I excluded this by trying to run the same code from two different machines at the same time. Each of the two took as long as one did alone, so I could rule out that one.
A colleague then tipped me that this might be a limitation in Windows. I googled a bit, and found amongst others this post saying that by default Windows limits the number of simultaneous request to the same web server to 4 for HTTP 1.0 and to 2 for HTTP 1.1 (for HTTP 1.1 this is actually according to the specification (RFC2068)).
The same post referred to above also provided a way to increase these limits. By adding two registry values to [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings] (MaxConnectionsPerServer and MaxConnectionsPer1_0Server), I could control this myself.
So, I tried this (sat both to 20), restarted my computer, and tried to run my program again. Sadly though, it didn't seem to help any. I also kept an eye on the Resource Monitor while running my batch lookup, and I noticed that my application (the one with the title blacked out) still only was using two TCP connections.
So, the question is, why isn't this working? Is the post I linked to using the wrong registry values? Is this perhaps not possible to "hack" in Windows any longer (I'm on Windows 7)?
And just in case anyone should wonder, I have also tried with different settings for MaxThreads on ThreadPool (everything from 10 to 100), and this didn't seem to affect my throughput at all, so the problem shouldn't be there either.
It is matter of ServicePoint. Which provides connection management for HTTP connections.
The default maximum number of concurrent connections allowed by a ServicePoint object is 2.
So if you need to increase it you can use ServicePointManager.DefaultConnectionLimit property. Just check the link in MSDN there you can see a sample. And set the value you need.
For quicker reference for someone. To increase the connection limit per host you can do this in your Main() or anytime before you begin making the HTTP requests.
System.Net.ServicePointManager.DefaultConnectionLimit = 1000; //or some other number > 4
Fire and forget this method from your main method. Icognito user is correct, only 2 threads are allowed to play at the same time.
private static void openServicePoint()
{
ServicePointManager.UseNagleAlgorithm = true;
ServicePointManager.Expect100Continue = true;
ServicePointManager.CheckCertificateRevocationList = true;
ServicePointManager.DefaultConnectionLimit = 10000;
Uri MS = new Uri("http://My awesome web site");
ServicePoint servicePoint = ServicePointManager.FindServicePoint(MS);
}
For Internet Explorer 8:
Run Registry Editor and navigate to following key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTION SPERSERVER
and
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTION SPER1_0SERVER
If FEATURE_MAXCONNECTIONSPERSERVER and FEATURE_MAXCONNECTIONSPER1_0SERVER are missing then create them. Now create DWORD Value called iexplore.exe for both sub keys (listed above) and set their value to 10 or whatever number desired.