個人密碼管理器

關(guān)鍵詞

  • c#
  • go
  • 本地web

設(shè)計思路

用go語言編寫本地后臺

  • 作用:

    1. 數(shù)據(jù)持久化耘柱。將數(shù)據(jù)存入sqlite數(shù)據(jù)庫腔长,還有數(shù)據(jù)的增刪改查葡缰,

    2. 本地web后端淆衷。監(jiān)聽本地1210端口缸榄,訪問本地1210端口可完成對數(shù)據(jù)的一系列操作

用c#語言編寫程序界面

  • 作用:

    1. 管理后臺服務(wù)。啟動后臺祝拯,關(guān)閉后臺甚带。

    2. 與后臺交互。通過訪問本地端口鹿驼,實現(xiàn)對數(shù)據(jù)的一系列操作

代碼

完整代碼:github/gitee

后臺代碼實現(xiàn)

web.go
package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"

    // "strconv"
    // "time"

    _ "github.com/mattn/go-sqlite3"
)

const (
    TIMELIMIT = 10
)

type setting struct {
    TIMELIMIT int
}

func main() {
    var st setting

    log.Println("start read setting")

    st.readSetting()

    log.Println("read setting is finish")

    log.Printf("main: starting HTTP server")

    httpServer()

    // var srv *http.Server
    // srv = new(http.Server)
    // srv = httpServer()

    // log.Printf("main: serving for " + strconv.Itoa(st.TIMELIMIT) + " seconds")

    // time.Sleep(time.Duration(st.TIMELIMIT) * time.Second)

    // log.Printf("main: stopping HTTP server")

    // now close the server gracefully ("shutdown")
    // timeout could be given instead of nil as a https://golang.org/pkg/context/
    // if err := srv.Shutdown(nil); err != nil {
    //  panic(err) // failure/timeout shutting down the server gracefully
    // }

    // log.Printf("main: done. exiting")
}

func httpServer() {
    htmlPath := "./index.html"

    srv := &http.Server{Addr: ":1210"}

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "http://localhost:1210")
        var data []byte
        var err error
        reqURI := r.RequestURI
        switch reqURI {
        case "/":
            data, err = readFile(htmlPath)
        case "/data":
            data, err = readSql()
        default:
            data, err = readFile("." + reqURI)
        }
        if err == nil {
            w.Write(data)
        }
    })

    if err := srv.ListenAndServe(); err != nil {
        // cannot panic, because this probably is an intentional close
        log.Printf("Httpserver: ListenAndServe() error: %s", err)
    }

    // go func() {
    //  if err := srv.ListenAndServe(); err != nil {
    //      // cannot panic, because this probably is an intentional close
    //      log.Printf("Httpserver: ListenAndServe() error: %s", err)
    //  }
    // }()

    // // returning reference so caller can call Shutdown()
    // return srv
}

func (st *setting) readSetting() {
    b, err := read("./setting.json")
    checkErr(err)
    if err := json.Unmarshal(b, st); err != nil {
        panic(b)
    }
}

func checkErr(err error) {
    if err != nil {
        panic(err)
    }
}

type user struct {
    id       string         `json:"id"`
    place    string         `json:"place"`
    account  string         `json:"account"`
    password string         `json:"password"`
    note     sql.NullString `json:"note"`
}

func (u *user) out() {
    fmt.Println(u.id)
    fmt.Println(u.place)
    fmt.Println(u.account)
    fmt.Println(u.password)
    fmt.Println(u.note)
}

func readSql() ([]byte, error) {
    return getJSON("select * from sercet")
}

func readFile(filepath string) ([]byte, error) {
    return read(filepath)
}

func read(filepath string) ([]byte, error) {
    f, err := os.Open(filepath)
    if err != nil {
        return nil, err
    }
    return ioutil.ReadAll(f)
}

func getJSON(sqlString string) ([]byte, error) {
    db, err := sql.Open("sqlite3", "./sercet.db")
    if err != nil {
        return nil, err
    }

    stmt, err := db.Prepare(sqlString)
    if err != nil {
        return nil, err
    }
    defer stmt.Close() // defer的作用欲低,在打開stmt后,不管后面的代碼流程如何影響畜晰,它能夠被自動關(guān)閉。

    rows, err := stmt.Query()
    if err != nil {
        return nil, err
    }
    defer rows.Close() // 同上

    columns, err := rows.Columns() // 返回[]string, error
    if err != nil {
        return []byte(""), err
    }

    count := len(columns)
    tableData := make([]map[string]interface{}, 0)
    values := make([]interface{}, count)
    valuePtrs := make([]interface{}, count)

    for rows.Next() {
        for i := 0; i < count; i++ {
            valuePtrs[i] = &values[i] // 將引用放入數(shù)組中
        }
        rows.Scan(valuePtrs...) // 使用數(shù)組獲取結(jié)果瑞筐,"..."是
        entry := make(map[string]interface{})
        for i, col := range columns { // i是數(shù)字凄鼻,col是數(shù)組中對應(yīng)下標i的值
            var v interface{}
            val := values[i]
            b, ok := val.([]byte) // 類型斷言(type assertion),簡單來說就是看val的類型是不是[]byte
            if ok {
                v = string(b)
            } else {
                v = val
            }
            entry[col] = v
        }
        tableData = append(tableData, entry)
    }

    return json.Marshal(tableData)
}

界面代碼實現(xiàn)

Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PasswordManager
{
    public partial class Form1 : Form
    {
        private Process p;
        private progressForm pf;

        public Form1()
        {
            InitializeComponent();
            pf = new progressForm();
            startWeb();
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        private void startWeb()
        {
            p = new Process();
            p.StartInfo.FileName = Application.StartupPath + @"\web2\web.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true; // 標準輸入流
            p.StartInfo.RedirectStandardOutput = true; // 標準輸出流
            p.StartInfo.RedirectStandardError = true; // 標準錯誤流
            p.StartInfo.CreateNoWindow = true; // 創(chuàng)建沒有窗口
            // 工作目錄 = 應(yīng)用啟動路徑
            p.StartInfo.WorkingDirectory = Application.StartupPath + @"\web2\";
            p.Start();

            webBrowser1.Url = new Uri("http://localhost:1210/");
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            pf.Show();
            pf.setValue(0);
            Process[] processList = Process.GetProcesses();
            foreach (Process p in processList)
            {
                if (p.ProcessName.ToLower() == "web")
                {
                    pf.setValue(50);
                    p.Kill();
                    break;
                }
            }
            pf.setValue(100);
            pf.Close();
        }

        private void setValue(int n)
        {

        }

        /// <summary>   
        /// 運行DOS命令   
        /// DOS關(guān)閉進程命令(ntsd -c q -p PID )PID為進程的ID   
        /// </summary>   
        /// <param name="command"></param>   
        /// <returns></returns>   
        private string RunCmd(string command)
        {
            Process p = new Process();

            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c " + command;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;

            p.Start();

            return p.StandardOutput.ReadToEnd();
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末聚假,一起剝皮案震驚了整個濱河市块蚌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膘格,老刑警劉巖峭范,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瘪贱,居然都是意外死亡纱控,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門菜秦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甜害,“玉大人,你說我怎么就攤上這事球昨《辏” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵主慰,是天一觀的道長嚣州。 經(jīng)常有香客問我,道長共螺,這世上最難降的妖魔是什么该肴? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮璃谨,結(jié)果婚禮上沙庐,老公的妹妹穿的比我還像新娘鲤妥。我一直安慰自己,他們只是感情好拱雏,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布棉安。 她就那樣靜靜地躺著,像睡著了一般铸抑。 火紅的嫁衣襯著肌膚如雪贡耽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天鹊汛,我揣著相機與錄音蒲赂,去河邊找鬼。 笑死刁憋,一個胖子當著我的面吹牛滥嘴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播至耻,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼若皱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了尘颓?” 一聲冷哼從身側(cè)響起走触,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疤苹,沒想到半個月后互广,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡卧土,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年惫皱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夸溶。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逸吵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缝裁,到底是詐尸還是另有隱情扫皱,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布捷绑,位于F島的核電站韩脑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粹污。R本人自食惡果不足惜段多,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望壮吩。 院中可真熱鬧进苍,春花似錦加缘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杠人,卻和暖如春勋乾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗡善。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工辑莫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人罩引。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓各吨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜒程。 傳聞我的和親對象是個殘疾皇子绅你,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容