c++ 腳本初級介紹


 

 

జ్ఞ ా رً ॣ

腳本是什么應該就不用多說了吧,想必想寫腳本的人一定知道什么是腳本;

眾所周知,c++不是寫腳本的最佳選擇;但我最熟悉c++,所以一直在用它寫腳本,偶爾用html5寫寫github的網頁,js什么的就靠其他大神的成就啦~。

接下來介紹c++的基本用法;

 一、鼠標的控制:

   正如小數有double,整數有int,鼠標也有自己的定義:POINT;

POINT p;  //我們定義了一個名字叫做p的鼠標;

  那么靠這個p可以做什么呢?

  1.有時候為了控制鼠標,我們需要知道屏幕某個點的坐標:

  p是封裝的,也就是說可以調用p.x和p.y,即:

cout<<p.x<<" "<<p.y<<endl; //輸出的便是鼠標在屏幕上的坐標;

  但是,定義p之后直接調用p.x和p.y是不行的,因為你沒有給p賦值。因此調用:

GetCursorPos(&P); //坐標便是目前鼠標的位置,以屏幕的左上角為(0,0)的平面直角坐標系,右下角便是你屏幕的分辨率最大值;大小寫要注意,一定不能寫錯;

   有人測試后會發現,我僅僅是讀到了一瞬間的鼠標位置,難道每測一次都要運行一次嗎?

  算法的基礎去哪了?while大循環啊!

#include <bits/stdc++.h>
#include <windows.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
int main()
{
  POINT P;
  while(1){
    GetCursorPos(&P);
    printf("%d %d \r",P.x,P.y);
  }
}

    請注意,腳本處處是坑,prinf("\r")的用法是接下來輸出的內容從這一行開始輸出,可以覆蓋原來的內容;如果沒被覆蓋完全那么沒被覆蓋的部分就仍然保持原來的內容;

  也就是說:printf("%d %d\r",P.x,P.y);是不行的,只能printf("%d %d       \r",P.x,P.y);

  為什么呢?如果原來的坐標是(123,1024); 即輸出:123 1024;

  假如你移動你的指針到(21,35);那么是輸出21 35嗎?不是,輸出的是21  35024;原因參考\r的用法,自己體會吧;

  2.我們需要把鼠標移到某個位置,並單擊或雙擊

  首先你需要先知道屏幕的分辨率最大是什么:

int x=GetSystemMetrics(SM_CXSCREEN);
int y=GetSystemMetrics(SM_CYSCREEN);

    現在(x,y)就是右下角的坐標;

  與GetCursorPos相對的,SetCursorPos(x,y)是將鼠標移到屏幕上坐標是(x,y)的位置上。如:SetCursorPos(264,119);

  模擬鼠標的點擊:

mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); //模擬按下鼠標左鍵 
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);  //模擬抬起鼠標左鍵 

   但要注意,按下抬起兩次中間要給電腦運行提供一個時間,這時需要用到:Sleep()函數;如Sleep(2234)就是程序暫停2234毫秒;  

   因此寫出函數:

void click(){ //模擬了鼠標的單擊
    mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
    Sleep(100);
    mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
} 

  那么雙擊呢?想必可以自己寫出來了吧;就是調用兩次click();

二、鍵盤的控制

   僅僅依靠鼠標無法寫出好的腳本,因此鍵盤的控制也不能少;

  1.監測鍵盤的按鍵

  比如說你寫了這樣一個腳本,用來惡搞同學: 

 
         
int x=GetSystemMetrics(SM_CXSCREEN);
int y=GetSystemMetrics(SM_CYSCREEN);
while(1){
  SetCursorPos(rand()%x,rand()%y);
  Sleep(200);
}

 顯然的,惡搞結束后就算是你想停止該程序運行也只能使用鍵盤win+r運行cmd,通過tasklist和taskkill /pid來結束進程;

  那么有沒有更好的辦法呢?

  有!就像俠盜獵車手GTA的秘籍差不多,按下指定的按鍵組合后停止該程序;

#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)

  上面這句話就是把寫起來賊為困難的話變成人話,這個函數的返回值是一個bool值,如果按下了VK_NONAME鍵,返回1,否則返回0;

  因此可以將惡搞的程序修改一下:

