I'm trying to create a task scheduler that runs twice a day. I've implemented a task scheduler using CacheItemRemovedCallaback, as suggested in this post and this blog. I have the a feature that enables the admin to modified the scheduled times, and saves them on Application variables:
protected void UpdateSchedule(object sender, EventArgs e)
{
Button button = sender as Button;
if (button.ID == "scheduleButton1")
{
Application.Lock();
Application["buildSchedule1"] = GetScheduleTime1;
Application.UnLock();
}
else if (button.ID == "scheduleButton2")
{
Application.Lock();
Application["buildSchedule2"] = GetScheduleTime2;
Application.UnLock();
}
HttpRuntime.Cache.Remove(Global.DummyCachekey); //remove current scheduled task and set new time
}
And on Global.aspx I have:
protected void Application_Start(object sender, EventArgs e)
{
Application.Lock();
Application["buildSchedule1"] = new TimeSpan(10,00, 0); //default time
Application["buildSchedule2"] = new TimeSpan(16,00, 0); //default time
Application.UnLock();
SheduleTask();
};
The problem is that for some reason (probably due to app pool recycling) the schedule times get reset, and even some times the task won't start at the default times.
I found solutions that mention Windows services or Windows task scheduler, but that doesn't work for me since I need to be able to let the admin configure the times through the web application. (I search for this, but couldn't find anything).
I found solutions that mention Windows services or Windows task scheduler
That's what you should be using. A web application doesn't "always run." It responds to requests, that's all. Unless something is actively making a request to the website, it's not doing anything.
but that doesn't work for me since I need to be able to let the admin configure the times through the web application
Sure it does. More than one application can share a single database. In this case you'd have two applications:
A Web Application where users can login and maintain the data related to the scheduled tasks.
A Windows Service (or scheduled Console Application) which runs in the background on the server and executes the configured tasks which it reads from the database.
Using hacks like Windows Scheduled Tasks and Control Panel abilities are not nice solutions. They sucks most of the time, they are a headache.
You can use ATrigger scheduling service. A .Net library is also available to create scheduled tasks without overhead.
//Tags: Tags are required to identify tasks.
//read more at: http://atrigger.com/docs/wiki/9/rest-api-v10-parameter-tag_
Dictionary<string, string> tags = new Dictionary<string, string>();
tags.Add("type", "test");
//Create
ATrigger.Client.doCreate(TimeQuantity.Hour(), "12", "http://www.example.com/myTask?something", tags);
Disclaimer: I was among the ATrigger team. It's a freeware and I have not any commercial purpose.
Related
I have this kind of Task
private async Task SaveToFile(StorageFile file)
{
// prepare data
await ...
Debug.Writeline("completed");
}
If the user press "back" button this task won't be completed. I need a way to make it go on until all it's done, even if the calling app is not running any more.
You have To use "background Task" for this. Its pretty simple,
create a new project for background tasks and add it to your solution, because your background task is a not a simple class its a separate WINRT project. To do this, right-click on your solution node in the Solution Explorer and select Add->New Project. Then select the Windows Run-time Component (Universal Windows) project type, name the project, and click OK. I named here "BackgroundStuff". You can create more than one background task for single application. there is no any limit.
Consider simple example to generate toast even App is not running:
private async void button_Click(object sender, RoutedEventArgs e)
{
string myTaskName = "MyBackgroundClass";
// check if task is already registered
foreach (var cur in BackgroundTaskRegistration.AllTasks)
if (cur.Value.Name == myTaskName)
{
await (new MessageDialog("Task already registered")).ShowAsync();
return;
}
// Windows Phone app must call this to use trigger types (see MSDN)
await BackgroundExecutionManager.RequestAccessAsync();
// register a new task
BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder { Name = "MyBackgroundClass", TaskEntryPoint ="MybackgroundStuff.MyBackgroundClass" };
taskBuilder.SetTrigger(new TimeTrigger(15, true));
BackgroundTaskRegistration myFirstTask = taskBuilder.Register();
If you want to learn more , refer my blog:
http://windowsapplife.blogspot.in/
No, you can not force a Task to keep running, if the parent process is terminated.
That said, the issue you've described is not really an issue unless your file takes longer than 10 seconds to save (which is an eternity, in computer lingo).
Windows Phone apps continue to run in the background for up to 10 seconds, after the user 'backs' out of it, or manually quits. This should be enough time for any application to finish its 'cleanup' operations.
See: App Lifecycle Windows Runtime Apps
See also: App activation and deactivation for Windows Phone 8
I am trying to access application history from C#. I would like to present same information as in task manager, but I cannot find api/example. Of course I implement a desktop application.
To specify problem: I am not interested on CPU/RAM. The only thing I would like to get is Time.
UPDATE
To exactly show what I am talking about look at this screen:
There is no supported way to get this information. Sorry.
The description of the questions lacks details that you are talking about Metro Apps. The solution would be an equivalent of Process.TotalProcessorTime but for Metro Apps.
Unfortunately, you cannot get that information because as you stated the applications are running within another process (WWAHost.exe). The design of Metro is a bit more like the phone - you can't directly manipulate the system in the same way. There isn't a directly "Process" in the Windows Runtime (see here), which in turn means the Process class wouldn't make sense to port...
I assume by The only thing I would like to get is Time. you mean the start and end time of each process
The best way will be that you will have to build that history your self. If you need the history only when your application is running then you just implement the code bellow otherwise if you wish to build the history for a certain period even when your application is down then try to create a Windows service that does the job for you. Following are the steps you need to do assuming you know how to create a windows service project, compile and install it:
Getting running processes info :
using System;
using System.Diagnostics;
public static class ProcessStart
{
Process[] runningProcesses;
var processesStartTimes = new Dictionary<int, Datetime>();
var processesExitTimes = new Dictionary<int, Datetime>();
static ProcessStart()
{
// This will get current running processes
runningProcesses = Process.GetProcesses();
foreach (var p in processes)
{
p.Exited += new EventHandler(ProcessExited);
processesStartTimes.Add(p.Id, p.StartTime);
}
}
private void ProcessExited(object sender, System.EventArgs e)
{
var p = (Process)sender;
processesExitTimes.Add(p.Id, p.ExitTime);
}
}
Getting new started processes
You need to create a new Timer object and run it every second checking for new created processes. I copied the code above and extended it :
public static class ProcessStart
{
Process[] runningProcesses;
var processesStartTimes = new Dictionary<int, Datetime>();
var processesExitTimes = new Dictionary<int, Datetime>();
var updateTimer = new Timer(1000);
static ProcessStart()
{
// This will get current running processes
runningProcesses = Process.GetProcesses();
foreach (var p in processes)
{
p.Exited += new EventHandler(ProcessExited);
processesStartTimes.Add(p.Id, p.StartTime);
}
updateTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}
private void ProcessExited(object sender, System.EventArgs e)
{
var p = (Process)sender;
processesExitTimes.Add(p.Id, p.ExitTime);
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
runningProcesses = Process.GetProcesses();
foreach (var p in processes)
{
// This will only add the processes that are not added yet
if (!processesStartTimes.Keys.Contains(p.Id))
{
p.Exited += new EventHandler(ProcessExited);
processesStartTimes.Add(p.Id, p.StartTime);
}
}
}
}
Finally :
You just then need to play with the System.Diagnostics.Process class. That should be your best way for getting all information you need about windows processes. It will grant you access to a wide range of properties and methods. Here is the official MSDN lik for it:
Process Class
EDIT :
As I can see from your comment, you are interested in the time the CPU have spent running a specific process. The same System.Diagnostics.Process class contains that info as well. That can be found using the Process.PrivilegedProcessorTime property. The MSDN description for this property is :
A TimeSpan that indicates the amount of time that the process has spent running code inside the operating system core.
More information Here
EDIT 2:
The following 2 Properties could also give you probably what you need:
Process.UserProcessorTime : Here
A TimeSpan that indicates the amount of time that the associated process has spent running code inside the application portion of the process (not inside the operating system core).
Process.TotalProcessorTime : Here
A TimeSpan that indicates the amount of time that the associated process has spent utilizing the CPU. This value is the sum of the UserProcessorTime and the PrivilegedProcessorTime.
I've done some research on this, because I found it to be interesting how the metro apps integrate into the existing process structure.
As other people have pointed out here, it is not possible in a beautiful supported API way to get the info you want.
However, every app is launched as a different process and for processes there are known ways to get run time, cpu time etc.
If you find the correspondig process to your windows 8 app, you will be able to get the info you need.
Some apps are really easy to spot. They are just a executable like any other desktop application with a proper processname and description.
For example in this picture "Map", "Windows Reader" and "Microsoft Camera Application":
Some other apps are a bit harder to spot. They are hosted in a process that is launched by the wwahost.exe executabe. I could only spot the app name by looking at the module list.
This is the Bing app:
To enumerate the modules and mapped files from a process you can use the WinAPIs VirtualQueryEx and GetMappedFileName.
Then you want to look for files that are located at %programfiles%\WindowsApps. This is the folder where windows saves all the application files for it's apps.
Every app has a .pri file. This file contains binary metadata of the application. You could use it to find the name of the app from the process that is hosting it. In the same folder with the .pri file there is a AppxManifest.xml in which you could find all kinds of additional information about the app.
I will try to summarize my writing a bit:
enumerate processes with WinAPI and get all infos you need (run time, cpu time, etc).
enumerate mapped files of each process and look for ressources.pri. The directory where this file is located has the app name in it.
as bonus read the AppxManifest.xml file for additional info on the app. You might need Administrator privilege or additional privileges to read this file.
I want to poll a directory to check whether new file is added to the directory in ASP.NET web application (C#). If any new file is added I want to read that file.
Can anybody give me an idea how to do that?
Thanks.
Normally you would use the FileSystemWatcher class. However, you have another problem. A web application isn't really suited for background processes. You can get away with it by using a background task and threading in general, but it's probably not a good idea. Always assume that your web application is stateless and can be re-started by the server at any time.
Ask yourself:
What is going to trigger this polling?
How is the application going to respond to this polling?
A web application is essentially a request/response system. Thus, any server-side logic (such as the polling) should be triggered by a request. But once the response is given, what is going to become of the polling? Suppose you fork off a thread in the web application which will poll in the background. What is it going to do when it finds something? There's no request/response interacting with it at that point.
Could this polling perhaps be delegated to another application? Perhaps a Windows Service? Then, in response to finding something during the polling, it can modify values in the web application's database. That way future requests to the web application would see the updated state.
This would more cleanly separate the concerns on an architectural level.
you can use FileSystemWatcher and create the instance in Application_Start event.
Sample code:
protected void Application_Start(
Object sender, EventArgs e)
{
FileSystemWatcher fsw =
new FileSystemWatcher(
Server.MapPath( “.” ) );
Application.Add( “myfsw” , fsw );
// Add event handlers here
fsw.EnableRaisingEvents = true;
}
Dispose this when application ends.
protected void Application_End(
Object sender, EventArgs e)
{
FileSystemWatcher fsw =
(FileSystemWatcher
)Application[“myfsw”];
Application.Remove( “myfsw” );
fsw.Dispose();
}
First after your program loads check the directory content and keep it as a list.After that add a timer. The timer will check the content of the directory and compare the current content with the last logged content. After comparing you can see which files are changed in the directory.
you can change the frequency of the timer based on your needs.
Hope it helps.
edit:
call GetDirectoryContent(); in your program's onload.
FileInfo[] lastUpdatedFies;
FileInfo[] temporaryFiles;
private void GetDirectoryContent()
{
DirectoryInfo di = new DirectoryInfo("c:/mydirectorypath/");
lastUpdatedFies = di.GetFiles(".");
}
private void GetDirectoryContent()
{
DirectoryInfo di = new DirectoryInfo("c:/mydirectorypath/");
lastUpdatedFies = di.GetFiles("*.*");
}
protected void tmrDirectory_Tick(object sender, EventArgs e)
{
DirectoryInfo di = new DirectoryInfo("c:/mydirectorypath/");
temporaryFiles = di.GetFiles("*.*");
foreach (FileInfo f in lastUpdatedFies)
{
//compare the list of files and do whatever you want.
// you can track any kind of data this way.
}
}`
you can also adjust the timer frequency. In this example i just kept track of files.so you will learn only if a file is deleted or added. if you want to keep track of the file size you can also do it in the same way.
Add Filewatcher in global.asmx when the application start event.
It's not clear, what do you want to do with these files. If you want read these files and cache them for future output, you can use ASP.NET Cache with CacheDependency on specific directory and a callback which will re-read the directory and add new file to cache. You should take a look at Cache.Insert method and CacheDependency constructor
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();
}
}
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.