基线 SVN r240
SVN-Revision: r240
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
/******************************
|
||||
* 说明:AES对称加密
|
||||
* 创建人:龚宇超
|
||||
* 创建日期:2018-06-21
|
||||
* 修改人:
|
||||
* 修改日期:
|
||||
* 修改备注:
|
||||
* 版本:1.0.0.0
|
||||
******************************/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance
|
||||
{
|
||||
/// <summary>
|
||||
/// AES对称加密
|
||||
/// </summary>
|
||||
public class AESUtil
|
||||
{
|
||||
private static string key = "lserpasebygyc222";
|
||||
|
||||
#region AES加解密
|
||||
/// <summary>
|
||||
///AES加密(加密步骤)
|
||||
///1,加密字符串得到2进制数组;
|
||||
///2,将2进制数组转为16进制;
|
||||
///3,进行base64编码
|
||||
/// </summary>
|
||||
/// <param name="toEncrypt">要加密的字符串</param>
|
||||
/// <param name="key">密钥</param>
|
||||
public static string Encrypt(string toEncrypt)
|
||||
{
|
||||
if (string.IsNullOrEmpty(toEncrypt)) return "";
|
||||
byte[] _key = Encoding.ASCII.GetBytes(key);
|
||||
byte[] _source = Encoding.UTF8.GetBytes(toEncrypt);
|
||||
|
||||
Aes aes = Aes.Create("AES");
|
||||
aes.Mode = CipherMode.ECB;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
aes.Key = _key;
|
||||
ICryptoTransform cTransform = aes.CreateEncryptor();
|
||||
byte[] cryptData = cTransform.TransformFinalBlock(_source, 0, _source.Length);
|
||||
string hexCryptString = Hex_2To16(cryptData);
|
||||
byte[] hexCryptData = Encoding.UTF8.GetBytes(hexCryptString);
|
||||
return Convert.ToBase64String(hexCryptData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AES解密(解密步骤)
|
||||
/// 1,将BASE64字符串转为16进制数组
|
||||
/// 2,将16进制数组转为字符串
|
||||
/// 3,将字符串转为2进制数据
|
||||
/// 4,用AES解密数据
|
||||
/// </summary>
|
||||
/// <param name="encryptedSource">已加密的内容</param>
|
||||
/// <param name="key">密钥</param>
|
||||
public static string Decrypt(string toDecrypt)
|
||||
{
|
||||
if (string.IsNullOrEmpty(toDecrypt)) return "";
|
||||
try
|
||||
{
|
||||
byte[] _key = Encoding.ASCII.GetBytes(key);
|
||||
Aes aes = Aes.Create("AES");
|
||||
aes.Mode = CipherMode.ECB;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
aes.Key = _key;
|
||||
ICryptoTransform cTransform = aes.CreateDecryptor();
|
||||
|
||||
byte[] encryptedData = Convert.FromBase64String(toDecrypt);
|
||||
string encryptedString = Encoding.UTF8.GetString(encryptedData);
|
||||
byte[] _source = Hex_16To2(encryptedString);
|
||||
byte[] originalSrouceData = cTransform.TransformFinalBlock(_source, 0, _source.Length);
|
||||
return Encoding.UTF8.GetString(originalSrouceData);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2进制转16进制
|
||||
/// </summary>
|
||||
static string Hex_2To16(byte[] bytes)
|
||||
{
|
||||
string hexString = string.Empty;
|
||||
Int32 iLength = 65535;
|
||||
if (bytes != null)
|
||||
{
|
||||
StringBuilder strB = new StringBuilder();
|
||||
|
||||
if (bytes.Length < iLength)
|
||||
{
|
||||
iLength = bytes.Length;
|
||||
}
|
||||
|
||||
for (int i = 0; i < iLength; i++)
|
||||
{
|
||||
strB.Append(bytes[i].ToString("X2"));
|
||||
}
|
||||
hexString = strB.ToString();
|
||||
}
|
||||
return hexString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 16进制转2进制
|
||||
/// </summary>
|
||||
static byte[] Hex_16To2(string hexString)
|
||||
{
|
||||
if ((hexString.Length % 2) != 0)
|
||||
{
|
||||
hexString += " ";
|
||||
}
|
||||
byte[] returnBytes = new Byte[hexString.Length / 2];
|
||||
for (Int32 i = 0; i < returnBytes.Length; i++)
|
||||
{
|
||||
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
|
||||
}
|
||||
return returnBytes;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance
|
||||
{
|
||||
partial class FrmMain
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows 窗体设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.pl_Top = new System.Windows.Forms.Panel();
|
||||
this.startBtn = new System.Windows.Forms.Button();
|
||||
this.txt_DBUser = new System.Windows.Forms.TextBox();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.txt_TimePoint = new System.Windows.Forms.TextBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.txt_Password = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.txt_DBName = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.txt_DBServer = new System.Windows.Forms.TextBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.pl_Bottom = new System.Windows.Forms.Panel();
|
||||
this.txt_Msg = new System.Windows.Forms.TextBox();
|
||||
this.txt_AppSecret = new System.Windows.Forms.TextBox();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.txt_AppKey = new System.Windows.Forms.TextBox();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.pl_Top.SuspendLayout();
|
||||
this.pl_Bottom.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// pl_Top
|
||||
//
|
||||
this.pl_Top.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.pl_Top.Controls.Add(this.txt_AppSecret);
|
||||
this.pl_Top.Controls.Add(this.label6);
|
||||
this.pl_Top.Controls.Add(this.txt_AppKey);
|
||||
this.pl_Top.Controls.Add(this.label7);
|
||||
this.pl_Top.Controls.Add(this.startBtn);
|
||||
this.pl_Top.Controls.Add(this.txt_DBUser);
|
||||
this.pl_Top.Controls.Add(this.label5);
|
||||
this.pl_Top.Controls.Add(this.txt_TimePoint);
|
||||
this.pl_Top.Controls.Add(this.label4);
|
||||
this.pl_Top.Controls.Add(this.txt_Password);
|
||||
this.pl_Top.Controls.Add(this.label3);
|
||||
this.pl_Top.Controls.Add(this.txt_DBName);
|
||||
this.pl_Top.Controls.Add(this.label2);
|
||||
this.pl_Top.Controls.Add(this.txt_DBServer);
|
||||
this.pl_Top.Controls.Add(this.label1);
|
||||
this.pl_Top.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.pl_Top.Location = new System.Drawing.Point(0, 0);
|
||||
this.pl_Top.Name = "pl_Top";
|
||||
this.pl_Top.Size = new System.Drawing.Size(610, 117);
|
||||
this.pl_Top.TabIndex = 0;
|
||||
//
|
||||
// startBtn
|
||||
//
|
||||
this.startBtn.Location = new System.Drawing.Point(524, 88);
|
||||
this.startBtn.Name = "startBtn";
|
||||
this.startBtn.Size = new System.Drawing.Size(75, 23);
|
||||
this.startBtn.TabIndex = 10;
|
||||
this.startBtn.Text = "开始同步";
|
||||
this.startBtn.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// txt_DBUser
|
||||
//
|
||||
this.txt_DBUser.Location = new System.Drawing.Point(96, 61);
|
||||
this.txt_DBUser.Name = "txt_DBUser";
|
||||
this.txt_DBUser.Size = new System.Drawing.Size(160, 21);
|
||||
this.txt_DBUser.TabIndex = 9;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(13, 66);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(77, 12);
|
||||
this.label5.TabIndex = 8;
|
||||
this.label5.Text = "数据库用户:";
|
||||
//
|
||||
// txt_TimePoint
|
||||
//
|
||||
this.txt_TimePoint.Location = new System.Drawing.Point(96, 89);
|
||||
this.txt_TimePoint.Name = "txt_TimePoint";
|
||||
this.txt_TimePoint.Size = new System.Drawing.Size(417, 21);
|
||||
this.txt_TimePoint.TabIndex = 7;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(13, 92);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(77, 12);
|
||||
this.label4.TabIndex = 6;
|
||||
this.label4.Text = "同步时间点:";
|
||||
//
|
||||
// txt_Password
|
||||
//
|
||||
this.txt_Password.Location = new System.Drawing.Point(353, 63);
|
||||
this.txt_Password.Name = "txt_Password";
|
||||
this.txt_Password.PasswordChar = '*';
|
||||
this.txt_Password.Size = new System.Drawing.Size(160, 21);
|
||||
this.txt_Password.TabIndex = 5;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(270, 66);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(77, 12);
|
||||
this.label3.TabIndex = 4;
|
||||
this.label3.Text = "数据库密码:";
|
||||
//
|
||||
// txt_DBName
|
||||
//
|
||||
this.txt_DBName.Location = new System.Drawing.Point(353, 36);
|
||||
this.txt_DBName.Name = "txt_DBName";
|
||||
this.txt_DBName.Size = new System.Drawing.Size(160, 21);
|
||||
this.txt_DBName.TabIndex = 3;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(270, 39);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(77, 12);
|
||||
this.label2.TabIndex = 2;
|
||||
this.label2.Text = "数据库名称:";
|
||||
//
|
||||
// txt_DBServer
|
||||
//
|
||||
this.txt_DBServer.Location = new System.Drawing.Point(96, 34);
|
||||
this.txt_DBServer.Name = "txt_DBServer";
|
||||
this.txt_DBServer.Size = new System.Drawing.Size(160, 21);
|
||||
this.txt_DBServer.TabIndex = 1;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(13, 39);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(77, 12);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "数据库地址:";
|
||||
//
|
||||
// pl_Bottom
|
||||
//
|
||||
this.pl_Bottom.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.pl_Bottom.Controls.Add(this.txt_Msg);
|
||||
this.pl_Bottom.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pl_Bottom.Location = new System.Drawing.Point(0, 117);
|
||||
this.pl_Bottom.Name = "pl_Bottom";
|
||||
this.pl_Bottom.Size = new System.Drawing.Size(610, 341);
|
||||
this.pl_Bottom.TabIndex = 1;
|
||||
//
|
||||
// txt_Msg
|
||||
//
|
||||
this.txt_Msg.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.txt_Msg.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txt_Msg.Location = new System.Drawing.Point(0, 0);
|
||||
this.txt_Msg.Multiline = true;
|
||||
this.txt_Msg.Name = "txt_Msg";
|
||||
this.txt_Msg.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.txt_Msg.Size = new System.Drawing.Size(608, 339);
|
||||
this.txt_Msg.TabIndex = 0;
|
||||
//
|
||||
// txt_AppSecret
|
||||
//
|
||||
this.txt_AppSecret.Location = new System.Drawing.Point(353, 9);
|
||||
this.txt_AppSecret.Name = "txt_AppSecret";
|
||||
this.txt_AppSecret.PasswordChar = '*';
|
||||
this.txt_AppSecret.Size = new System.Drawing.Size(160, 21);
|
||||
this.txt_AppSecret.TabIndex = 14;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(270, 12);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(71, 12);
|
||||
this.label6.TabIndex = 13;
|
||||
this.label6.Text = "AppSecret:";
|
||||
//
|
||||
// txt_AppKey
|
||||
//
|
||||
this.txt_AppKey.Location = new System.Drawing.Point(96, 7);
|
||||
this.txt_AppKey.Name = "txt_AppKey";
|
||||
this.txt_AppKey.Size = new System.Drawing.Size(160, 21);
|
||||
this.txt_AppKey.TabIndex = 12;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(13, 12);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(53, 12);
|
||||
this.label7.TabIndex = 11;
|
||||
this.label7.Text = "AppKey:";
|
||||
//
|
||||
// FrmMain
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(610, 458);
|
||||
this.Controls.Add(this.pl_Bottom);
|
||||
this.Controls.Add(this.pl_Top);
|
||||
this.Name = "FrmMain";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "获取打卡记录";
|
||||
this.pl_Top.ResumeLayout(false);
|
||||
this.pl_Top.PerformLayout();
|
||||
this.pl_Bottom.ResumeLayout(false);
|
||||
this.pl_Bottom.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel pl_Top;
|
||||
private System.Windows.Forms.Panel pl_Bottom;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox txt_DBName;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.TextBox txt_DBServer;
|
||||
private System.Windows.Forms.TextBox txt_Password;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.TextBox txt_DBUser;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.TextBox txt_TimePoint;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Button startBtn;
|
||||
private System.Windows.Forms.TextBox txt_Msg;
|
||||
private System.Windows.Forms.TextBox txt_AppSecret;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.TextBox txt_AppKey;
|
||||
private System.Windows.Forms.Label label7;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
using Lskj.Control;
|
||||
using Lskj.Core;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance
|
||||
{
|
||||
public partial class FrmMain : Form
|
||||
{
|
||||
public FrmMain()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Load += OnFrmMainLoad;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取数据的timer
|
||||
/// </summary>
|
||||
public System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
|
||||
/// <summary>
|
||||
/// 界面上下文
|
||||
/// </summary>
|
||||
public SynchronizationContext SyncContext;
|
||||
private void OnFrmMainLoad(object sender, EventArgs e)
|
||||
{
|
||||
string appKey = IniHelper.Read("AppKey");
|
||||
if (!string.IsNullOrEmpty(appKey))
|
||||
{
|
||||
txt_AppKey.Text = appKey;
|
||||
}
|
||||
string appSecret = IniHelper.Read("AppSecret");
|
||||
if (!string.IsNullOrEmpty(appSecret))
|
||||
{
|
||||
txt_AppSecret.Text = appSecret;
|
||||
}
|
||||
string dbServer = IniHelper.Read("DBServer");
|
||||
if (!string.IsNullOrEmpty(dbServer))
|
||||
{
|
||||
txt_DBServer.Text = dbServer;
|
||||
}
|
||||
string dbName = IniHelper.Read("DBName");
|
||||
if (!string.IsNullOrEmpty(dbName))
|
||||
{
|
||||
txt_DBName.Text = dbName;
|
||||
}
|
||||
string dbUser = IniHelper.Read("DBUser");
|
||||
if (!string.IsNullOrEmpty(dbUser))
|
||||
{
|
||||
txt_DBUser.Text = dbUser;
|
||||
}
|
||||
string password = IniHelper.Read("Password");
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
txt_Password.Text = password;
|
||||
}
|
||||
string timePoint = IniHelper.Read("TimePoint");
|
||||
if (!string.IsNullOrEmpty(timePoint))
|
||||
{
|
||||
txt_TimePoint.Text = timePoint;
|
||||
}
|
||||
txt_AppKey.TextChanged += OnTextChanged;
|
||||
txt_AppSecret.TextChanged += OnTextChanged;
|
||||
txt_DBName.TextChanged += OnTextChanged;
|
||||
txt_DBServer.TextChanged += OnTextChanged;
|
||||
txt_DBUser.TextChanged += OnTextChanged;
|
||||
txt_Password.TextChanged += OnTextChanged;
|
||||
txt_TimePoint.TextChanged += OnTextChanged;
|
||||
startBtn.Click += OnStartBtnClick;
|
||||
SyncContext = SynchronizationContext.Current;
|
||||
}
|
||||
/// <summary>
|
||||
/// 文本值改变时
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OnTextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (sender == txt_AppKey)
|
||||
{
|
||||
IniHelper.Write("AppKey", txt_AppKey.Text);
|
||||
}
|
||||
if (sender == txt_AppSecret)
|
||||
{
|
||||
IniHelper.Write("AppSecret", txt_AppSecret.Text);
|
||||
}
|
||||
if (sender == txt_DBServer)
|
||||
{
|
||||
IniHelper.Write("DBServer", txt_DBServer.Text);
|
||||
}
|
||||
if (sender == txt_DBName)
|
||||
{
|
||||
IniHelper.Write("DBName", txt_DBName.Text);
|
||||
}
|
||||
if (sender == txt_DBUser)
|
||||
{
|
||||
IniHelper.Write("DBUser", txt_DBUser.Text);
|
||||
}
|
||||
if (sender == txt_Password)
|
||||
{
|
||||
IniHelper.Write("Password", txt_Password.Text);
|
||||
}
|
||||
if (sender == txt_TimePoint)
|
||||
{
|
||||
IniHelper.Write("TimePoint", txt_TimePoint.Text);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 开始同步按钮点击
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OnStartBtnClick(object sender, EventArgs e)
|
||||
{
|
||||
DBConfig.Instance.ServerName = txt_DBServer.Text;
|
||||
DBConfig.Instance.DataBase = txt_DBName.Text;
|
||||
if (DBConfig.Instance.CreateConnection())
|
||||
{
|
||||
CreateAttendanceTable();
|
||||
timer.Interval = 200;
|
||||
timer.Tick += OnTimerTick;
|
||||
timer.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageUtil.Show("服务器连接失败");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// timer事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OnTimerTick(object sender, EventArgs e)
|
||||
{
|
||||
timer.Enabled = false;
|
||||
try
|
||||
{
|
||||
string[] timePoints = txt_TimePoint.Text.Split(',');
|
||||
foreach (string timePoint in timePoints)
|
||||
{
|
||||
if (DateTime.TryParse(timePoint, out DateTime dateTime))
|
||||
{
|
||||
if (DateTime.Now.TimeOfDay > dateTime.TimeOfDay)
|
||||
{
|
||||
string checkDateFrom = DateTime.Now.Date.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
string checkDateTo = DateTime.Now.Date.AddDays(1).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
string appkey = this.txt_AppKey.Text;
|
||||
string appsecret = this.txt_AppSecret.Text;
|
||||
HttpTools.setting("application/x-www-form-urlencoded", "", "");
|
||||
if (GetAccessToken(appkey, appsecret, out string accessToken))
|
||||
{
|
||||
List<string> deptsList = new List<string>();
|
||||
GetDepartmentsList(accessToken, "1", deptsList);
|
||||
List<string> usersList = new List<string>();
|
||||
foreach (string deptid in deptsList)
|
||||
{
|
||||
GetUsersList(accessToken, deptid, usersList);
|
||||
}
|
||||
foreach (string userid in usersList)
|
||||
{
|
||||
GetAttendance(accessToken, userid, checkDateFrom, checkDateTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SyncContext.Post(AddMsg, $"TimerTick:获取考勤信息失败,{ex.Message}。");
|
||||
}
|
||||
timer.Enabled = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新界面信息
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
private void AddMsg(object state)
|
||||
{
|
||||
string msg = state + "";
|
||||
txt_Msg.AppendText($"{msg}\r\n");
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建表
|
||||
/// </summary>
|
||||
private void CreateAttendanceTable()
|
||||
{
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.AppendLine("if not exists(select top 1 * from sysObjects where Id = OBJECT_ID(N'P_DingTalkAttendanceTab') and xtype = 'U')");
|
||||
sqlBuilder.AppendLine("begin");
|
||||
sqlBuilder.AppendLine("CREATE TABLE P_DingTalkAttendanceTab (id INT IDENTITY(1,1) PRIMARY KEY, gmtModified VARCHAR(200), baseCheckTime VARCHAR(200), groupId VARCHAR(200), timeResult VARCHAR(200), deviceId VARCHAR(200), approveId VARCHAR(200), userAccuracy VARCHAR(200), classId VARCHAR(200), workDate VARCHAR(200), bizId VARCHAR(200), planId VARCHAR(200), checkType VARCHAR(200), planCheckTime VARCHAR(200), corpId VARCHAR(200), locationResult VARCHAR(200), userLongitude VARCHAR(200), isLegal VARCHAR(200), procInstId VARCHAR(200), gmtCreate VARCHAR(200), userId VARCHAR(200), outsideRemark VARCHAR(200), userAddress VARCHAR(200), userLatitude VARCHAR(200), sourceType VARCHAR(200), userCheckTime VARCHAR(200), locationMethod VARCHAR(200));");
|
||||
sqlBuilder.AppendLine("end");
|
||||
SqlHelper.ExecuteNonQuery(sqlBuilder.ToString());
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取token
|
||||
/// </summary>
|
||||
/// <param name="appkey"></param>
|
||||
/// <param name="appsecret"></param>
|
||||
/// <param name="access_token"></param>
|
||||
/// <returns></returns>
|
||||
private bool GetAccessToken(string appkey, string appsecret, out string access_token)
|
||||
{
|
||||
bool success = true;
|
||||
access_token = "";
|
||||
try
|
||||
{
|
||||
string postUrl = $"https://oapi.dingtalk.com/gettoken";
|
||||
Dictionary<string, string> pmsDic = new Dictionary<string, string>();
|
||||
pmsDic.Add("appkey", appkey);
|
||||
pmsDic.Add("appsecret", appsecret);
|
||||
HttpWebResponse webResponse = HttpTools.Get(postUrl, "", pmsDic, null, HttpTools.Method.GET, out CookieCollection cookieCollection, out string result);
|
||||
if (webResponse != null && !string.IsNullOrEmpty(result))
|
||||
{
|
||||
JObject returnJObject = (JObject)JsonConvert.DeserializeObject(result);
|
||||
if (returnJObject.ContainsKey("errcode") && (returnJObject["errcode"] + "").Equals("0"))
|
||||
{
|
||||
access_token = returnJObject["access_token"] + "";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SyncContext.Post(AddMsg, $"GetAccessToken:accesstoken获取失败,{ex.Message}。");
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获部门信息
|
||||
/// </summary>
|
||||
/// <param name="access_token"></param>
|
||||
/// <param name="dept_id"></param>
|
||||
/// <param name="deptsList"></param>
|
||||
/// <returns></returns>
|
||||
private bool GetDepartmentsList(string access_token, string dept_id, List<string> deptsList)
|
||||
{
|
||||
if (deptsList == null)
|
||||
{
|
||||
deptsList = new List<string>();
|
||||
}
|
||||
bool success = true;
|
||||
try
|
||||
{
|
||||
string postUrl = $"https://oapi.dingtalk.com/topapi/v2/department/listsub?access_token={access_token}";
|
||||
JObject pmsJObject = new JObject();
|
||||
pmsJObject.Add("dept_id", dept_id);
|
||||
pmsJObject.Add("language", "zh_CN");
|
||||
string pmsBody = JsonConvert.SerializeObject(pmsJObject);
|
||||
HttpWebResponse webResponse = HttpTools.Post(postUrl, pmsBody, null, HttpTools.Method.POST, out CookieCollection cookieCollection, out string result);
|
||||
if (webResponse != null && !string.IsNullOrEmpty(result))
|
||||
{
|
||||
JObject returnJObject = (JObject)JsonConvert.DeserializeObject(result);
|
||||
if (returnJObject.ContainsKey("errcode") && (returnJObject["errcode"] + "").Equals("0"))
|
||||
{
|
||||
JArray departmentJArray = (JArray)returnJObject["result"];
|
||||
foreach (JObject item in departmentJArray)
|
||||
{
|
||||
string deptid = item["dept_id"] + "";
|
||||
deptsList.Add(deptid);
|
||||
GetDepartmentsList(access_token, deptid, deptsList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SyncContext.Post(AddMsg, $"GetDepartmentsList:部门{dept_id}信息获取失败,{ex.Message}。");
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取部门员工列表
|
||||
/// </summary>
|
||||
/// <param name="accessToken"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="checkDateFrom"></param>
|
||||
/// <param name="checkDateTo"></param>
|
||||
/// <returns></returns>
|
||||
private bool GetUsersList(string access_token, string dept_id, List<string> usersList)
|
||||
{
|
||||
if (usersList == null)
|
||||
{
|
||||
usersList = new List<string>();
|
||||
}
|
||||
bool success = true;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(access_token))
|
||||
{
|
||||
string postUrl = $"https://oapi.dingtalk.com/topapi/user/listid?access_token={access_token}";
|
||||
JObject pmsJObject = new JObject();
|
||||
pmsJObject.Add("dept_id", dept_id);
|
||||
string pmsBody = JsonConvert.SerializeObject(pmsJObject);
|
||||
HttpWebResponse webResponse = HttpTools.Post(postUrl, pmsBody, null, HttpTools.Method.POST, out CookieCollection cookieCollection, out string result);
|
||||
if (webResponse != null && !string.IsNullOrEmpty(result))
|
||||
{
|
||||
JObject returnJObject = (JObject)JsonConvert.DeserializeObject(result);
|
||||
if (returnJObject.ContainsKey("errcode") && (returnJObject["errcode"] + "").Equals("0"))
|
||||
{
|
||||
JArray usersJArray = (JArray)returnJObject["result"]["userid_list"];
|
||||
foreach (JValue item in usersJArray)
|
||||
{
|
||||
string userid = item.Value + "";
|
||||
usersList.Add(userid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SyncContext.Post(AddMsg, $"GetUsersList:部门{dept_id}员工列表信息获取失败,{ex.Message}。");
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取打卡记录
|
||||
/// </summary>
|
||||
/// <param name="accessToken"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="checkDateFrom"></param>
|
||||
/// <param name="checkDateTo"></param>
|
||||
/// <returns></returns>
|
||||
private bool GetAttendance(string access_token, string user, string checkDateFrom, string checkDateTo)
|
||||
{
|
||||
bool success = true;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(access_token))
|
||||
{
|
||||
string postUrl = $"https://oapi.dingtalk.com/attendance/listRecord?access_token={access_token}";
|
||||
JObject pmsJObject = new JObject();
|
||||
JArray userIdArray = new JArray();
|
||||
userIdArray.Add(user);
|
||||
pmsJObject.Add("userIds", userIdArray);
|
||||
pmsJObject.Add("checkDateFrom", checkDateFrom);
|
||||
pmsJObject.Add("checkDateTo", checkDateTo);
|
||||
pmsJObject.Add("isI18n", "false");
|
||||
string pmsBody = JsonConvert.SerializeObject(pmsJObject);
|
||||
HttpWebResponse webResponse = HttpTools.Post(postUrl, pmsBody, null, HttpTools.Method.POST, out CookieCollection cookieCollection, out string result);
|
||||
if (webResponse != null && !string.IsNullOrEmpty(result))
|
||||
{
|
||||
JObject returnJObject = (JObject)JsonConvert.DeserializeObject(result);
|
||||
if (returnJObject.ContainsKey("errcode") && (returnJObject["errcode"] + "").Equals("0"))
|
||||
{
|
||||
JArray resultJArray = (JArray)returnJObject["recordresult"];
|
||||
foreach (JObject item in resultJArray)
|
||||
{
|
||||
string gmtModified = item.ContainsKey("gmtModified") ? item["gmtModified"] + "" : "";
|
||||
string baseCheckTime = item.ContainsKey("baseCheckTime") ? item["baseCheckTime"] + "" : "";
|
||||
string groupId = item.ContainsKey("groupId") ? item["groupId"] + "" : "";
|
||||
string timeResult = item.ContainsKey("timeResult") ? item["timeResult"] + "" : "";
|
||||
string deviceId = item.ContainsKey("deviceId") ? item["deviceId"] + "" : "";
|
||||
string approveId = item.ContainsKey("approveId") ? item["approveId"] + "" : "";
|
||||
string userAccuracy = item.ContainsKey("userAccuracy") ? item["userAccuracy"] + "" : "";
|
||||
string classId = item.ContainsKey("classId") ? item["classId"] + "" : "";
|
||||
string workDate = item.ContainsKey("workDate") ? item["workDate"] + "" : "";
|
||||
string bizId = item.ContainsKey("bizId") ? item["bizId"] + "" : "";
|
||||
string planId = item.ContainsKey("planId") ? item["planId"] + "" : "";
|
||||
string id = item.ContainsKey("id") ? item["id"] + "" : "";
|
||||
string checkType = item.ContainsKey("checkType") ? item["checkType"] + "" : "";
|
||||
string planCheckTime = item.ContainsKey("planCheckTime") ? item["planCheckTime"] + "" : "";
|
||||
string corpId = item.ContainsKey("corpId") ? item["corpId"] + "" : "";
|
||||
string locationResult = item.ContainsKey("locationResult") ? item["locationResult"] + "" : "";
|
||||
string userLongitude = item.ContainsKey("userLongitude") ? item["userLongitude"] + "" : "";
|
||||
string isLegal = item.ContainsKey("isLegal") ? item["isLegal"] + "" : "";
|
||||
string procInstId = item.ContainsKey("procInstId") ? item["procInstId"] + "" : "";
|
||||
string gmtCreate = item.ContainsKey("gmtCreate") ? item["gmtCreate"] + "" : "";
|
||||
string userId = item.ContainsKey("userId") ? item["userId"] + "" : "";
|
||||
string outsideRemark = item.ContainsKey("outsideRemark") ? item["outsideRemark"] + "" : "";
|
||||
string userAddress = item.ContainsKey("userAddress") ? item["userAddress"] + "" : "";
|
||||
string userLatitude = item.ContainsKey("userLatitude") ? item["userLatitude"] + "" : "";
|
||||
string sourceType = item.ContainsKey("sourceType") ? item["sourceType"] + "" : "";
|
||||
string userCheckTime = item.ContainsKey("userCheckTime") ? item["userCheckTime"] + "" : "";
|
||||
string locationMethod = item.ContainsKey("locationMethod") ? item["locationMethod"] + "" : "";
|
||||
string insertSql = $"insert into P_DingTalkAttendanceTab (gmtModified, baseCheckTime, groupId, timeResult, deviceId, approveId, userAccuracy, classId, workDate, bizId, planId, id, checkType, planCheckTime, corpId, locationResult, userLongitude, isLegal, procInstId, gmtCreate, userId, outsideRemark, userAddress, userLatitude, sourceType, userCheckTime, locationMethod) values ('{gmtModified}', '{baseCheckTime}', '{groupId}', '{timeResult}', '{deviceId}', '{approveId}', '{userAccuracy}', '{classId}', '{workDate}', '{bizId}', '{planId}', '{id}', '{checkType}', '{planCheckTime}', '{corpId}', '{locationResult}', '{userLongitude}', '{isLegal}', '{procInstId}', '{gmtCreate}', '{userId}', '{outsideRemark}', '{userAddress}', '{userLatitude}', '{sourceType}', '{userCheckTime}', '{locationMethod}');";
|
||||
SqlHelper.ExecuteNonQuery(insertSql);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SyncContext.Post(AddMsg, $"GetAttendance:人员{user}签到信息获取失败,{ex.Message}。");
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,358 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance
|
||||
{
|
||||
public static class HttpTools
|
||||
{
|
||||
public enum Encode
|
||||
{
|
||||
Default = 0,
|
||||
UTF8 = 1
|
||||
}
|
||||
public static CookieContainer cookie = new CookieContainer(); // 用于记录访问网页时cookie数据
|
||||
public static CookieCollection cookieCollection;
|
||||
private static string ContentType = string.Empty;// "application/x-www-form-urlencoded";
|
||||
private static string Accept = string.Empty;//"text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
|
||||
private static string UserAgent = string.Empty;//"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14";
|
||||
private static Encode EncodeMode = Encode.Default;
|
||||
public enum Method
|
||||
{
|
||||
POST = 0,
|
||||
GET = 1
|
||||
}
|
||||
public static void setting(string contentType, string accept, string userAgent, Encode encode = Encode.Default)
|
||||
{
|
||||
ContentType = contentType;
|
||||
Accept = accept;
|
||||
UserAgent = userAgent;
|
||||
EncodeMode = encode;
|
||||
}
|
||||
/// <summary>
|
||||
/// post数据到指定的网址,获取cookie数据,和返回页
|
||||
/// </summary>
|
||||
public static HttpWebResponse Post(string url, string postData, Dictionary<string, string> pmsDic, Dictionary<string, string> headerDic, Method method)
|
||||
{
|
||||
if (method == Method.POST)
|
||||
{
|
||||
return Post(url, postData, pmsDic, headerDic, method, out cookieCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Get(url, postData, pmsDic, headerDic, method, out cookieCollection, out _);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// post数据到指定的网址,获取cookie数据,和返回页
|
||||
/// </summary>
|
||||
public static HttpWebResponse Post(string url, string postData, Dictionary<string, string> pmsDic, Dictionary<string, string> headerDic, Method method, out CookieCollection cookieCollection)
|
||||
{
|
||||
HttpWebResponse httpWebResponse = null;
|
||||
try
|
||||
{
|
||||
HttpWebRequest httpWebRequest;
|
||||
httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||
|
||||
httpWebRequest.CookieContainer = cookie;
|
||||
httpWebRequest.ContentType = ContentType;
|
||||
//httpWebRequest.Referer = url;
|
||||
httpWebRequest.Accept = Accept;
|
||||
httpWebRequest.UserAgent = UserAgent;
|
||||
httpWebRequest.Method = method == Method.POST ? "POST" : "GET";
|
||||
byte[] byteRequest = null;
|
||||
if (headerDic != null)
|
||||
{
|
||||
foreach (var item in headerDic)
|
||||
{
|
||||
if (item.Key.Equals("Content-Type"))
|
||||
{
|
||||
httpWebRequest.ContentType = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
httpWebRequest.Headers.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(postData))
|
||||
{
|
||||
switch (EncodeMode)
|
||||
{
|
||||
case Encode.Default:
|
||||
byteRequest = Encoding.Default.GetBytes(postData);
|
||||
break;
|
||||
case Encode.UTF8:
|
||||
byteRequest = Encoding.UTF8.GetBytes(postData);
|
||||
break;
|
||||
}
|
||||
httpWebRequest.ContentLength = byteRequest.Length;
|
||||
Stream stream = httpWebRequest.GetRequestStream();
|
||||
stream.Write(byteRequest, 0, byteRequest.Length);
|
||||
stream.Close();
|
||||
}
|
||||
else if (pmsDic != null)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int i = 0;
|
||||
foreach (var item in pmsDic)
|
||||
{
|
||||
if (i > 0)
|
||||
builder.Append("&");
|
||||
builder.AppendFormat("{0}={1}", item.Key, item.Value);
|
||||
i++;
|
||||
}
|
||||
switch (EncodeMode)
|
||||
{
|
||||
case Encode.Default:
|
||||
byteRequest = Encoding.Default.GetBytes(builder.ToString());
|
||||
break;
|
||||
case Encode.UTF8:
|
||||
byteRequest = Encoding.UTF8.GetBytes(builder.ToString());
|
||||
break;
|
||||
}
|
||||
httpWebRequest.ContentLength = byteRequest.Length;
|
||||
Stream stream = httpWebRequest.GetRequestStream();
|
||||
stream.Write(byteRequest, 0, byteRequest.Length);
|
||||
stream.Close();
|
||||
}
|
||||
httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
|
||||
cookie = httpWebRequest.CookieContainer;
|
||||
cookieCollection = cookie.GetCookies(new Uri(url));
|
||||
return httpWebResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
cookieCollection = null;
|
||||
return httpWebResponse;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Get到指定的网址,获取cookie数据,和返回页
|
||||
/// </summary>
|
||||
public static HttpWebResponse Get(string url, string postData, Dictionary<string, string> pmsDic, Dictionary<string, string> headerDic, Method method, out CookieCollection cookieCollection, out string result)
|
||||
{
|
||||
result = "";
|
||||
HttpWebResponse httpWebResponse = null;
|
||||
try
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(url);
|
||||
if (pmsDic != null && pmsDic.Count > 0)
|
||||
{
|
||||
builder.Append("?");
|
||||
int i = 0;
|
||||
foreach (var item in pmsDic)
|
||||
{
|
||||
if (i > 0)
|
||||
builder.Append("&");
|
||||
builder.AppendFormat("{0}={1}", item.Key, item.Value);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
HttpWebRequest httpWebRequest;
|
||||
httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(builder.ToString());
|
||||
httpWebRequest.CookieContainer = cookie;
|
||||
httpWebRequest.ContentType = ContentType;
|
||||
//httpWebRequest.Referer = url;
|
||||
httpWebRequest.Accept = Accept;
|
||||
httpWebRequest.UserAgent = UserAgent;
|
||||
httpWebRequest.Method = method == Method.POST ? "POST" : "GET";
|
||||
byte[] byteRequest = null;
|
||||
if (headerDic != null)
|
||||
{
|
||||
foreach (var item in headerDic)
|
||||
{
|
||||
if (item.Key.Equals("Content-Type"))
|
||||
{
|
||||
httpWebRequest.ContentType = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
httpWebRequest.Headers.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
|
||||
Stream responseStream = httpWebResponse.GetResponseStream();
|
||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
|
||||
result = streamReader.ReadToEnd();
|
||||
streamReader.Close();
|
||||
responseStream.Close();
|
||||
cookie = httpWebRequest.CookieContainer;
|
||||
cookieCollection = cookie.GetCookies(new Uri(url));
|
||||
return httpWebResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
cookieCollection = null;
|
||||
return httpWebResponse;
|
||||
}
|
||||
}
|
||||
public static HttpWebResponse Post(string url, string postData, Dictionary<string, string> dic, Method method, out CookieCollection cookieCollection, out string result)
|
||||
{
|
||||
result = "";
|
||||
HttpWebResponse httpWebResponse = null;
|
||||
try
|
||||
{
|
||||
HttpWebRequest httpWebRequest;
|
||||
httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||
httpWebRequest.CookieContainer = cookie;
|
||||
httpWebRequest.ContentType = ContentType;
|
||||
//httpWebRequest.Referer = url;
|
||||
httpWebRequest.Accept = Accept;
|
||||
httpWebRequest.UserAgent = UserAgent;
|
||||
httpWebRequest.Method = method == Method.POST ? "POST" : "GET";
|
||||
byte[] byteRequest = null;
|
||||
if (!string.IsNullOrEmpty(postData))
|
||||
{
|
||||
switch (EncodeMode)
|
||||
{
|
||||
case Encode.Default:
|
||||
byteRequest = Encoding.Default.GetBytes(postData);
|
||||
break;
|
||||
case Encode.UTF8:
|
||||
byteRequest = Encoding.UTF8.GetBytes(postData);
|
||||
break;
|
||||
}
|
||||
httpWebRequest.ContentLength = byteRequest.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int i = 0;
|
||||
if (dic != null)
|
||||
{
|
||||
foreach (var item in dic)
|
||||
{
|
||||
if (i > 0)
|
||||
builder.Append("&");
|
||||
builder.AppendFormat("{0}={1}", item.Key, item.Value);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
switch (EncodeMode)
|
||||
{
|
||||
case Encode.Default:
|
||||
byteRequest = Encoding.Default.GetBytes(builder.ToString());
|
||||
break;
|
||||
case Encode.UTF8:
|
||||
byteRequest = Encoding.UTF8.GetBytes(builder.ToString());
|
||||
break;
|
||||
}
|
||||
httpWebRequest.ContentLength = byteRequest.Length;
|
||||
}
|
||||
Stream stream = httpWebRequest.GetRequestStream();
|
||||
stream.Write(byteRequest, 0, byteRequest.Length);
|
||||
stream.Close();
|
||||
|
||||
httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
|
||||
Stream responseStream = httpWebResponse.GetResponseStream();
|
||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
|
||||
result = streamReader.ReadToEnd();
|
||||
streamReader.Close();
|
||||
responseStream.Close();
|
||||
cookie = httpWebRequest.CookieContainer;
|
||||
cookieCollection = cookie.GetCookies(new Uri(url));
|
||||
return httpWebResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
cookieCollection = null;
|
||||
result = ex.Message;
|
||||
return httpWebResponse;
|
||||
}
|
||||
}
|
||||
public static HttpWebResponse Post(string url, string postData, Dictionary<string, string> dic, Dictionary<string, string> headerDic, Method method, out CookieCollection cookieCollection, out string result)
|
||||
{
|
||||
result = "";
|
||||
HttpWebResponse httpWebResponse = null;
|
||||
try
|
||||
{
|
||||
HttpWebRequest httpWebRequest;
|
||||
httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||
httpWebRequest.CookieContainer = cookie;
|
||||
httpWebRequest.ContentType = ContentType;
|
||||
//httpWebRequest.Referer = url;
|
||||
httpWebRequest.Accept = Accept;
|
||||
httpWebRequest.UserAgent = UserAgent;
|
||||
httpWebRequest.Method = method == Method.POST ? "POST" : "GET";
|
||||
byte[] byteRequest = null;
|
||||
if (headerDic != null)
|
||||
{
|
||||
foreach (var item in headerDic)
|
||||
{
|
||||
if (item.Key.Equals("Content-Type"))
|
||||
{
|
||||
httpWebRequest.ContentType = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
httpWebRequest.Headers.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(postData))
|
||||
{
|
||||
switch (EncodeMode)
|
||||
{
|
||||
case Encode.Default:
|
||||
byteRequest = Encoding.Default.GetBytes(postData);
|
||||
break;
|
||||
case Encode.UTF8:
|
||||
byteRequest = Encoding.UTF8.GetBytes(postData);
|
||||
break;
|
||||
}
|
||||
httpWebRequest.ContentLength = byteRequest.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int i = 0;
|
||||
if (dic != null)
|
||||
{
|
||||
foreach (var item in dic)
|
||||
{
|
||||
if (i > 0)
|
||||
builder.Append("&");
|
||||
builder.AppendFormat("{0}={1}", item.Key, item.Value);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
switch (EncodeMode)
|
||||
{
|
||||
case Encode.Default:
|
||||
byteRequest = Encoding.Default.GetBytes(builder.ToString());
|
||||
break;
|
||||
case Encode.UTF8:
|
||||
byteRequest = Encoding.UTF8.GetBytes(builder.ToString());
|
||||
break;
|
||||
}
|
||||
httpWebRequest.ContentLength = byteRequest.Length;
|
||||
}
|
||||
Stream stream = httpWebRequest.GetRequestStream();
|
||||
stream.Write(byteRequest, 0, byteRequest.Length);
|
||||
stream.Close();
|
||||
|
||||
httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
|
||||
Stream responseStream = httpWebResponse.GetResponseStream();
|
||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
|
||||
result = streamReader.ReadToEnd();
|
||||
streamReader.Close();
|
||||
responseStream.Close();
|
||||
cookie = httpWebRequest.CookieContainer;
|
||||
cookieCollection = cookie.GetCookies(new Uri(url));
|
||||
return httpWebResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
cookieCollection = null;
|
||||
result = ex.Message;
|
||||
return httpWebResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance
|
||||
{
|
||||
/// <summary>
|
||||
/// Ini 文件操作类
|
||||
/// </summary>
|
||||
public static class IniHelper
|
||||
{
|
||||
public static string AbsolutelyPath
|
||||
{
|
||||
get { return Application.StartupPath + "\\"; }
|
||||
}
|
||||
public static string MainMenuConfigPath
|
||||
{
|
||||
get { return AbsolutelyPath + "MenuConfig.ini"; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 写入INI文件
|
||||
/// </summary>
|
||||
/// <param name="section">节点名称[如[TypeName]]</param>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="val">值</param>
|
||||
/// <param name="filepath">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[DllImport("kernel32")]
|
||||
private static extern long WritePrivateProfileString(string section, string key, string val, string filepath);
|
||||
/// <summary>
|
||||
/// 读取INI文件
|
||||
/// </summary>
|
||||
/// <param name="section">节点名称</param>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="def">值</param>
|
||||
/// <param name="retval">stringbulider对象</param>
|
||||
/// <param name="size">字节大小</param>
|
||||
/// <param name="filePath">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[DllImport("kernel32")]
|
||||
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retval, int size, string filePath);
|
||||
/// <summary>
|
||||
/// 获取某个指定节点(Section)中所有KEY和Value
|
||||
/// </summary>
|
||||
/// <param name="lpAppName">节点名称</param>
|
||||
/// <param name="lpReturnedString">返回值的内存地址,每个之间用\0分隔</param>
|
||||
/// <param name="nSize">内存大小(characters)</param>
|
||||
/// <param name="lpFileName">Ini文件</param>
|
||||
/// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>
|
||||
[DllImport("kernel32")]
|
||||
private static extern int GetPrivateProfileSection(string lpAppName, byte[] lpszReturnBuffer, int nSize, string lpFileName);
|
||||
/// <summary>
|
||||
/// <para>说明:写入Ini文件(以键值对的形式存放)</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2017-07-22</para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns></returns>
|
||||
public static void Write(string key, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
key = HttpUtility.UrlEncode(AESUtil.Encrypt(key));
|
||||
value = HttpUtility.UrlEncode(AESUtil.Encrypt(value));
|
||||
//根据INI文件名设置要写入INI文件的节点名称
|
||||
//此处的节点名称完全可以根据实际需要进行配置
|
||||
string filePath = MainMenuConfigPath;
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
File.Create(filePath);
|
||||
}
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
WritePrivateProfileString(fileName, key, value, filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:通过Key获取Value值</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2017-07-22</para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="key">键</param>
|
||||
/// <returns>值</returns>
|
||||
public static string Read(string key)
|
||||
{
|
||||
key = HttpUtility.UrlEncode(AESUtil.Encrypt(key));
|
||||
string value = string.Empty;
|
||||
try
|
||||
{
|
||||
//判读INI文件是否存在
|
||||
string filePath = MainMenuConfigPath;
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
StringBuilder temp = new StringBuilder(1024);
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
GetPrivateProfileString(fileName, key, "", temp, 1024, filePath);
|
||||
return AESUtil.Decrypt(HttpUtility.UrlDecode(temp.ToString()));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:写入Ini文件(以键值对的形式存放)</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2017-07-22</para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns></returns>
|
||||
public static void Write(string iniName, string key, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
//根据INI文件名设置要写入INI文件的节点名称
|
||||
//此处的节点名称完全可以根据实际需要进行配置
|
||||
string filePath = Path.Combine(new string[] { AbsolutelyPath + iniName });
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
File.Create(filePath);
|
||||
}
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
WritePrivateProfileString(fileName, key, value, filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:通过Key获取Value值</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2017-07-22</para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="key">键</param>
|
||||
/// <returns>值</returns>
|
||||
public static string Read(string iniName, string key)
|
||||
{
|
||||
string value = string.Empty;
|
||||
try
|
||||
{
|
||||
//判读INI文件是否存在
|
||||
string filePath = Path.Combine(new string[] { AbsolutelyPath + iniName });
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
StringBuilder temp = new StringBuilder(1024);
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
GetPrivateProfileString(fileName, key, "", temp, 1024, filePath);
|
||||
|
||||
return temp + "";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:通过Key获取Value值</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2017-07-22</para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="key">键</param>
|
||||
/// <returns>值</returns>
|
||||
public static string Read(string iniName, string mainKey, string listKey)
|
||||
{
|
||||
string value = string.Empty;
|
||||
try
|
||||
{
|
||||
//判读INI文件是否存在
|
||||
string filePath = Path.Combine(new string[] { AbsolutelyPath + iniName });
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
StringBuilder temp = new StringBuilder(1024);
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
GetPrivateProfileString(mainKey, listKey, "", temp, 1024, filePath);
|
||||
return temp + "";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取INI文件中指定节点(Section)中的所有条目(key=value形式)
|
||||
/// </summary>
|
||||
/// <param name="iniFile">Ini文件</param>
|
||||
/// <param name="section">节点名称</param>
|
||||
/// <returns>指定节点中的所有项目,没有内容返回string[0]</returns>
|
||||
public static Dictionary<string, string> GetSectionKeys(string iniFile, string category)
|
||||
{
|
||||
Dictionary<string, string> result = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
string filePath = Path.Combine(new string[] { AbsolutelyPath + iniFile });
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
byte[] buffer = new byte[2048];
|
||||
GetPrivateProfileSection(category, buffer, 2048, filePath);
|
||||
String[] tmp = Encoding.Default.GetString(buffer).Trim('\0').Split('\0');
|
||||
foreach (String entry in tmp)
|
||||
{
|
||||
string[] v = entry.Split('=');
|
||||
result.Add(v[0], v[1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A43F12D9-E92B-401E-863C-EA286D85969D}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>Lskj.GetDingTalkAttendance</RootNamespace>
|
||||
<AssemblyName>Lskj.GetDingTalkAttendance</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Lskj.Control">
|
||||
<HintPath>..\..\..\Debug\Lskj.Control.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lskj.Core">
|
||||
<HintPath>..\..\..\Debug\Lskj.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lskj.Util">
|
||||
<HintPath>..\..\..\Debug\Lskj.Util.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.1.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\引用DLL\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AESUtil.cs" />
|
||||
<Compile Include="FrmMain.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FrmMain.Designer.cs">
|
||||
<DependentUpon>FrmMain.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="HttpTools.cs" />
|
||||
<Compile Include="IniHelper.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="FrmMain.resx">
|
||||
<DependentUpon>FrmMain.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new FrmMain());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Lskj.GetDingTalkAttendance")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Lskj.GetDingTalkAttendance")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2025")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("a43f12d9-e92b-401e-863c-ea286d85969d")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
Generated
+70
@@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本: 4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能导致不正确的行为,如果
|
||||
// 重新生成代码,则所做更改将丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance.Properties
|
||||
{
|
||||
/// <summary>
|
||||
/// 强类型资源类,用于查找本地化字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lskj.GetDingTalkAttendance.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?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.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: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" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Generated
+29
@@ -0,0 +1,29 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Lskj.GetDingTalkAttendance.Properties
|
||||
{
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
Reference in New Issue
Block a user