乐趣区

关于c#:C用Winform制作一个简单的密码管理工具

为什么要做?

首先是为了练习一下 c#。
想必大家都有过记不起某个平台的账号密码的经验,那种感触着实令人抓狂。那这么多账号密码基本记不住!我之前用 python 写过一个 超级简略 (连账号信息都写在代码里那种) 的控制台程序用来给我提醒明码,然而我想增加一个账号时间接被麻烦到吐。所以我才想用 Winform 做一个简略的小工具来帮忙我记忆。(仅供我本人应用(所以界面会比拟丑。。),然而我会把代码贴出来所以有点 c# 根底的其实都能够本人做一个)

构想

我的需要非常简单

  1. 在我须要的时候,输出一个平台能把对应的账号密码显示进去
  2. 可能增加账号信息

还有一点就是在查问账号之前须要输出一个口令来验证身份,这个口令只有我本人晓得 (我把它存在了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 这个工具。当然还有一点时加重了我对有数明码的记忆负担。

以记录本人的学习历程

退出移动版