Wednesday, May 29, 2013

Transmitting Intervaled Screen Captures

This article shows how  to periodically capture the entire desktop and store it to files and optionally transmit the captured files on the Internet. The code is in C# and so the program only supports operating systems where C# desktop apps could run: mainly Windows-based systems.

I've chosen a hidden Windows app as my main driver. You could have very well chosen a console or a service process as your main driver. The app is hidden from ordinary users (of course there are ways to detect that the app is running in the background).

The app starts a timer and on timed-interval checks for the existence of a resource or an event to determine whether it should gracefully terminate or do another screen capture. The external resource in our case is a text file that the administrator could dump into a known or configured folder. The existence of the file signals to the app that it ought to terminate;  otherwise the app captures the entire desktop and dumps it to a file in the configured folder.

The "timer repetition interval", "folder name", "capture base file name", "termination file name",  "maximum number of files to write" are configured in app.config.

The capture file name is computed as: configured capture base file name + Counter + .extension.
Above the Counter is an integer that is incremented in our app. When the Counter reaches "maximum number of files to write" the Counter is reset to 0 and we would override the previously written files.

On my next article I will touch upon transmitting the captured files to the Internet. From that point possibilities are only limited by our imagination: the app could be used as a monitoring tool, replace rudimentary video conferencing tools, etc.

The C# code is listed below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Drawing;
using System.Text;
using System.Drawing.Imaging;
using System.IO;
using System.Configuration;

namespace WindowsFormsApplication1
{
    static class Program
    {
        ///



        /// The main entry point for the application.
        ///
        [STAThread]
        static void Main()
        {
              Timer MyTimer = new Timer();
              //  mins converted to milliseconds
              MyTimer.Interval = (Convert.ToInt32(ConfigurationManager.AppSettings["CaptureMinutesInterval"]) * 60 * 1000);
                MyTimer.Tick += new EventHandler(Timer_Tick);
                MyTimer.Start();
                Application.Run();

        }
        static int counter = 0;
        private static void Timer_Tick(object sender, EventArgs e)
        {
            if (File.Exists(ConfigurationManager.AppSettings["FilePath"] + ConfigurationManager.AppSettings["EndFile"]))
            {
                Application.Exit();
                return;
            }


            if (!System.IO.Directory.Exists(ConfigurationManager.AppSettings["FilePath"]))
            {
                System.IO.Directory.CreateDirectory(ConfigurationManager.AppSettings["FilePath"]);
            }

         
            int screenWidth = Screen.GetBounds(new Point(0, 0)).Width;
            int screenHeight = Screen.GetBounds(new Point(0, 0)).Height;

            // Rectangle bounds = Screen.GetBounds(Point.Empty);
            using (Bitmap bitmap = new Bitmap(screenWidth, screenHeight))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
                }
                // could use other extensions
                bitmap.Save(ConfigurationManager.AppSettings["FilePath"] + ConfigurationManager.AppSettings["CapBaseName"] + counter +
                    ".png", ImageFormat.Png);
                counter++;
                if (Convert.ToInt32(ConfigurationManager.AppSettings["MaxFiles"]) > counter)
                {
                    counter = 0;
                }
            }
        }
    }
}




 
   
   
   
   
   
 
 

Monday, January 7, 2013

Receiving and returning JSON data in C# and MVC

Suppose you have a C# class as follows:
    [Serializable]
    public class Spec
    {
        public string ID { get; set; }
        public int TypeID { get; set; }
        public string Value { get; set; }
        public int ForID { get; set; }
    }

To send an array of Specs from Javascript on the browser to an MVC controller you may issue:

         $.ajax({
            url: "/Create/UpdateSpecs",
            cache: false,
            data: { "SkuID": PID, "Specs": JSON.stringify(aspecs)
            },
            type: "POST"
        });

1) /Create/UpdateSpecs is your server-side endpoint.

2) JSON.stringify is from the JSON library. You may need to download jquery.json-2.2.js (or newer) if you you need to support older browsers.

3) To construct an array of Specs in Javascript you may issue something like the following code snippet where aspecs is your array of specs in Javascript and cnt is your array index:
aspecs[cnt] = { "ID": item.attr("id"), "TypeID": item.attr("typeid"), "Value": item.val(), "ForID": item.attr("for") };

On the C# MVC side, below, Specs has your JSON array that you could convert to a C# array by
calling JsonConvert.DeserializeObject and casting as array of Specs as follows:

 (Spec[])JsonConvert.DeserializeObject(Specs);

1) Important: You must have a reference to the library:
Newtonsoft.Json

2) The C# method returns a JsonResult. The return could be a complex data structure or a basic or intrinsic type.

        [HttpPost]
        public JsonResult UpdateSpecs(int SkuID, string Specs)
        {
            if (!string.IsNullOrEmpty(Specs))
            {
                Spec[] args = (Spec[])JsonConvert.DeserializeObject(Specs);

                ProductBinder UIBinder = new ProductBinder();


                return this.Json(UIBinder.UpdateSpecs(args, SkuID));
            }
            else
            {
                return null;
            }
        }
     
       
         
         
           
         
         
       
       
         
         
           
         
         
       
     
   

Wednesday, November 28, 2012

For AJAX cross-site calls there is JSONP and there is:
jQuery.support.cors = true;

http://dhanushkaat.blogspot.com/2011/11/performing-cross-domain-requests-with.html

Wednesday, October 3, 2012

javascript/jquery: Adjusting div height as window height changes


$(function () {

    function winresize() {
        var windowHeight = $(window).height();
        if (windowHeight > 300) {
            windowHeight = windowHeight - 200;
        }

        $("#bboard").css("margin-top", windowHeight);
    }

    winresize();

    $(window).resize(function () {
        winresize();
    });
});

Wednesday, August 15, 2012

Thursday, March 22, 2012

selecting drop down index with JQUery

Use the .attr('selectedIndex') property. For example

$("#testselect").attr('selectedIndex', 1);

Thursday, February 2, 2012

determining row in an item template using the row index:

http://www.ezzylearning.com/tutorial.aspx?tid=7597714

javascript:

row = $(editButton).parent().parent();
id = $("#id", row).text();
name = $("#name", row).text();
fee = $("#fee", row).text();
row.addClass("highlightRow");

html template: