Compare commits

..

No commits in common. "net8.0" and "1.0.0.1.1" have entirely different histories.

14 changed files with 730 additions and 187 deletions

83
OTP/Form1.Designer.cs generated
View File

@ -36,65 +36,63 @@
label2 = new System.Windows.Forms.Label(); label2 = new System.Windows.Forms.Label();
button3 = new System.Windows.Forms.Button(); button3 = new System.Windows.Forms.Button();
button4 = new System.Windows.Forms.Button(); button4 = new System.Windows.Forms.Button();
button5 = new System.Windows.Forms.Button();
progressBar1 = new System.Windows.Forms.ProgressBar(); progressBar1 = new System.Windows.Forms.ProgressBar();
label3 = new System.Windows.Forms.Label(); label3 = new System.Windows.Forms.Label();
label4 = new System.Windows.Forms.Label();
label5 = new System.Windows.Forms.Label();
SuspendLayout(); SuspendLayout();
// //
// listBox1 // listBox1
// //
listBox1.Font = new System.Drawing.Font("微软雅黑", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); listBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
listBox1.FormattingEnabled = true; listBox1.FormattingEnabled = true;
listBox1.ItemHeight = 27; listBox1.ItemHeight = 20;
listBox1.Location = new System.Drawing.Point(49, 44); listBox1.Location = new System.Drawing.Point(49, 44);
listBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); listBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
listBox1.Name = "listBox1"; listBox1.Name = "listBox1";
listBox1.Size = new System.Drawing.Size(551, 409); listBox1.Size = new System.Drawing.Size(551, 404);
listBox1.TabIndex = 0; listBox1.TabIndex = 0;
listBox1.SelectedIndexChanged += ListBox1_SelectedIndexChanged; listBox1.SelectedIndexChanged += listBox1_SelectedIndexChanged;
// //
// label1 // label1
// //
label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Bold); label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
label1.Location = new System.Drawing.Point(640, 56); label1.Location = new System.Drawing.Point(640, 68);
label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label1.Name = "label1"; label1.Name = "label1";
label1.Size = new System.Drawing.Size(230, 43); label1.Size = new System.Drawing.Size(230, 43);
label1.TabIndex = 1; label1.TabIndex = 1;
label1.Text = "TOTP Code"; label1.Text = "TOTP Code";
label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
label1.Click += Label1_Click;
// //
// button1 // button1
// //
button1.Enabled = false; button1.Enabled = false;
button1.Location = new System.Drawing.Point(640, 354); button1.Location = new System.Drawing.Point(640, 339);
button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button1.Name = "button1"; button1.Name = "button1";
button1.Size = new System.Drawing.Size(107, 27); button1.Size = new System.Drawing.Size(107, 27);
button1.TabIndex = 3; button1.TabIndex = 3;
button1.Text = "Generate"; button1.Text = "Generate";
button1.UseVisualStyleBackColor = true; button1.UseVisualStyleBackColor = true;
button1.Click += Button1_Click; button1.Click += button1_Click;
// //
// button2 // button2
// //
button2.Enabled = false; button2.Enabled = false;
button2.Location = new System.Drawing.Point(755, 354); button2.Location = new System.Drawing.Point(755, 339);
button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button2.Name = "button2"; button2.Name = "button2";
button2.Size = new System.Drawing.Size(115, 94); button2.Size = new System.Drawing.Size(115, 128);
button2.TabIndex = 3; button2.TabIndex = 3;
button2.Text = "Copy"; button2.Text = "Copy";
button2.UseVisualStyleBackColor = true; button2.UseVisualStyleBackColor = true;
button2.Click += Button2_Click; button2.Click += button2_Click;
// //
// label2 // label2
// //
label2.BackColor = System.Drawing.Color.Transparent; label2.BackColor = System.Drawing.Color.Transparent;
label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F); label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
label2.Location = new System.Drawing.Point(640, 297); label2.Location = new System.Drawing.Point(640, 285);
label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label2.Name = "label2"; label2.Name = "label2";
label2.Size = new System.Drawing.Size(230, 23); label2.Size = new System.Drawing.Size(230, 23);
@ -104,29 +102,40 @@
// //
// button3 // button3
// //
button3.Location = new System.Drawing.Point(640, 388); button3.Location = new System.Drawing.Point(640, 373);
button3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button3.Name = "button3"; button3.Name = "button3";
button3.Size = new System.Drawing.Size(107, 27); button3.Size = new System.Drawing.Size(107, 27);
button3.TabIndex = 7; button3.TabIndex = 7;
button3.Text = "Manage"; button3.Text = "Manage";
button3.UseVisualStyleBackColor = true; button3.UseVisualStyleBackColor = true;
button3.Click += Button3_Click; button3.Click += button3_Click;
// //
// button4 // button4
// //
button4.Location = new System.Drawing.Point(640, 421); button4.Location = new System.Drawing.Point(640, 406);
button4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button4.Name = "button4"; button4.Name = "button4";
button4.Size = new System.Drawing.Size(107, 27); button4.Size = new System.Drawing.Size(107, 27);
button4.TabIndex = 8; button4.TabIndex = 8;
button4.Text = "Refresh"; button4.Text = "Refresh";
button4.UseVisualStyleBackColor = true; button4.UseVisualStyleBackColor = true;
button4.Click += Button4_Click; button4.Click += button4_Click;
//
// button5
//
button5.Location = new System.Drawing.Point(640, 441);
button5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button5.Name = "button5";
button5.Size = new System.Drawing.Size(107, 27);
button5.TabIndex = 9;
button5.Text = "Troubleshooting";
button5.UseVisualStyleBackColor = true;
button5.Click += button5_Click;
// //
// progressBar1 // progressBar1
// //
progressBar1.Location = new System.Drawing.Point(640, 177); progressBar1.Location = new System.Drawing.Point(640, 165);
progressBar1.Maximum = 30; progressBar1.Maximum = 30;
progressBar1.Name = "progressBar1"; progressBar1.Name = "progressBar1";
progressBar1.Size = new System.Drawing.Size(230, 51); progressBar1.Size = new System.Drawing.Size(230, 51);
@ -134,44 +143,22 @@
// //
// label3 // label3
// //
label3.Font = new System.Drawing.Font("Segoe UI", 24F); label3.Font = new System.Drawing.Font("Segoe UI", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
label3.Location = new System.Drawing.Point(640, 231); label3.Location = new System.Drawing.Point(640, 219);
label3.Name = "label3"; label3.Name = "label3";
label3.Size = new System.Drawing.Size(230, 45); label3.Size = new System.Drawing.Size(230, 45);
label3.TabIndex = 11; label3.TabIndex = 11;
label3.Text = "1"; label3.Text = "1";
label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
// //
// label4
//
label4.AutoSize = true;
label4.Font = new System.Drawing.Font("Segoe UI", 12F);
label4.Location = new System.Drawing.Point(640, 129);
label4.Name = "label4";
label4.Size = new System.Drawing.Size(45, 21);
label4.TabIndex = 12;
label4.Text = "Next:";
//
// label5
//
label5.AutoSize = true;
label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold);
label5.Location = new System.Drawing.Point(713, 130);
label5.Name = "label5";
label5.Size = new System.Drawing.Size(92, 20);
label5.TabIndex = 13;
label5.Text = "Next Code";
label5.Click += Label5_Click;
//
// Form1 // Form1
// //
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(904, 508); ClientSize = new System.Drawing.Size(904, 508);
Controls.Add(label5);
Controls.Add(label4);
Controls.Add(label3); Controls.Add(label3);
Controls.Add(progressBar1); Controls.Add(progressBar1);
Controls.Add(button5);
Controls.Add(button4); Controls.Add(button4);
Controls.Add(button3); Controls.Add(button3);
Controls.Add(label2); Controls.Add(label2);
@ -188,7 +175,6 @@
Load += Form1_Load; Load += Form1_Load;
VisibleChanged += Form1_VisibleChanged; VisibleChanged += Form1_VisibleChanged;
ResumeLayout(false); ResumeLayout(false);
PerformLayout();
} }
#endregion #endregion
@ -200,10 +186,9 @@
private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button button3; private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4; private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.ProgressBar progressBar1; private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
} }
} }