int x=GetSystemMetrics(SM_CXSCREEN);
int y=GetSystemMetrics(SM_CYSCREEN);
while(1){
  SetCursorPos(rand()%x,rand()%y);
  Sleep(200);
   if(KEY_DOWN(‘M')&&KEY_DOWN('X')&&KEY_DOWN('R')){
          return 0;      
   } 
}

  這樣你只需要像真正的大佬一樣,隨意的按下幾個鍵子,就終止了這個看似惡魔般的程序;

  2.模擬鍵盤的按鍵

  先來看一下這兩個函數:

keybd_event(ascii,0,0,0);
keybd_event(ascii,0,KEYEVENTF_KEYUP,0); 

  第一個參數:虛擬鍵碼(鍵盤鍵碼對照表一會給出);
  第二個參數:硬件掃描碼,一般設置為0即可;
  第三個參數:函數操作的一個標志位,如果值為KEYEVENTF_EXTENDEDKEY則該鍵被按下,也可設置為0即可,如果值為KEYEVENTF_KEYUP則該按鍵被抬起;
  第四個參數:定義與擊鍵相關的附加的32位值,一般設置為0即可。

  其中要格外注意,ascii並不是傳統的ASCII碼,

 

   

   因此可以寫出模擬按下按鍵的函數:

void press(int asi){
    keybd_event(asi,0,0,0);
    keybd_event(asi,0,KEYEVENTF_KEYUP,0);
    Sleep(100);
}

三、獲取系統信息優化腳本

  很多時候,為了得到某些數據,我們需要從電腦中讀取或運行某些東西,所以需要更多的腳本技巧;

  1.獲取系統目前的時間

time_t nowTime = time(NULL);
struct tm *t = localtime(&nowTime);
printf("\r%d-%02d-%02d %02d:%02d:%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);

  time_t 是一種類型,它定義的是時間類型nowTime;

  結構體指tm針指向的是nowTime的地址;

   tm結構體的原型:

struct tm {
   int tm_sec;         /* 秒,范圍從 0 到 59                */
   int tm_min;         /* 分,范圍從 0 到 59                */
   int tm_hour;        /* 小時,范圍從 0 到 23                */
   int tm_mday;        /* 一月中的第幾天,范圍從 1 到 31                    */
   int tm_mon;         /* 月份,范圍從 0 到 11                */
   int tm_year;        /* 自 1900 起的年數                */
   int tm_wday;        /* 一周中的第幾天,范圍從 0 到 6                */
   int tm_yday;        /* 一年中的第幾天,范圍從 0 到 365                    */
   int tm_isdst;       /* 夏令時                        */    
};

    localtime(&nowTime);把從1900-1-1零點零分到當前時間系統所偏移的秒數時間轉換為本地時間;

    %02d指的就是如果位數不夠就補0補到2位;

    如數字是0,那么輸出00;

  2.設置程序的正版激活信息

  眾所周知,每台電腦乃至每個主板、硬盤都有唯一的編號,我們在激活時使用這些編號作為hash值,並生成針對於此hash值下的激活代碼。(比如說用后綴自動機或者回文自動機算法來得到一個10MB的序列)這樣就算其他終端得到這台終端的激活碼也無法使用軟件。

  我們可以用三種語句來獲得唯一號:

wmic BaseBoard get Manufacturer

wmic BaseBoard get Product

wmic diskdrive get SerialNumber //硬盤唯一號

  我通常選用第三句獲取硬盤信息; 

     請注意,這三句話並不是c++的語言,而是cmd中的語法;

  在c++中,對於調用的cmd語法,我們可以使用system(".........");這樣的語句。比如說system("ping baidu.com -l 1024 -t"); 或者system("wmic diskdrive get SerialNumber");

  對於cmd中的語法,下面或許會有一些專項介紹;

  但是,僅僅運行system("wmic diskdrive get SerialNumber");僅僅會在控制台上得到結果,無法讓程序得到有效輸入,怎么辦呢?

  解決辦法之一:將這句話運行時重定向輸出內容到一個文件比如tmp.out,然后程序再重定向輸入到tmp.out中;

  解決方法之二:重定向輸入到控制台,讀取控制台顯示的內容;

void GetOnlykey(){ //第二種解決問題的辦法
    FILE *popen(const char *command,const char *type);
    FILE *file;    
    strcat(ptr, "wmic diskdrive get SerialNumber");      
    if((file=_popen(ptr, "r"))!=NULL)
    {
           while(fgets(tmpp,1024,file)!=NULL){ 
              memcpy(tmp,cmd,1024);
           memcpy(cmd,tmpp,1024);   //只需要最后一行的字符串
        }
        _pclose(file);
    }
    inc(i,1,(int)strlen(tmp)) onlykey=(onlykey*10%p+tmp[i])%p; 
}

  在這里稍微擴展一下,freopen("tmp.in","r",stdin);將輸入流定義到tmp.in文件里,而freopen("con","r",stdin);將輸入流定義到控制台了;

  獲得hash之后作為種子,srand("hash值")就好了;

  3.設定該程序后台運行;

  要做到這種效果,我們需要用到除了c++之外的語言。即:.vbs文件

  我們新建一個文檔,鍵入以下內容,並把擴展名更改為.vbs;

Set us=WScript.CreateObject("WScript.shell")
us.Run "solve.exe" ,0

  其中“us”是一個名稱,可以隨意設定; "solve.exe"是要后台運行程序的名稱;這兩個地方可以根據需要進行修改;

  假設這個.vbs文件叫background.vbs。那么如何在c++的程序中調用它呢?

  使用cmd中start的語法,調用語句:system("start background.vbs");就可以了。但要注意,vbs文件和該c++程序需要在一個文件夾內,否則應該使用cmd的start擴展語法;(具體的在cmd語法介紹里);

 四、cmd——命令提示符語法簡介

  之前便說過,在c++中調用cmd的語法需要用到system(".......");語句,而要調用system(" "),我們需要包含<windows.h>庫,也就是#include <windows.h>

  1.cd語法:

  cd命令是”change directory”中單詞的首字母縮寫,其英文釋義是改變目錄,所以該命令的功能是從當前目錄切換到指定目錄。

  其中目錄的路徑可分為絕對路徑和相對路徑。若目錄名稱省略,則切換至使用者的用戶目錄(也就是剛登錄時所在的目錄、home目錄)。

  用法:cd [選項] [目錄名]

  cd / 切換到用戶根目錄
  cd ../.. 返回上兩級目錄;
  cd .. 表示切換到上一級目錄。
  cd !$  把上個命令的參數作為cd參數使用。

  2.dir語法:

   /S    顯示指定目錄和所有子目錄中的文件。

    dir /?  顯示目錄中的文件和子目錄列表。

  dir /d      只顯示當前目錄下的文件名稱

  dir /od     按文件修改時間排序,遞增;

  dir /o-d    按文件修改時間排序,遞減

  dir /od/tc   按文件創建時間排序,遞增  

  dir /o-d/tc  按文件創建時間排序,遞減

  dir /on 按文件名排序對應,遞增

  dir /o-n 按文件名排序對應,遞減

  dir /oe 按擴展名排序對應,遞增

  dir /o-e 按文件名排序對應,遞減

  dir /s /b >a.txt  打印文件夾下的所有文件

  3.title語法:

  title ......   其中“......”便是程序的標題;

  4.start語法:

  利用好start語法可以干很多事情呦,比如說運行電腦中某個位置的程序,或者打開某個網頁;

  比如打開baidu.com: system("start https://www.baidu.com");

  比如運行位於C:\Users\Administrator\Desktop上的1.exe,那么我們system("start C:\\Users\\Administrator\\Desktop\\1.exe");

  注意,單斜杠要變成雙斜杠,否則系統會認為這是個亂糟糟的轉義序列;

  5.下載http文件

  win10中有個powershell可以實現此功能

  powershell的兩種打開方式:直接在開始菜單里找或者在cmd中輸入start powershell回車就可以啟動

  打開powershell后輸入:

$client = new-object System.Net.WebClient
$client.DownloadFile('#1', '#2')

  其中#1填寫下載地址,#2填寫本地保存位置,例如:

$client = new-object System.Net.WebClient 
$client.DownloadFile('http://static.duoshuo.com/embed.js','d:\embed.js')

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM