How to monitor (observe) a computer. Part 1 - taking screenshots of users

Making screenshots of users. Let's discuss the implementation in the C # programming language.





The method described in this article is simple, no unnecessary functionality. You can use off-the-shelf development or modify the source code as you like. There will be a link to GitHub at the end of the article.





Required functionality:





  1. The program should take screenshots





  2. Programs should not be visible on the taskbar

























:





Main :





 static void Main(string[] args)
 {
     Log.Instance.Info($"started");

     //   
     var handle = GetConsoleWindow();
     ShowWindow(handle, SW_HIDE);

     //  
     ReadSettings();

     //     
     while (true)
     {
          //  
          CheckStorage();

          //  
          DoScreen();

          //   
          Thread.Sleep(_interval * 1000);
     }
 }
      
      



:





ReadSettings -

CheckStorage -

DoScreen -





ReadSettings ( )

Visual Studio . .

interval - ,

limit - , MB

path - , C:\temp





.





/// <summary>
///    ,  
/// </summary>
static int _interval { get; set; }

/// <summary>
///   ,  MB
/// </summary>
static int _limit { get; set; }

/// <summary>
///    ,  C:\temp
/// </summary>
static string _path { get; set; }
      
      



Screenshoter.exe.config Screenshoter.exe. .





/// <summary>
///     
/// </summary>
static void ReadSettings()
{
    _interval = 10;
    if (Properties.Settings.Default.interval > 0) _interval = Properties.Settings.Default.interval;
    Log.Instance.Info($"set interval = {_interval} sec");

    _limit = 20;
    if (Properties.Settings.Default.limit > 0) _limit = Properties.Settings.Default.limit;
    Log.Instance.Info($"set storage = {_limit} Mb");

    _path = @"C:\temp";
    if (!string.IsNullOrEmpty(Properties.Settings.Default.path)) _path = Properties.Settings.Default.path;
    Log.Instance.Info($"set path = {_path}");
}
      
      



CheckStorage ( )

: , .





/// <summary>
///     
/// </summary>
static void CheckStorage()
{
    var currentSize = StorageSize();

    if (currentSize > _limit)
    {
        //    MB
        var totalToTrash = currentSize - _limit;

        //   - KB
        StorageClear(totalToTrash * 1024);
    }
}
      
      



StorageSize StorageClear.



StorageSize KB. KB (), MB () ? 1 1 , 1 5 1 .



StorageSize , ( ).





/// <summary>
///  ,  MB
/// </summary>
/// <returns></returns>
static long StorageSize()
{
    long i = 0;

    try
    {
        DirectoryInfo directory = new DirectoryInfo(_path);
        FileInfo[] files = directory.GetFiles();

        foreach (FileInfo file in files)
        {
            i += file.Length;
        }
    }
    catch (Exception ex)
    {
        Log.Instance.Error(3, ex.Message);
        return _limit;
    }

    return i /= (1024 * 1024);
}
      
      



StorageClear . , , .





/// <summary>
///  
/// </summary>
/// <param name="sizeKb"></param>
static void StorageClear(long sizeKb)
{
    try
    {
        Log.Instance.Info($"clear = {sizeKb} Kb");

        DirectoryInfo directory = new DirectoryInfo(_path);
        FileInfo[] files = directory.GetFiles().OrderBy(f => f.CreationTime).ToArray();

        foreach (FileInfo file in files)
        {
            var size = file.Length / 1024;
            File.Delete(file.FullName);
            sizeKb -= size;
            if (sizeKb <= 0) break;
        }
    }
    catch (Exception ex)
    {
        Log.Instance.Error(2, ex.Message);
    }
}
      
      



DoScreen ( )

. - PNG. . , Log .





/// <summary>
///  
/// </summary>
static void DoScreen()
{
    try
    {
        Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        Graphics graphics = Graphics.FromImage(printscreen as Image);
        graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);
        printscreen.Save(Path.Combine(_path, GetFileName()), System.Drawing.Imaging.ImageFormat.Png);
    }
    catch (Exception ex)
    {
        Log.Instance.Error(1, ex.Message);
    }
}

/// <summary>
///    
/// </summary>
/// <returns></returns>
static string GetFileName()
{
    var time = DateTime.Now;
    return $"{time.ToString("yyyy_MM_dd__HH_mm_ss")}.png";
}
      
      



. Main.





#region DllImport

[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

const int SW_HIDE = 0;
const int SW_SHOW = 5;

#endregion
      
      



Log Singleton ().





public sealed class Log
{
    private static volatile Log _instance;
    private static readonly object SyncRoot = new object();
    private readonly object _logLocker = new object();

    private Log()
    {
        CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
        LogDirectory = Path.Combine(CurrentDirectory, "log");
    }

    public string CurrentDirectory { get; set; }
    public string LogDirectory { get; set; }

    public static Log Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (SyncRoot)
                {
                    if (_instance == null) _instance = new Log();
                }
            }
            return _instance;
        }
    }

    public void Error(int errorNumber, string errorText)
    {
        Add($" {(errorNumber.ToString()).PadLeft(4, '0')}: {errorText}", "[ERROR]");
    }

    public void Info(string log)
    {
        Add(log, "[INFO]");
    }

    private void Add(string log, string logLevel)
    {
        lock (_logLocker)
        {
            try
            {
                if (!Directory.Exists(LogDirectory))
                {
                    //   log   
                    Directory.CreateDirectory(LogDirectory);
                }
                //          .
                string newFileName = Path.Combine(LogDirectory, String.Format("{0}.txt", DateTime.Now.ToString("yyyyMMdd")));
                File.AppendAllText(newFileName, $"{DateTime.Now} {logLevel} {log} \r\n", Encoding.UTF8);
            }
            catch { }
        }
    }
}
      
      












All Articles