海运的博客

windows下定时截屏对比相似度并关机/待机

发布时间:November 20, 2020 // 分类: // No Comments

先判断上次键盘鼠标活动时间,如果时间较长则隔一段时间截屏判断是否在看视频,如果图片符合相似度则执行待机操作。

#include <windows.h>
#include "bitmap.h"
#include "stdio.h"
#include <time.h>
#include <stdlib.h>
#include <PowrProf.h>
#include <math.h>

void echo(CHAR *str);
int getlastinput();
int CheckFullscreen();
int CaptureImage(CHAR *lpbitmap, int width, int height);
int save(char *outfile, CHAR *lpbitmap, DWORD dwBmpSize, int width, int height);

void echo(CHAR *str) {
  //MessageBox(NULL, str, NULL, MB_OK);
  time_t t1;
  struct tm *newtime;
  char time_str[128];
  t1 = time(NULL);
  newtime=localtime(&t1);
  strftime(time_str, 128, "%Y%m%d_%H%M%S", newtime);
  printf("%s:  %s \n", time_str, str);
  //printf("%s \n", str);
}

int main(int argc, char *argv[]) {
  INT width  = GetSystemMetrics(SM_CXSCREEN);  // 屏幕宽
  INT height = GetSystemMetrics(SM_CYSCREEN);  // 屏幕高
  DWORD dwBmpSize = width *  height * 4;
  INT  WidthBytes = width * 4;
  if (argc == 1) {
    printf("use sleep_time(sec) idle_time(min) similarity(<100) save_bmp(1) debug(1)\n");
    exit(1);
  }
  int sleep_idle, sleep_time, idle_time, save_bmp, debug;
  sleep_idle = sleep_time = idle_time = save_bmp = debug = 0;
  float similarity = 0;
  if (argc > 1)
    sleep_time = atoi(argv[1]);
  if (argc > 2)
    idle_time = atoi(argv[2]);
  if (argc > 3)
    similarity = atof(argv[3]);
  if (argc > 4)
    save_bmp = atoi(argv[4]);
  if (argc > 5)
    debug = atoi(argv[5]);
  if (!sleep_time && !idle_time) {
    exit(1);
  }
  if (sleep_time >= 30) {
    sleep_idle = round(sleep_time/5);
    printf("sleep_idle  = %d\n",  sleep_idle);
    sleep_idle = sleep_idle * 1000;
  } else {
    sleep_idle = sleep_time * 1000;
  }
  sleep_time = sleep_time * 1000; //sec
  idle_time = idle_time * 60 * 1000; //min

  HANDLE hDIB;
  hDIB = GlobalAlloc(GHND, dwBmpSize);
  CHAR *lpbitmap = (char *)GlobalLock(hDIB);
  HANDLE hDIB2;
  hDIB2 = GlobalAlloc(GHND, dwBmpSize);
  CHAR *lpbitmap2 = (char *)GlobalLock(hDIB2);

  if (!CaptureImage(lpbitmap, width, height)) {
    exit(1);
  }

  while (1) {
    //CheckFullscreen();
    long int idle = getlastinput();
    printf("%d \n", idle);
    if (!debug && idle < idle_time) {
      echo ("idle");
      Sleep(sleep_idle);
      continue;
    }
    if (!CaptureImage(lpbitmap2, width,height)) {
      Sleep(5*1000);
      continue;
    }

    int count = 0;
    int cmp = 0;
    int index = 0;
    for (int i = 0;i < width;++i)
    {
      for (int j = 0;j < height;++j)
      {
        count++;
        index = i * 4 + j * WidthBytes;
        if (lpbitmap[index + 2] != lpbitmap2[index + 2] || lpbitmap[index + 1] != lpbitmap2[index + 1] || lpbitmap[index + 0] != lpbitmap2[index + 0]) {
          cmp++;
        }
        //BYTE r = lpbitmap[index + 2];
        //BYTE g = lpbitmap[index + 1];
        //BYTE b = lpbitmap[index + 0];
        //printf("r  = %d\n",  r );
        //printf("g  = %d\n",  g );
        //printf("b  = %d\n",  b );
        //printf("index = %d\n",  index);
        //Sleep(1000);
      }
    }

    printf("count = %d\n", count);
    printf("cmp = %d\n", cmp);
    float percentage = (float)cmp / count * 100.0;
    printf("Percentage = %.2f%%\n", percentage);
    if (!debug && percentage <= similarity) {
      echo("SetSuspendState");
      SetSuspendState(0, 1, 1);
      Sleep(60*1000);
    }

    if (save_bmp == 1 && percentage <= similarity) {
      time_t t1;
      struct tm *newtime;
      char time_str[128];
      char outfile[128];
      t1 = time(NULL);
      newtime=localtime(&t1);
      //strftime(outfile, 128, "%Y%m%d_%H%M%S.bmp", newtime);
      strftime(time_str, 128, "%Y%m%d_%H%M%S", newtime);
      sprintf(outfile,"%s_1_%.2f%%.bmp",time_str,percentage);
      save(outfile,lpbitmap, dwBmpSize, width, height);
      sprintf(outfile,"%s_2_%.2f%%.bmp",time_str,percentage);
      save(outfile,lpbitmap2, dwBmpSize, width,height);
    }

    memcpy(lpbitmap, lpbitmap2, dwBmpSize);
    Sleep(sleep_time);
  }
  // 解锁堆内存并释放
  GlobalUnlock(hDIB);
  GlobalFree(hDIB);
  GlobalUnlock(hDIB2);
  GlobalFree(hDIB2);
  return 0;
}


