真的懶得上圖了,很累。實驗的時候請先理解源代碼再運行!!!因為會涉及到鎖定系統,禁用alt和更改管理員密碼等操作。
眾所周知,java是不太適合操作系統底層的,所以類似禁用任務管理器,禁用鍵盤的操作真的很難,我用了其它思路來間接解決這個問題。程序一運行,將全屏顯示在最前端,屏蔽關閉和最小化,殺滅explorer進程,使用戶無法按win鍵,殺滅taskmgr進程,防止用戶之前啟動了任務管理器並置於前端,將錯誤的卡置於刷卡器,屏幕報錯,超過5次錯誤,鎖定一分鐘,此時將不接受所有卡,一分鐘後再錯再鎖一分鐘,以此類推,刷正確的卡將恢復離開時的桌面(就是程序退出,重開explorer),最關鍵的問題是如何防止用戶調用ctrl+alt+del(調出任務管理器)或alt+f4(關閉程序)以及alt+Tab(切換程序),先前我的想法是加一個線程,不斷地檢查並關閉taskmgr,但因為太耗費資源而禁用(i7的cpu99%,16g內存10分鐘95%),後來我讓程序不斷模擬按鍵esc,任務管理器調出後會迅速關閉,但這種方法無法防止後面兩個快捷鍵,查了很多方法均以失敗告終,最終,我想了一個不是辦法的辦法,監聽窗口alt按鍵(因為此時窗口全屏不可能失去焦點),當用戶按下alt後立刻自動鎖定計算機,如果計算機此時是空密碼將自動添加一個預設密碼。關於間隔時間檢測:我加了一個線程,定義了一個變量,每100毫秒自減,當小於-50會固定在-50(防止int溢出),當多次錯誤會將變量置於600,隨着時間遞減,然後再在驗證的時候看下這個變量是否為負數,如果不是,拒絕驗證
然而,這和直接win+l鎖定計算機有什麼不同?我想了一下主要有幾點:1.退出程序密碼,原本的系統密碼,和嘗試按alt後鎖定計算機的密碼相互獨立,也就是說,可以多加一個系統鎖2.自定義多次嘗試密碼錯誤的操作:可以關機,可以刪除指定文件,甚至可以發送警告短訊或郵件,同時對於兩次錯誤密碼的間隔時間也可以設置3.多人共享一個用戶,密碼由刷卡機控制,凡是符合條件的卡都可進入系統。順便說下,可以將程序密碼,預設系統密碼放到程序外面,寫個程序修改這些加密數據,但是很累,不想做了。
===然而,感覺這些並沒有什麼卵用(手動攤手)===
源代碼
package abc; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Toolkit; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.IOException; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPasswordField; public class AFrame extends JFrame implements Runnable { private static final long serialVersionUID = 1L; int n = 5; int t = -50; Toolkit kit = Toolkit.getDefaultToolkit(); JFrame jf; Dimension screensize = kit.getScreenSize(); int Width = screensize.width; int Height = screensize.height; public AFrame() { jf = new JFrame(); jf.setBounds(0, 0, Width, Height); Container c = new Container(); JLabel jb1 = new JLabel("解鎖計算機請將智能卡放入感應區"); JLabel jb2 = new JLabel("xxx製作"); jf.setUndecorated(true); JPasswordField jtf = new JPasswordField(); jb1.setBounds(Width / 2 - 320, 100, 750, 50); jb2.setBounds(Width / 2 - 170, 200, 800, 50); jtf.setBounds(Width / 2 - 120, 300, 200, 25); jb1.setFont(new Font("宋體", 1, 45)); jb2.setFont(new Font("宋體", 1, 25)); jtf.setFont(new Font("宋體", 1, 25)); jb1.setOpaque(true); jb1.setBackground(Color.GREEN); c.add(jb1); c.add(jb2); c.add(jtf); jf.add(c); jf.setVisible(false); jf.setVisible(true); Runtime r = Runtime.getRuntime(); try { r.exec("taskkill /f /im taskmgr.exe"); r.exec("taskkill /f /im explorer.exe"); } catch (IOException e1) { e1.printStackTrace(); } jtf.addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ALT) { Runtime r = Runtime.getRuntime(); try { r.exec("rundll32 user32.dll,LockWorkStation"); String exec = "net user \"Administrator\" \"123\""; r.exec(exec); } catch (IOException e1) { e1.printStackTrace(); } } if (e.getKeyCode() == KeyEvent.VK_ENTER) { String s = new String(jtf.getPassword()); if ((s.equals("123")||s.equals("234") ||s.equals("456") )&& t < 0) { Runtime r = Runtime.getRuntime(); try { r.exec("explorer.exe"); } catch (IOException e1) { e1.printStackTrace(); } System.exit(0); } else if (t >= 0) { jb1.setText(" 讀碼被鎖,還有" + (t / 10) + "秒!"); jtf.setText(""); jtf.requestFocus(); jb1.setBackground(Color.yellow); } else { n--; jb1.setText(" 智能卡讀碼錯誤!還有" + n + "次機會!"); jb1.setBackground(Color.red); jtf.setText(""); jtf.requestFocus(); if (n <= 0) { jb1.setText(" 讀碼關閉1分鐘!"); t = 600; jtf.setText(""); jtf.requestFocus(); } } } } @Override public void keyReleased(KeyEvent arg0) { } @Override public void keyTyped(KeyEvent arg0) { } }); } @Override public void run() { while (true) { try { Thread.sleep(100); t--; if (t <= -50) { t = -50; } System.out.println(t); } catch (Exception e) { e.printStackTrace(); } } } } package abc; public class Test{ public static void main(String[] args) { AFrame a=new AFrame(); new Thread(a,"A").start(); } }