為什么要做?
首先是為了練習一下c#。
想必大家都有過記不起某個平台的賬號密碼的經歷,那種感受着實令人抓狂。那這么多賬號密碼根本記不住!我之前用python
寫過一個超級簡單(連賬號信息都寫在代碼里那種)的控制台程序用來給我提示密碼,但是我想添加一個賬號時直接被麻煩到吐。 所以我才想用Winform
做一個簡單的小工具來幫助我記憶。(僅供我自己使用(所以界面會比較丑。。),但是我會把代碼貼出來所以有點c#基礎的其實都可以自己做一個)
設想
我的需求非常簡單
- 在我需要的時候,輸入一個平台能把對應的賬號密碼顯示出來
- 能夠添加賬號信息
還有一點就是在查詢賬號之前需要輸入一個口令來驗證身份,這個口令只有我自己知道(我把它存在了app.config
文件中,后續如果有需要可以擴展出更改口令的功能),所以即使別人用我的電腦運行起來這個程序,他不知道口令也是沒用的。
賬號信息怎么存?
我曾經想要用SQL Server
存,畢竟c#
與它如此親近,但是我要存的東西本質上只是一些字符串,感覺有點大材小用所以沒有選擇SQL Server
。最近學了JS了解了一些json
的知識發現json
文件是個很好的選擇於是我便決用它了。但是我還不會用c#處理json數據呀。於是我又去網上找方法,然后我就發現了newtonsoft.json(json.NET)
,它時一款.NET
中開源的json序列化與反序列化工具。有了它,就可以解決我的問題了。
code
首先把入口界面搭建起來,一個超級簡單的窗體,只放了三個控件。
為了方便操作給它加一個退出的快捷鍵ESC。非常簡單只需要在KeyDown
事件中寫下如下代碼:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode==Keys.Escape)
{
this.Close();
}
}
然后是確定這個按鈕的功能:當輸入正確的口令后,點擊確定
可以進入到下一個界面。
口令放在哪?
我將口令這個數據放在了App.config
文件中,在解決方案資源管理器中右鍵添加新建項就可以添加它了。然后向其中加入如下代碼:
<appSettings>
<add key="CMD" value="123123"/>
</appSettings>
然后給剛才的入口窗體添加一個字段CMD
並用ConfigurationManager
將剛才的配置讀取出來賦值給它:
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
這個工具。當然還有一點時減輕了我對無數密碼的記憶負擔。
以記錄自己的學習歷程