C#-用Winform製做一個簡單的密碼管理工具

爲何要作?

首先是爲了練習一下c#。
想必你們都有過記不起某個平臺的帳號密碼的經歷,那種感覺着實使人抓狂。那這麼多帳號密碼根本記不住!我以前用python寫過一個超級簡單(連帳號信息都寫在代碼裏那種)的控制檯程序用來給我提示密碼,可是我想添加一個帳號時直接被麻煩到吐。 因此我纔想用Winform作一個簡單的小工具來幫助我記憶。(僅供我本身使用(因此界面會比較醜。。),可是我會把代碼貼出來因此有點c#基礎的其實均可以本身作一個)python

設想

個人需求很是簡單json

  1. 在我須要的時候,輸入一個平臺能把對應的帳號密碼顯示出來
  2. 可以添加帳號信息

還有一點就是在查詢帳號以前須要輸入一個口令來驗證身份,這個口令只有我本身知道(我把它存在了app.config文件中,後續若是有須要能夠擴展出更改口令的功能),因此即便別人用個人電腦運行起來這個程序,他不知道口令也是沒用的。c#

帳號信息怎麼存?

我曾經想要用SQL Server存,畢竟c#與它如此親近,可是我要存的東西本質上只是一些字符串,感受有點大材小用因此沒有選擇SQL Server。最近學了JS瞭解了一些json的知識發現json文件是個很好的選擇因而我便決用它了。可是我還不會用c#處理json數據呀。因而我又去網上找方法,而後我就發現了newtonsoft.json(json.NET) ,它時一款.NET中開源的json序列化與反序列化工具。有了它,就能夠解決個人問題了。app

code

首先把入口界面搭建起來,一個超級簡單的窗體,只放了三個控件。ide

入口

爲了方便操做給它加一個退出的快捷鍵ESC。很是簡單隻須要在KeyDown事件中寫下以下代碼:工具

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if(e.KeyCode==Keys.Escape)
    {
        this.Close();
    }
}

而後是肯定這個按鈕的功能:當輸入正確的口令後,點擊肯定能夠進入到下一個界面。學習

口令放在哪?

我將口令這個數據放在了App.config文件中,在解決方案資源管理器中右鍵添加新建項就能夠添加它了。而後向其中加入以下代碼:ui

<appSettings>
    <add key="CMD" value="123123"/>
  </appSettings>

而後給剛纔的入口窗體添加一個字段CMD並用ConfigurationManager將剛纔的配置讀取出來賦值給它:this

public readonly string CMD=ConfigurationManager.AppSettings["CMD"].ToString() ;

上面的肯定按鈕的功能是口令正確是將下個界面顯示出來,因此咱們先把下個界面建立出來:加密

有了這個界面,就能夠去寫第一個界面中肯定按鈕的點擊事件了:

private void button1_Click(object sender, EventArgs e)
{
    ;
    string entered_cmd = textBox1.Text; 
    if(entered_cmd.Equals(CMD))
    {
        (new GetPwd()).Show();
        this.Hide();
    }
    else
    {
        MessageBox.Show("錯誤!","警告",MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
}

這樣第一個界面的代碼就寫完了(沒錯就是這麼簡單)。

帳號信息查詢界面

也就是上面的第二個窗體。它加載的初始狀態是這樣:

用於顯示帳號和密碼的兩個文本框我設置成了不可見(當輸入的平臺是存在的並點擊肯定就能夠看到了)和只讀。像這樣:

一個小問題

和上一個窗體同樣,我也給這個窗體綁定了enter(至關於點擊肯定按鈕)和esc快捷鍵。可是當我關閉這個窗體時,已經沒法再進行任何操做了但是這個程序進程卻沒有結束。怎麼解決這個問題呢?前段時間學習了委託因而我想到了一個比學校老師曾經教過的更好的方法(當時還沒學習委託,老師教的是把第一個窗體對象傳遞給第二個窗體):給第二個窗體定義一個委託字段 public Action close_main;而後在顯示該窗體是將前一個窗體的close()方法傳遞過來便可。
前面的代碼修改一下:

(new GetPwd() {close_main=this.Close}).Show();

而後在第二個窗體的FormClosed事件中執行這個方法就能夠了。

private void GetPwd_FormClosed(object sender, FormClosedEventArgs e)
{
    close_main();
}

查詢

全部的帳號信息我都放在一個json文件中:PWD.json,有關對其的各類邏輯性操做我抽成了一個類Manager:

class Manager
{
    public static string GetjsonString()
    {
        // 獲取整個json字符串
        if(!File.Exists(Path.GetFullPath(@"..//..") + ".../PWD.JSON"))
        {
            File.Create(Path.GetFullPath(@"..//..") + ".../PWD.JSON");
        }
        StreamReader jsonFile = File.OpenText(Path.GetFullPath(@"..//..") + ".../PWD.JSON");
        string res = jsonFile.ReadToEnd();
        jsonFile.Close();
        return res;
    }
    public static List<Acount> GetAcountsList()
    {
        //將json字符串序列化爲一個集合對象
        return JsonConvert.DeserializeObject<List<Acount>>(GetjsonString());
    }
    public static Acount SearchAcount(string platform)
    {
        //搜索平臺爲platform的帳號
        List<Acount> acounts = GetAcountsList();
        if(acounts==null||acounts.Count==0)
        {
            return null;
        }
        var res = from a in acounts
              where a.platForm == platform
              select a;
        return res.Count()>=1?res.First():null;
    }
    public static bool CheckExistence(Acount acount)
    {
        //檢查acount 這個帳號是否存在
        //檢查該帳號是否存在
        List<Acount> acounts = GetAcountsList();
        var res = from a in acounts
                  where a.platForm==acount.platForm&&a.acount == acount.acount && a.password == acount.password
                  select a;
        return res.Count() == 1;
    }
    public static void AddAcount(Acount a)
    {
        //添加一個帳號信息
        if(a.platForm==""||a.acount==""||a.password=="")
        {
            MessageBox.Show("請輸入完整信息!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return ;
        }
        List<Acount> acounts = GetAcountsList();
        acounts.Add(a);
        string res = JsonConvert.SerializeObject(acounts);
        StreamWriter jsonwriter = new StreamWriter(Path.GetFullPath(@"..//..") + ".../PWD.JSON");
        jsonwriter.WriteLine(res);
        jsonwriter.Close();
    }
}

有了這些方法,其餘地方就很是簡單了。查詢界面的肯定按鈕點擊事件:

private void button1_Click(object sender, EventArgs e)
{
    Acount acount = Manager.SearchAcount(txt_platform.Text.ToLower());
    if(acount!=null)
    {
        txt_uId.Text = acount.acount;
        txt_pwd.Text = acount.password;
        txt_uId.Visible = true;
        txt_pwd.Visible = true;
        txt_uId.ReadOnly = true;
        txt_pwd.ReadOnly = true;
    }
    else
    {
        MessageBox.Show("無此帳號!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
}

添加

第三個界面用來添加,經過第二個界面的Add按鈕呼出。
長這樣:

個人設想是想要添加帳號信息須要再次驗證一下身份:輸入一個已有的正確帳號信息來經過驗證,驗證經過後仍然使用這個界面來添加(三個文本框依次用來輸入平臺、帳號、密碼)。這個界面只有一個按鈕,驗證時它的text屬性爲"Check",添加時爲"Add",窗體的標題也有相應的變化。該按鈕的點擊事件以下:

private void button1_Click(object sender, EventArgs e)
{
    if(btn_check.Text=="Check")
    {
        if (Manager.CheckExistence(new Acount(txt_check_platform.Text.ToLower(), txt_check_uid.Text, txt_check_pwd.Text)))
        {
            txt_check_platform.Text = "";
            txt_check_uid.Text = "";
            txt_check_pwd.Text = "";
            this.Text = "添加密碼";
            btn_check.Text = "Add";
            txt_check_platform.Focus();
        }
        else
        {
            MessageBox.Show("驗證失敗!!", "驗證反饋", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    else
    {
        Manager.AddAcount(new Acount(txt_check_platform.Text.ToLower(), txt_check_uid.Text, txt_check_pwd.Text));
        this.close();
    }            
}

添加時:

另外,第三個界面也作了和前一個界面相同的快捷鍵和關閉處理

最後

這個程序很是很是簡單,固然後續仍是能夠擴展許多其餘功能的。雖然製做過程很簡單可是我仍是有很重要的收穫,就是newtonsoft.json這個工具。固然還有一點時減輕了我對無數密碼的記憶負擔。

以記錄本身的學習歷程

相關文章
相關標籤/搜索