int CaptureImage(CHAR *lpbitmap, int width, int height)
{
  int ret = 1;
  //GetDesktopWindow()
  HDC hScreenDC = GetDC(NULL); //获取显示设备上下文环境
  HDC hMemoryDC = CreateCompatibleDC(hScreenDC); // 创建与显示设备兼容的内存下文环境(设备描述表)
  if (!hMemoryDC) {
    echo(TEXT("CreateCompatibleDC has failed"));
    ret = 0;
    goto done;
  }

  //创建一个与显示设备描述表兼容的位图
  HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
  if (!hBitmap) {
    echo(TEXT("CreateCompatibleBitmap Failed"));
    ret = 0;
    goto done;
  }

  //把位图选到内存设备描述表中
  SelectObject(hMemoryDC, hBitmap);
  //HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemoryDC, hBitmap);
  //把屏幕设备描述表拷贝到内存设备描述表中。
  if (!BitBlt(
        hMemoryDC,    // 目的DC
        0, 0,        // 目的DC的 x,y 坐标
        width, height, // 目的 DC 的宽高
        hScreenDC,   // 来源DC
        0, 0,        // 来源DC的 x,y 坐标
        SRCCOPY))    // 粘贴方式
  {
    echo(TEXT("BitBlt has failed"));
    ret = 0;
    goto done;
  }

  //BITMAP bmpScreen;
  //Get the BITMAP from the HBITMAP
  //GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);
  //hBitmap = (HBITMAP) SelectObject(hMemoryDC, hOldBitmap);

  BITMAPINFOHEADER bi;
  bi.biSize = sizeof(BITMAPINFOHEADER);
  bi.biWidth = width;
  bi.biHeight = height;
  bi.biPlanes = 1;
  bi.biBitCount = 32;
  bi.biCompression = BI_RGB;
  bi.biSizeImage = 0;
  bi.biXPelsPerMeter = 0;
  bi.biYPelsPerMeter = 0;
  bi.biClrUsed = 0;
  bi.biClrImportant = 0;

  // 获取兼容位图的位并且拷贝结果到一个 lpbitmap 中.
  GetDIBits(
      hScreenDC,  // 设备环境句柄
      hBitmap,  // 位图句柄
      0,          // 指定检索的第一个扫描线
      (UINT)height, // 指定检索的扫描线数
      lpbitmap,   // 指向用来检索位图数据的缓冲区的指针
      (BITMAPINFO *)&bi, // 该结构体保存位图的数据格式
      DIB_RGB_COLORS // 颜色表由红、绿、蓝(RGB)三个直接值构成
      );

  //printf("sizeof((LPSTR)lpbitmap) = %d\n", sizeof((LPSTR)lpbitmap));
  //printf("sizeof(lpbitmap[0]) = %d\n", sizeof(lpbitmap[0]));

done:
  DeleteObject(hBitmap);
  DeleteObject(hMemoryDC);
  //DeleteDC(hMemoryDC);
  ReleaseDC(NULL, hScreenDC);
  return ret;
}