View File

@ -12,8 +12,8 @@ namespace OTP
private byte[] secretKey; private byte[] secretKey;
private Totp totp; private Totp totp;
private Timer timer; private Timer timer;
private const string connectionString = "Data Source=key.db;Version=3;"; private string connectionString = "Data Source=key.db;Version=3;";
private const string embeddedDatabaseResource = "OTP.empty_key.db"; private string embeddedDatabaseResource = "OTP.empty_key.db";
private int runonce = 0; private int runonce = 0;
public Form1() public Form1()
@ -23,10 +23,8 @@ namespace OTP
//secretKey = Base32Encoding.ToBytes("JBSWY3DPEHPK3PXP"); // 示例的 base32 编码 //secretKey = Base32Encoding.ToBytes("JBSWY3DPEHPK3PXP"); // 示例的 base32 编码
//totp = new Totp(secretKey); //totp = new Totp(secretKey);
timer = new Timer timer = new Timer();
{ timer.Interval = 1000; // 设置计时器间隔为 1 秒
Interval = 1000 // 设置计时器间隔为 1 秒
};
timer.Tick += Timer_Tick; timer.Tick += Timer_Tick;
} }
public class TitleInfo public class TitleInfo
@ -56,16 +54,14 @@ namespace OTP
{ {
// 生成新的 TOTP 密码 // 生成新的 TOTP 密码
string newTotpCode = totp.ComputeTotp(); string newTotpCode = totp.ComputeTotp();
string newNextTotpCode = totp.ComputeTotp(DateTime.UtcNow.AddSeconds(30));
// 在标签上显示新生成的密码 // 在标签上显示新生成的密码
// 使用Invoke确保在UI线程上更新UI元素 // 使用Invoke确保在UI线程上更新UI元素
this.Invoke((System.Windows.Forms.MethodInvoker)(() => label1.Text = newTotpCode)); this.Invoke((System.Windows.Forms.MethodInvoker)(() => label1.Text = newTotpCode));
this.Invoke((System.Windows.Forms.MethodInvoker)(() => label5.Text = newNextTotpCode));
} }
private void Button1_Click(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e)
{ {
button1.Enabled = false; // 禁用生成按钮 button1.Enabled = false; // 禁用生成按钮
button2.Enabled = true; // 启用复制按钮 button2.Enabled = true; // 启用复制按钮
@ -87,14 +83,18 @@ namespace OTP
} }
private static void ExtractEmbeddedDatabase() private void ExtractEmbeddedDatabase()
{ {
// 从嵌入的资源中复制数据库文件到同目录下 // 从嵌入的资源中复制数据库文件到同目录下
try try
{ {
using Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedDatabaseResource); using (Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedDatabaseResource))
using FileStream fileStream = new("key.db", FileMode.Create); {
resourceStream.CopyTo(fileStream); using (FileStream fileStream = new FileStream("key.db", FileMode.Create))
{
resourceStream.CopyTo(fileStream);
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -106,26 +106,32 @@ namespace OTP
{ {
try try
{ {
using SQLiteConnection connection = new(connectionString); using (SQLiteConnection connection = new SQLiteConnection(connectionString))
connection.Open();
using SQLiteCommand command = new("SELECT Id, Title, SecretKey FROM TotpData", connection);
using SQLiteDataReader reader = command.ExecuteReader();
listBox1.Items.Clear(); // 清空现有数据
while (reader.Read())
{ {
int id = reader.GetInt32(0); connection.Open();
string title = reader.GetString(1);
string secretKey = reader.GetString(2);
TitleInfo titleInfo = new() using (SQLiteCommand command = new SQLiteCommand("SELECT Id, Title, SecretKey FROM TotpData", connection))
{ {
Id = id, using (SQLiteDataReader reader = command.ExecuteReader())
Title = title, {
SecretKey = secretKey listBox1.Items.Clear(); // 清空现有数据
}; while (reader.Read())
{
int id = reader.GetInt32(0);
string title = reader.GetString(1);
string secretKey = reader.GetString(2);
listBox1.Items.Add(titleInfo); TitleInfo titleInfo = new TitleInfo
{
Id = id,
Title = title,
SecretKey = secretKey
};
listBox1.Items.Add(titleInfo);
}
}
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -134,11 +140,12 @@ namespace OTP
} }
} }
private void ListBox1_SelectedIndexChanged(object sender, EventArgs e) private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{ {
if (listBox1.SelectedIndex >= 0) // Ensure an item is selected if (listBox1.SelectedIndex >= 0) // Ensure an item is selected
{ {
if (listBox1.SelectedItem is TitleInfo selectedTitleInfo) TitleInfo selectedTitleInfo = listBox1.SelectedItem as TitleInfo;
if (selectedTitleInfo != null)
{ {
if (runonce == 0) if (runonce == 0)
{ {
@ -163,15 +170,15 @@ namespace OTP
} }
private void Button2_Click(object sender, EventArgs e) private void button2_Click(object sender, EventArgs e)
{ {
Clipboard.SetText(label1.Text); Clipboard.SetText(label1.Text);
} }
private void Button3_Click(object sender, EventArgs e) private void button3_Click(object sender, EventArgs e)
{ {
// 创建 Form2 实例 // 创建 Form2 实例
Form2 form2 = new(); Form2 form2 = new Form2();
// 显示新创建的 Form2 实例 // 显示新创建的 Form2 实例
form2.Show(); form2.Show();
@ -199,7 +206,6 @@ namespace OTP
LoadTitlesToListBox(); LoadTitlesToListBox();
runonce = 0; runonce = 0;
label1.Text = "TOTP Code"; label1.Text = "TOTP Code";
label1.Text = "Next Code";
button1.Enabled = false; button1.Enabled = false;
button2.Enabled = false; button2.Enabled = false;
label3.Text = "time"; label3.Text = "time";
@ -211,19 +217,15 @@ namespace OTP
} }
} }
private void Button4_Click(object sender, EventArgs e) private void button4_Click(object sender, EventArgs e)
{ {
LoadTitlesToListBox(); LoadTitlesToListBox();
} }
private void Label1_Click(object sender, EventArgs e) private void button5_Click(object sender, EventArgs e)
{ {
Clipboard.SetText(label1.Text); Form4 form4 = new Form4();
} form4.Show();
private void Label5_Click(object sender, EventArgs e)
{
Clipboard.SetText(label5.Text);
} }
} }
} }

8
OTP/Form2.Designer.cs generated
View File

@ -74,7 +74,7 @@
button1.TabIndex = 1; button1.TabIndex = 1;
button1.Text = "New Record"; button1.Text = "New Record";
button1.UseVisualStyleBackColor = true; button1.UseVisualStyleBackColor = true;
button1.Click += Button1_Click; button1.Click += button1_Click;
// //
// button2 // button2
// //
@ -85,7 +85,7 @@
button2.TabIndex = 2; button2.TabIndex = 2;
button2.Text = "Delete Record(s)"; button2.Text = "Delete Record(s)";
button2.UseVisualStyleBackColor = true; button2.UseVisualStyleBackColor = true;
button2.Click += Button2_Click; button2.Click += button2_Click;
// //
// button3 // button3
// //
@ -96,7 +96,7 @@
button3.TabIndex = 3; button3.TabIndex = 3;
button3.Text = "Save Changes"; button3.Text = "Save Changes";
button3.UseVisualStyleBackColor = true; button3.UseVisualStyleBackColor = true;
button3.Click += Button3_Click; button3.Click += button3_Click;
// //
// button4 // button4
// //
@ -107,7 +107,7 @@
button4.TabIndex = 4; button4.TabIndex = 4;
button4.Text = "Discard Changes"; button4.Text = "Discard Changes";
button4.UseVisualStyleBackColor = true; button4.UseVisualStyleBackColor = true;
button4.Click += Button4_Click; button4.Click += button4_Click;
// //
// Form2 // Form2
// //

View File

@ -8,8 +8,8 @@ namespace OTP
{ {
public partial class Form2 : Form public partial class Form2 : Form
{ {
private const string connectionString = "Data Source=key.db;Version=3;"; private string connectionString = "Data Source=key.db;Version=3;";
private const string backupPath = "key.db.bak"; // 备份数据库文件的路径 private string backupPath = "key.db.bak"; // 备份数据库文件的路径
private string sourceFileHash = ""; // 原始数据库文件的哈希值 private string sourceFileHash = ""; // 原始数据库文件的哈希值
public Form2() public Form2()
@ -65,12 +65,16 @@ namespace OTP
} }
} }
// 计算文件的SHA-256哈希值 // 计算文件的SHA-256哈希值
private static string CalculateSHA256Hash(string filePath) private string CalculateSHA256Hash(string filePath)
{ {
using SHA256 sha256 = SHA256.Create(); using (SHA256 sha256 = SHA256.Create())
using FileStream stream = File.OpenRead(filePath); {
byte[] hashBytes = sha256.ComputeHash(stream); using (FileStream stream = File.OpenRead(filePath))
return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); {
byte[] hashBytes = sha256.ComputeHash(stream);
return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
}
}
} }
@ -82,42 +86,51 @@ namespace OTP
{ {
dataGridView1.Rows.Clear(); // 清空现有数据 dataGridView1.Rows.Clear(); // 清空现有数据
using SQLiteConnection connection = new(connectionString); using (SQLiteConnection connection = new SQLiteConnection(connectionString))
connection.Open();
using SQLiteCommand command = new("SELECT Id, Title FROM TotpData", connection);
using SQLiteDataReader reader = command.ExecuteReader();
while (reader.Read())
{ {
int id = reader.GetInt32(0); connection.Open();
string title = reader.GetString(1);
dataGridView1.Rows.Add(title); using (SQLiteCommand command = new SQLiteCommand("SELECT Id, Title FROM TotpData", connection))
dataGridView1.Rows[^1].Tag = id; // 将 Id 存储在行的 Tag 属性中 {
using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(0);
string title = reader.GetString(1);
dataGridView1.Rows.Add(title);
dataGridView1.Rows[dataGridView1.Rows.Count - 1].Tag = id; // 将 Id 存储在行的 Tag 属性中
}
}
}
} }
} }
private void Button1_Click(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e)
{ {
using Form3 form3 = new(); using (Form3 form3 = new Form3())
DialogResult result = form3.ShowDialog();
if (result == DialogResult.OK)
{ {
// 在 Form3 中添加数据完成后,刷新数据 DialogResult result = form3.ShowDialog();
LoadData();
if (result == DialogResult.OK)
{
// 在 Form3 中添加数据完成后,刷新数据
LoadData();
}
} }
} }
private void Form2_FormClosing(object sender, FormClosingEventArgs e) private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{ {
if (Application.OpenForms["Form1"] is Form1 form1) Form1 form1 = Application.OpenForms["Form1"] as Form1;
if (form1 != null)
{ {
form1.Show(); form1.Show();
} }
} }
private void Button2_Click(object sender, EventArgs e) private void button2_Click(object sender, EventArgs e)
{ {
try try
{ {
@ -140,16 +153,20 @@ namespace OTP
} }
} }
private static void DeleteRecordFromDatabase(int recordId) private void DeleteRecordFromDatabase(int recordId)
{ {
try try
{ {
using SQLiteConnection connection = new(connectionString); using (SQLiteConnection connection = new SQLiteConnection(connectionString))
connection.Open(); {
connection.Open();
using SQLiteCommand command = new("DELETE FROM TotpData WHERE ID = @ID", connection); using (SQLiteCommand command = new SQLiteCommand("DELETE FROM TotpData WHERE ID = @ID", connection))
command.Parameters.AddWithValue("@ID", recordId); {
command.ExecuteNonQuery(); command.Parameters.AddWithValue("@ID", recordId);
command.ExecuteNonQuery();
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -157,7 +174,7 @@ namespace OTP
} }
} }
private void Button3_Click(object sender, EventArgs e) private void button3_Click(object sender, EventArgs e)
{ {
// 删除备份文件 // 删除备份文件
if (File.Exists(backupPath)) if (File.Exists(backupPath))
@ -169,7 +186,7 @@ namespace OTP
this.Close(); this.Close();
} }
private void Button4_Click(object sender, EventArgs e) private void button4_Click(object sender, EventArgs e)
{ {
try try
{ {

71
OTP/Form3.Designer.cs generated
View File

@ -34,13 +34,18 @@
textBox2 = new System.Windows.Forms.TextBox(); textBox2 = new System.Windows.Forms.TextBox();
button1 = new System.Windows.Forms.Button(); button1 = new System.Windows.Forms.Button();
button2 = new System.Windows.Forms.Button(); button2 = new System.Windows.Forms.Button();
button3 = new System.Windows.Forms.Button();
button4 = new System.Windows.Forms.Button(); button4 = new System.Windows.Forms.Button();
button5 = new System.Windows.Forms.Button();
button6 = new System.Windows.Forms.Button(); button6 = new System.Windows.Forms.Button();
label3 = new System.Windows.Forms.Label(); label3 = new System.Windows.Forms.Label();
label4 = new System.Windows.Forms.Label(); label4 = new System.Windows.Forms.Label();
label5 = new System.Windows.Forms.Label(); label5 = new System.Windows.Forms.Label();
groupBox1 = new System.Windows.Forms.GroupBox(); groupBox1 = new System.Windows.Forms.GroupBox();
button8 = new System.Windows.Forms.Button();
pictureBox1 = new System.Windows.Forms.PictureBox();
groupBox1.SuspendLayout(); groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// label1 // label1
@ -88,7 +93,7 @@
button1.TabIndex = 4; button1.TabIndex = 4;
button1.Text = "Add"; button1.Text = "Add";
button1.UseVisualStyleBackColor = true; button1.UseVisualStyleBackColor = true;
button1.Click += Button1_Click; button1.Click += button1_Click;
// //
// button2 // button2
// //
@ -101,27 +106,49 @@
button2.Text = "Cancel"; button2.Text = "Cancel";
button2.UseVisualStyleBackColor = true; button2.UseVisualStyleBackColor = true;
// //
// button3
//
button3.Location = new System.Drawing.Point(341, 5);
button3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button3.Name = "button3";
button3.Size = new System.Drawing.Size(205, 27);
button3.TabIndex = 6;
button3.Text = "Scan QR Code from Screenshot";
button3.UseVisualStyleBackColor = true;
button3.Click += button3_Click;
//
// button4 // button4
// //
button4.Location = new System.Drawing.Point(341, 9); button4.Location = new System.Drawing.Point(341, 38);
button4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button4.Name = "button4"; button4.Name = "button4";
button4.Size = new System.Drawing.Size(205, 27); button4.Size = new System.Drawing.Size(205, 27);
button4.TabIndex = 7; button4.TabIndex = 7;
button4.Text = "Scan QR Code from Image File"; button4.Text = "Scan QR Code from Image File";
button4.UseVisualStyleBackColor = true; button4.UseVisualStyleBackColor = true;
button4.Click += Button4_Click; button4.Click += button4_Click;
//
// button5
//
button5.Location = new System.Drawing.Point(341, 72);
button5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button5.Name = "button5";
button5.Size = new System.Drawing.Size(205, 27);
button5.TabIndex = 8;
button5.Text = "Scan QR Code with Camera";
button5.UseVisualStyleBackColor = true;
button5.Click += button5_Click;
// //
// button6 // button6
// //
button6.Location = new System.Drawing.Point(341, 44); button6.Location = new System.Drawing.Point(341, 105);
button6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
button6.Name = "button6"; button6.Name = "button6";
button6.Size = new System.Drawing.Size(205, 27); button6.Size = new System.Drawing.Size(205, 27);
button6.TabIndex = 9; button6.TabIndex = 9;
button6.Text = "Import from Clipboard"; button6.Text = "Import from Clipboard";
button6.UseVisualStyleBackColor = true; button6.UseVisualStyleBackColor = true;
button6.Click += Button6_Click; button6.Click += button6_Click;
// //
// label3 // label3
// //
@ -155,6 +182,8 @@
// //
// groupBox1 // groupBox1
// //
groupBox1.Controls.Add(button8);
groupBox1.Controls.Add(pictureBox1);
groupBox1.Controls.Add(label4); groupBox1.Controls.Add(label4);
groupBox1.Controls.Add(label5); groupBox1.Controls.Add(label5);
groupBox1.Controls.Add(label3); groupBox1.Controls.Add(label3);
@ -162,20 +191,42 @@
groupBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
groupBox1.Name = "groupBox1"; groupBox1.Name = "groupBox1";
groupBox1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
groupBox1.Size = new System.Drawing.Size(528, 214); groupBox1.Size = new System.Drawing.Size(528, 332);
groupBox1.TabIndex = 14; groupBox1.TabIndex = 14;
groupBox1.TabStop = false; groupBox1.TabStop = false;
groupBox1.Text = "Debug Info"; groupBox1.Text = "Debug Info";
// //
// button8
//
button8.Location = new System.Drawing.Point(427, 0);
button8.Name = "button8";
button8.Size = new System.Drawing.Size(101, 23);
button8.TabIndex = 15;
button8.Text = "Stop Camera";
button8.UseVisualStyleBackColor = true;
button8.Click += button8_Click;
//
// pictureBox1
//
pictureBox1.Location = new System.Drawing.Point(122, 130);
pictureBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
pictureBox1.Name = "pictureBox1";
pictureBox1.Size = new System.Drawing.Size(298, 195);
pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
pictureBox1.TabIndex = 14;
pictureBox1.TabStop = false;
//
// Form3 // Form3
// //
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
CancelButton = button2; CancelButton = button2;
ClientSize = new System.Drawing.Size(569, 404); ClientSize = new System.Drawing.Size(569, 517);
Controls.Add(groupBox1); Controls.Add(groupBox1);
Controls.Add(button6); Controls.Add(button6);
Controls.Add(button5);
Controls.Add(button4); Controls.Add(button4);
Controls.Add(button3);
Controls.Add(button2); Controls.Add(button2);
Controls.Add(button1); Controls.Add(button1);
Controls.Add(textBox2); Controls.Add(textBox2);
@ -190,8 +241,10 @@
ShowIcon = false; ShowIcon = false;
StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
Text = "New Record"; Text = "New Record";
FormClosing += Form3_FormClosing;
groupBox1.ResumeLayout(false); groupBox1.ResumeLayout(false);
groupBox1.PerformLayout(); groupBox1.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
} }
@ -204,11 +257,15 @@
private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4; private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button button6; private System.Windows.Forms.Button button6;
private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label5;
private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button button8;
} }
} }

View File

@ -1,6 +1,12 @@
using System; using FlashCap;
using FlashCap.Utilities;
using ScreenCapturerNS;
using System;
using System.Data.SQLite; using System.Data.SQLite;
using System.Drawing; using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using ZXing; using ZXing;
@ -8,15 +14,49 @@ namespace OTP
{ {
public partial class Form3 : Form public partial class Form3 : Form
{ {
private const string connectionString = "Data Source=key.db;Version=3;"; private string connectionString = "Data Source=key.db;Version=3;";
private bool isCapturing = false; // 添加标识截图状态的成员变量
private bool isLocalfile = false; private bool isLocalfile = false;
private bool isScanningPaused = false;
private bool isRecording = false;
private SynchronizationContext synchContext;
private System.Windows.Forms.Timer timer;
private CaptureDevice captureDevice;
public Form3() public Form3()
{ {
InitializeComponent(); // 确保调用了这个方法 InitializeComponent();
// 初始化定时器间隔为1秒1000毫秒
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += Timer_Tick;
}
private void Timer_Tick(object sender, EventArgs e)
{
if (pictureBox1.Image != null && isRecording)
{
ScanQRCode((Bitmap)pictureBox1.Image);
}
} }
private void Button1_Click(object sender, EventArgs e)
private async void Form3_FormClosing(object sender, FormClosingEventArgs e)
{
StopCapturing();
if (isRecording)
{
await this.captureDevice.StopAsync();
pictureBox1.Image = null;
isRecording = false;
// Discard capture device.
this.captureDevice?.Dispose();
this.captureDevice = null;
}
}
private void button1_Click(object sender, EventArgs e)
{ {
try try
{ {
@ -25,14 +65,16 @@ namespace OTP
if (!string.IsNullOrWhiteSpace(title) && !string.IsNullOrWhiteSpace(secretKey)) if (!string.IsNullOrWhiteSpace(title) && !string.IsNullOrWhiteSpace(secretKey))
{ {
using (SQLiteConnection connection = new(connectionString)) using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{ {
connection.Open(); connection.Open();
using SQLiteCommand command = new("INSERT INTO TotpData (Title, SecretKey) VALUES (@Title, @SecretKey)", connection); using (SQLiteCommand command = new SQLiteCommand("INSERT INTO TotpData (Title, SecretKey) VALUES (@Title, @SecretKey)", connection))
command.Parameters.AddWithValue("@Title", title); {
command.Parameters.AddWithValue("@SecretKey", secretKey); command.Parameters.AddWithValue("@Title", title);
command.ExecuteNonQuery(); command.Parameters.AddWithValue("@SecretKey", secretKey);
command.ExecuteNonQuery();
}
} }
this.DialogResult = DialogResult.OK; this.DialogResult = DialogResult.OK;
MessageBox.Show("Record added successfully."); MessageBox.Show("Record added successfully.");
@ -50,8 +92,40 @@ namespace OTP
MessageBox.Show($"An error occurred: {ex.Message}"); MessageBox.Show($"An error occurred: {ex.Message}");
} }
} }
private void button3_Click(object sender, EventArgs e)
{
if (isCapturing)
{
label5.Text = "Stopped";
StopCapturing(); // 停止截图
}
else
{
label3.Text = "None";
label5.Text = "Running";
label4.Text = "No QR code found.";
StartCapturing(); // 开始截图
}
}
private void ScanQRCode(Bitmap bitmap) private void StartCapturing()
{
//deactivateButton(3);
isCapturing = true; // 设置截图状态为正在截图
ScreenCapturer.StartCapture((Bitmap bitmap) =>
{
ScanQRCode(bitmap);
});
}
private void StopCapturing()
{
//activeButton();
isCapturing = false; // 设置截图状态为未截图
ScreenCapturer.StopCapture(); // 停止截图
}
private async void ScanQRCode(Bitmap bitmap)
{ {
// 创建二维码读取器实例 // 创建二维码读取器实例
var barcodeReader = new ZXing.Windows.Compatibility.BarcodeReader(); var barcodeReader = new ZXing.Windows.Compatibility.BarcodeReader();
@ -62,35 +136,49 @@ namespace OTP
{ {
// 扫描成功,显示扫描结果 // 扫描成功,显示扫描结果
string decodedText = result.Text; string decodedText = result.Text;
label3.Text = decodedText; this.Invoke((MethodInvoker)(() => label3.Text = decodedText));
// 判断是否符合期望的格式 // 判断是否符合期望的格式
if (decodedText.StartsWith("otpauth://totp/") && decodedText.Contains("?secret=")) if (decodedText.StartsWith("otpauth://totp/") && decodedText.Contains("?secret="))
{ {
if (isLocalfile) if (!isLocalfile && !isScanningPaused)
{ {
isLocalfile = false; StopCapturing();
} this.Invoke((MethodInvoker)(() => label5.Text = "Stopped"));
string[] parts = decodedText.Split(['/', '=', '&', '?']);
if (parts.Length >= 6)
{
// 扫码成功
string title = Uri.UnescapeDataString(parts[3]); // 解码 title 部分
string secretKey = parts[5]; // 获取 secretKey 部分
// 在窗体上显示 title 和 secretKey
textBox1.Text = title;
textBox2.Text = secretKey;
label4.Text = "Success";
} }
else else
{ {
label4.Text = "Invalid QR code format."; isLocalfile = false;
}
string[] parts = decodedText.Split(new char[] { '/', '=', '&', '?' });
if (parts.Length >= 6)
{
//扫码成功
string title = parts[3]; // 获取 title 部分
string secretKey = parts[5]; // 获取 secretKey 部分
// 在窗体上显示 title 和 secretKey
this.Invoke((MethodInvoker)(() => textBox1.Text = title));
this.Invoke((MethodInvoker)(() => textBox2.Text = secretKey));
this.Invoke((MethodInvoker)(() => label4.Text = "Success"));
if (isRecording)
{
await this.captureDevice.StopAsync();
pictureBox1.Image = null;
isRecording = false;
// Discard capture device.
this.captureDevice?.Dispose();
this.captureDevice = null;
}
}
else
{
this.Invoke((MethodInvoker)(() => label4.Text = "Invalid QR code format."));
} }
} }
else else
{ {
label4.Text = "QR code format not recognized."; this.Invoke((MethodInvoker)(() => label4.Text = "QR code format not recognized."));
} }
} }
else else
@ -100,24 +188,81 @@ namespace OTP
label3.Text = "None"; label3.Text = "None";
label4.Text = "QR code not detected."; label4.Text = "QR code not detected.";
} }
else if (isScanningPaused)
{
this.Invoke((MethodInvoker)(() => label3.Text = "None"));
this.Invoke((MethodInvoker)(() => label4.Text = "QR code not detected."));
}
} }
} }
private void Button4_Click(object sender, EventArgs e) private void button4_Click(object sender, EventArgs e)
{ {
isLocalfile = true; isLocalfile = true;
using OpenFileDialog openFileDialog = new(); using (OpenFileDialog openFileDialog = new OpenFileDialog())
openFileDialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{ {
string filePath = openFileDialog.FileName; openFileDialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
using Bitmap image = new(filePath); using (Bitmap image = new Bitmap(filePath))
ScanQRCode(image); {
ScanQRCode(image);
}
}
} }
} }
private void Button6_Click(object sender, EventArgs e) private async void button5_Click(object sender, EventArgs e)
{
this.synchContext = SynchronizationContext.Current;
var devices = new CaptureDevices();
var descriptors = devices.EnumerateDescriptors().
//Where(d => d.DeviceType == DeviceTypes.DirectShow). // Only DirectShow device.
Where(d => d.Characteristics.Length >= 1). // One or more valid video characteristics.
ToArray();
// Use first device.
var descriptor0 = descriptors.ElementAtOrDefault(0);
if (descriptor0 != null)
{
var characteristics = descriptor0.Characteristics.
FirstOrDefault(c => c.PixelFormat != PixelFormats.Unknown);
if (characteristics != null)
{
this.captureDevice = await descriptor0.OpenAsync(
characteristics,
this.OnPixelBufferArrived);
await this.captureDevice.StartAsync();
}
}
}
private void OnPixelBufferArrived(PixelBufferScope bufferScope)
{
ArraySegment<byte> image = bufferScope.Buffer.ReferImage();
using (var stream = image.AsStream())
{
var bitmap = Image.FromStream(stream);
bufferScope.ReleaseNow();
this.synchContext.Post(_ =>
{
pictureBox1.Image = bitmap;
if (!isRecording)
{
isRecording = true;
timer.Start();
}
}, null);
}
}
private void button6_Click(object sender, EventArgs e)
{ {
string clipboardText = Clipboard.GetText(); string clipboardText = Clipboard.GetText();
@ -125,10 +270,10 @@ namespace OTP
clipboardText.StartsWith("otpauth://totp/") && clipboardText.StartsWith("otpauth://totp/") &&
clipboardText.Contains("?secret=")) clipboardText.Contains("?secret="))
{ {
string[] parts = clipboardText.Split(['/', '=', '&', '?']); string[] parts = clipboardText.Split(new char[] { '/', '=', '&', '?' });
if (parts.Length >= 6) if (parts.Length >= 6)
{ {
string title = Uri.UnescapeDataString(parts[3]); // 解码 title 部分 string title = parts[3]; // 获取 title 部分
string secretKey = parts[5]; // 获取 secretKey 部分 string secretKey = parts[5]; // 获取 secretKey 部分
MessageBox.Show("OTP link successfully pasted."); MessageBox.Show("OTP link successfully pasted.");
@ -143,5 +288,18 @@ namespace OTP
MessageBox.Show("Clipboard content is not a valid OTP link."); MessageBox.Show("Clipboard content is not a valid OTP link.");
} }
} }
private async void button8_Click(object sender, EventArgs e)
{
if (isRecording)
{
await this.captureDevice.StopAsync();
pictureBox1.Image = null;
isRecording = false;
// Discard capture device.
this.captureDevice?.Dispose();
this.captureDevice = null;
}
}
} }
} }

118
OTP/Form4.Designer.cs generated Normal file
View File

@ -0,0 +1,118 @@
namespace OTP
{
partial class Form4
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label2
//
this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 36F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(12, 64);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(152, 55);
this.label2.TabIndex = 1;
this.label2.Text = "label2";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label3
//
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 36F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(12, 119);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(216, 55);
this.label3.TabIndex = 2;
this.label3.Text = "网络时间";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label1
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 36F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(360, 55);
this.label1.TabIndex = 3;
this.label1.Text = "计算机本地时间";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label4
//
this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 36F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label4.Location = new System.Drawing.Point(12, 174);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(152, 55);
this.label4.TabIndex = 4;
this.label4.Text = "label4";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// Form4
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(705, 242);
this.Controls.Add(this.label2);
this.Controls.Add(this.label3);
this.Controls.Add(this.label1);
this.Controls.Add(this.label4);
this.Name = "Form4";
this.Text = "Troubleshooting";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form4_FormClosing);
this.Load += new System.EventHandler(this.Form4_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label4;
}
}

81
OTP/Form4.cs Normal file
View File

@ -0,0 +1,81 @@
using GuerrillaNtp;
using System;
using System.Windows.Forms;
namespace OTP
{
public partial class Form4 : Form
{
private NtpClient ntpClient;
private NtpClock clock;
private Timer timer;
public Form4()
{
InitializeComponent();
ntpClient = new NtpClient("time.pool.aliyun.com");
// Create and configure the timer
timer = new Timer();
timer.Interval = 1000; // 1 second interval
timer.Tick += Timer_Tick;
}
private async void Form4_Load(object sender, EventArgs e)
{
try
{
// Display local time
UpdateLocalTimeLabel();
// Query time from NTP server
clock = await ntpClient.QueryAsync();
// Display network time from NTP server
UpdateNetworkTimeLabel();
// Start the timer to update network time periodically
timer.Start();
}
catch (Exception ex)
{
// Handle any exceptions that might occur during NTP query
label4.Text = "NTP Error: " + ex.Message;
}
}
private void Timer_Tick(object sender, EventArgs e)
{
// Update the time label
UpdateLocalTimeLabel();
UpdateNetworkTimeLabel();
}
private void UpdateLocalTimeLabel()
{
DateTime localTime = DateTime.Now;
label2.Text = localTime.ToString();
}
private void UpdateNetworkTimeLabel()
{
if (clock != null)
{
DateTimeOffset networkTime = clock.UtcNow;
// Convert network time to user's local time zone
TimeZoneInfo localTimeZone = TimeZoneInfo.Local;
DateTimeOffset localTime = TimeZoneInfo.ConvertTime(networkTime, localTimeZone);
label4.Text = localTime.ToString();
}
}
// Form4 closing event
private void Form4_FormClosing(object sender, FormClosingEventArgs e)
{
// Stop the timer when the form is closing
timer.Stop();
}
}
}