int getlastinput()
{
  long int      newTicks;        // time value for new ticks
  long int      inputTicks;      // time value for current time
  long int      elapsedTicks;    // time value for elapsed time
  LASTINPUTINFO lii;             // Structure for Windows time stuff

  // Set size of lii.cbsize
  lii.cbSize = sizeof(lii);

  // Get the time of the most recent (new) user input
  GetLastInputInfo(&lii);
  newTicks = lii.dwTime;

  inputTicks = GetTickCount();
  elapsedTicks = inputTicks - newTicks;

  return elapsedTicks;
}

int CheckFullscreen() {
  int bFullScreen = 0;
  HWND hWnd = GetForegroundWindow();
  RECT rcApp, rcDesk;
  GetWindowRect(GetDesktopWindow(), &rcDesk);

  if (hWnd!=GetDesktopWindow() && hWnd!=GetShellWindow()) {
    GetWindowRect(hWnd, &rcApp);
    if (rcApp.left<=rcDesk.left && rcApp.top<=rcDesk.top && rcApp.right>=rcDesk.right && rcApp.bottom>=rcDesk.bottom) {
      char wnd_name[256];
      char wnd_title[256];
      GetWindowText(hWnd,wnd_title,sizeof(wnd_title));
      GetClassName(hWnd, wnd_name, sizeof(wnd_name));
      printf("title: %s\n", wnd_title);
      printf("name: %s\n", wnd_name);

      if (strcmp(wnd_name, "Windows.UI.Core.CoreWindow") != 0 && strcmp(wnd_name, "WorkerW") != 0){
        bFullScreen =1;
      }
    }
  }
  return bFullScreen;
}

int save(char *outfile, CHAR *lpbitmap, DWORD dwBmpSize, int width, int height) {
  HANDLE hFile;
  DWORD dwSizeofDIB;
  DWORD dwBytesWritten;
  BITMAPFILEHEADER bmfHeader;

  BITMAPINFOHEADER bi;
  bi.biSize = sizeof(BITMAPINFOHEADER);
  bi.biWidth = width;
  bi.biHeight = height;
  bi.biPlanes = 1;
  bi.biBitCount = 32;
  bi.biCompression = BI_RGB;
  bi.biSizeImage = 0;
  bi.biXPelsPerMeter = 0;
  bi.biYPelsPerMeter = 0;
  bi.biClrUsed = 0;
  bi.biClrImportant = 0;

  // 创建一个文件来保存文件截图
  hFile = CreateFile(
      outfile,
      GENERIC_WRITE,
      0,
      NULL,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL,
      NULL
      );

  // 将 图片头(headers)的大小, 加上位图的大小来获得整个文件的大小
  dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

  // 设置 Offset 偏移至位图的位(bitmap bits)实际开始的地方
  bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

  // 文件大小
  bmfHeader.bfSize = dwSizeofDIB;

  // 位图的 bfType 必须是字符串 "BM"
  bmfHeader.bfType = 0x4D42; //BM

  dwBytesWritten = 0;
  WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
  WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
  WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
  // 关闭文件句柄
  CloseHandle(hFile);
  return 0;
}

使用tdm-gcc编译:

gcc screen.c -o screen.exe -lgdi32 -lPowrprof

参考:
https://docs.microsoft.com/zh-cn/windows/win32/gdi/capturing-an-image?redirectedfrom=MSDN
https://lellansin.wordpress.com/2014/03/16/c-gdi-%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE/
https://bbs.csdn.net/topics/390838652?page=4
https://bbs.csdn.net/topics/340205786?page=2
https://blog.csdn.net/haogeai123/article/details/7030583

ubuntu安装smokeping并配置nginx fastcgi

发布时间:November 16, 2020 // 分类: // No Comments

使用apt安装smokeping不安装apache,cgi文件位于/usr/share/smokeping/smokeping.cgi, 其它文件位于/usr/share/smokeping/www目录。

apt install --no-install-recommends smokeping
apt install fcgiwrap

nginx配置文件:

server {
        listen     88;
        charset utf-8;

        location / {
                root /usr/share/smokeping/www/;
        }
        location ~ /$ {
                root /usr/share/smokeping/;
                index smokeping.cgi;
        }
        location ^~ /smokeping/ {
                alias /usr/share/smokeping/www/;
        }
        location ~ .*\.(cgi|sh)$ {
                gzip off;
                root /usr/share/smokeping/;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass  unix:/var/run/fcgiwrap.socket;
        }
        access_log off;
}

smokeping配置文件目录:

grep cfg /usr/share/smokeping/smokeping.cgi
my $cfg = (shift @ARGV) || "/etc/smokeping/config";

修改data目录,datadir目录smokeping要有读写权限,dyndir目录fcgiwrap运行用户www-data要有读写权限。

cat /etc/smokeping/config.d/pathnames
datadir  = /mnt/smokeping/data
dyndir = /mnt/smokeping/data/__cgi

修改检测频率每60秒10次,也可在Probes内设置,注意再次修改要删除数据。

cat /etc/smokeping/config.d/Database 
step     = 60
pings    = 10

Probes配置:

*** Probes ***

+ FPing
binary = /usr/bin/fping
step = 60
pings = 20
#mininterval = 0.05
#timeout = 0.5

+ DNS
binary = /usr/bin/dig
forks = 2
lookup = google.com
step = 60
pings = 10

+Curl
binary = /usr/bin/curl
forks = 5
step = 60
pings = 10
timeout = 5
agent = User-Agent: Smokeping
require_zero_status = yes
urlformat = http://%host%/

Targets配置:

*** Targets ***

probe = FPing

menu = Top
title = Network Latency Grapher
remark = Welcome to the SmokePing website of WORKS Company. \
         Here you will learn all about the latency of our network.

+ Ping
menu = Ping
title = Ping

alerts = hostdown,startdown

++ OL
menu = OL
title = OL
host = www.haiyun.me

++ HE
menu = HE
title = HE
host = www.haiyun.me

+ Curl 
menu = Curl
title = Curl

probe = Curl

++ OL
menu = OL
title = OL
host = 127.0.0.1
extraargs = --socks5 127.0.0.1:2016

++ HE
menu = HE
title = HE
host = 127.0.0.1
extraargs = --socks5 127.0.0.1:2015

Alerts配置:

*** Alerts ***
#to = alertee@address.somewhere
to = |/usr/local/bin/sendmail
from = smokealert@haiyun.me
#mailhost=www.haiyun.me
#mailpass=xxxxxx
#mailuser=xxxx

+someloss
type = loss
# in percent
pattern = >0%,*12*,>0%,*12*,>0%
comment = loss 3 times  in a row

+hostdown
type = loss
pattern = <90%,<90%,>90%,>90%,>90%,>90%,>90%,>90%
comment = no reply

+startdown
type = loss
pattern = ==S,>90%,>90%,>90%,>90%,>90%,>90%
comment = loss at startup

虽然smokeping可配置使用smtp发信,好像不支持smtp tls/ssl,所以调用/usr/local/bin/sendmail来发信,注意smokeping运行用户要有执行权限。:

#!/usr/bin/php
<?php
include('/usr/local/bin/smtp.php');
if (count($argv) != 6) {
  die("Invalid parameter\n");
}
$alertname = $argv[1];
$target = $argv[2];
$losspattern = $argv[3];
$rtt = $argv[4];
$hostname = $argv[5];
$title = $target.' is down';
$body = 'host: '.$hostname.'<br />'.'rtt: '.$rtt.'<br />';
send_mail($title, $body);

smartctl usb移动硬盘盒错误

发布时间:October 10, 2020 // 分类: // No Comments

升级smartctl后获取usb 移动硬盘SMART信息错误:

smartctl -a  /dev/sda
smartctl 7.1 2019-12-30 r5022 [aarch64-linux-5.3.0-aml-g12] (localbuild)
Copyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org

/dev/sda: Unknown USB bridge [0x1bcf:0x0c31 (0x10f)]
Please specify device type with the -d option.

Use smartctl -h to get a usage summary

解决方法:

smartctl -a -d usbsunplus /dev/sda

n1 ubuntu查看温度

发布时间:October 4, 2020 // 分类: // No Comments

echo $((`cat /sys/class/hwmon/hwmon0/temp1_input`/ 1000))

ubuntu交叉编译aarch64/arm ssdb

发布时间:September 27, 2020 // 分类: // No Comments

交叉编译环境:

wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
tar -Jxf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz 
export PATH=$PATH:"`pwd`/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/"
export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export LD=aarch64-linux-gnu-ld
export AR=aarch64-linux-gnu-ar
export RANLIB=aarch64-linux-gnu-ranlib

单独编译jemalloc、leveldb和snappy:

git clone https://github.com/ideawu/ssdb.git
cd ssdb/deps/jemalloc-4.1.0/
./autogen.sh --host=aarch64-linux-gnu && make
cd ../leveldb-1.20/
make
cd ../snappy-1.1.0/
./configure --host=aarch64-linux-gnu && make
cd ../../

编译ssdb:

cat > build_config.mk <<EOF
CFLAGS = -DNDEBUG -D__STDC_FORMAT_MACROS -Wall -O2 -Wno-sign-compare
CFLAGS += -I "`pwd`/deps/leveldb-1.20/include"
CFLAGS += -I "`pwd`/deps/jemalloc-4.1.0/include"
CFLAGS += -DNEW_MAC
CLIBS = "`pwd`/deps/leveldb-1.20/out-static/libleveldb.a"
CLIBS += "`pwd`/deps/snappy-1.1.0/.libs/libsnappy.a"
CLIBS += "`pwd`/deps/jemalloc-4.1.0/lib/libjemalloc.a"
CLIBS += -pthread -lrt
EOF
sed -i 's/\$(shell sh/#\$(shell sh/' Makefile 
sed -i 's/chmod u+x "\${LEVELDB_PATH}/#chmod u+x "\${LEVELDB_PATH}/' Makefile 
sed -i 's/cd "\${LEVELDB_PATH}/#cd "\${LEVELDB_PATH}/' Makefile 
make

systemd管理:

[Unit]
Description=ssdb service
After=network.target

[Service]
LimitNOFILE=65535
Type=simple
User=ssdb
#PIDFile=/var/run/ssdb.pid
ExecStart=/usr/local/ssdb/ssdb-server /usr/local/ssdb/ssdb.conf -s start
ExecStop=/usr/local/ssdb/ssdb-server /usr/local/ssdb/ssdb.conf -s stop
#Restart=always
#RestartSec=5
#StartLimitBurst=3
#StartLimitInterval=60
#StandardOutput=null
#StandardError=null

[Install]
WantedBy=multi-user.target

使用ssdb用户运行,新建用户,数据目录给予权限:

useradd -M -s /usr/sbin/nologin ssdb
chown -R ssdb:ssdb /ssdb-data/
分类
最新文章
最近回复
  • K: 好的,谢谢,我去试试!
  • 海运: 可以试试3proxy
  • daha: PHP的怎么使用???
  • 海运: 换回了5.3内核,5.8用5.3 dtb虽然能开机且负载正常,但也有其它问题,不建议使用。
  • shangyatsen: 后面的内核高精度计时器的问题使用5.4或者5.3的dtb会正常吗?我也发现有这个日志出现。感觉...
  • 海运: 缺少相应模块?
  • lee: 你好,我执行这条语句 iptables -t mangle -A PREROUTING -m ...
  • 海运: 只更新rootfs,不更新内核,我在用5.3配19.10,懒得再升最新版了,很稳定。 注意:更...
  • lyly168: 这是手动挂载吧,请问自动挂载要怎么弄?
  • swswsw1: 请问升级后,内核更新了吗?听说N1只有在5.0.2的内核下才稳定,怕升级了之后功耗太高
归档