120
OTP/Form4.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -23,7 +23,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>none</DebugType>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<StartupObject>OTP.Program</StartupObject> <StartupObject>OTP.Program</StartupObject>
@ -38,7 +38,7 @@
<SignAssembly>False</SignAssembly> <SignAssembly>False</SignAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType> <DebugType>none</DebugType>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="empty_key.db" /> <EmbeddedResource Include="empty_key.db" />
@ -59,16 +59,25 @@
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FlashCap" Version="1.10.0" />
<PackageReference Include="GuerrillaNtp" Version="3.1.0" />
<PackageReference Include="Otp.NET" Version="1.4.0" /> <PackageReference Include="Otp.NET" Version="1.4.0" />
<PackageReference Include="ScreenCapturer" Version="3.0.1" />
<PackageReference Include="SharpDX" Version="4.2.0" />
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
<PackageReference Include="SharpDX.DXGI" Version="4.2.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Data.SQLite" Version="1.0.118.0" /> <PackageReference Include="System.Data.SQLite" Version="1.0.118.0" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.118.0" /> <PackageReference Include="System.Data.SQLite.Core" Version="1.0.118.0" />
<PackageReference Include="System.Data.SQLite.EF6" Version="1.0.118.0" /> <PackageReference Include="System.Data.SQLite.EF6" Version="1.0.118.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" /> <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="ZXing.Net" Version="0.16.9" /> <PackageReference Include="ZXing.Net" Version="0.16.9" />
<PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.12" /> <PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.12" />
<PackageReference Include="EntityFramework" Version="6.5.1" /> <PackageReference Include="EntityFramework" Version="6.4.4" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.6" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Properties\Settings.Designer.cs"> <Compile Update="Properties\Settings.Designer.cs">

View File

@ -1,9 +1,5 @@
# OTP # OTP
这是一个适用于Windows平台的二步验证代码生成器 这是一个不太靠谱的适用于Windows平台的二步验证代码生成器
可满足基本TOTP验证器需求 .net8.0移植版本,功能基本已完成
------
<img src="https://git.chenx221.cyou/chenx221/OTP/raw/branch/net8.0/img/2024-08-22_201918.png">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB