/// <summary> /// 从url处获取图像(经过memory缓存) /// </summary> /// <param name="url"></param> /// <returns></returns> private static Image _load_image_from_url(string url) { var req = new NetStream(); req.RetryTimes = 3; var header = new Parameters(); header.Add("Origin", "https://passport.bilibili.com"); header.Add("Referer", "https://passport.bilibili.com/login"); req.HttpGet(url, header); var stream = req.Stream; var out_stream = new MemoryStream(); int read = 0; var buffer = new byte[16384]; do { read = stream.Read(buffer, 0, 16384); out_stream.Write(buffer, 0, read); } while (read > 0); out_stream.Seek(0, SeekOrigin.Begin); req.Close(); return(Image.FromStream(out_stream)); }
private _logincheck_result _v2_api__logincheck(string token, string username) { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; try { Tracer.GlobalTracer.TraceInfo("Fetching: logincheck"); var param = new Parameters(); param.Add("token", token); param.Add("tpl", "netdisk"); param.Add("subpro", "netdisk_web"); param.Add("apiver", "v3"); param.Add("tt", (long)(util.ToUnixTimestamp(DateTime.Now) * 1000)); param.Add("sub_source", "leadsetpwd"); param.Add("username", username); param.Add("loginversion", "v4"); param.Add("dv", "i_do_not_know_this_param"); param.Add("traceid", ""); param.Add("callback", "bd__cbs__ababab"); var referer = new Parameters(); referer.Add("Referer", "https://pan.baidu.com/"); ns.HttpGet("https://passport.baidu.com/v2/api/?logincheck&" + param.BuildQueryString(), headerParam: referer); var api_result = ns.ReadResponseString(); api_result = _escape_callback_function(api_result); var json_api_result = JsonConvert.DeserializeObject(api_result) as JObject; var errno = json_api_result["errInfo"].Value <string>("no"); if (errno != "0") { throw new LoginFailedException("failed to get logincheck: " + api_result.ToString()); } return(new _logincheck_result() { codestring = json_api_result["data"].Value <string>("codeString"), vcodetype = json_api_result["data"].Value <string>("vcodetype") }); } catch (LoginFailedException ex) { throw ex; } catch (Exception ex) { throw new LoginFailedException("logincheck failed", ex); } }
//获取验证信息 private static void _fetch_auth_info() { if (string.IsNullOrEmpty(_access_token)) { throw new ArgumentNullException("Access Token could not be null or empty"); } var ns = new NetStream(); var param = new Parameters(); param.Add("access_token", _access_token); param.Add("appkey", APPKEY); param.Add("build", "513000"); param.Add("mobi_app", "android"); param.Add("platform", "android"); param.Add("ts", (long)util.ToUnixTimestamp(DateTime.Now)); param.Add("sign", CalculateSign(param)); ns.UserAgent = ANDROID_USER_AGENT; try { ns.HttpGet(_URL_AUTH_INFO, urlParam: param); var response = ns.ReadResponseString(); ns.Close(); var json = JsonConvert.DeserializeObject(response) as JObject; int code = json.Value <int>("code"); if (code != 0) { Tracer.GlobalTracer.TraceError("Error code: " + code); Tracer.GlobalTracer.TraceError(json.ToString()); } else { _appid = json["data"].Value <int>("appid"); var ts = util.FromUnixTimestamp(json.Value <long>("ts")); _expire_time = ts.AddSeconds(json["data"].Value <int>("expires_in")); _mid = json["data"].Value <uint>("mid"); _uname = json["data"].Value <string>("uname"); _userid = json["data"].Value <string>("userid"); } } catch (Exception ex) { Tracer.GlobalTracer.TraceError(ex.ToString()); throw ex; } finally { ns.Close(); } }
private _getpublickey_result _v2_getpublickey(string token, string gid) { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; try { Tracer.GlobalTracer.TraceInfo("Fetching: getpublickey"); var param = new Parameters(); param.Add("token", token); param.Add("tpl", "netdisk"); param.Add("subpro", "netdisk_web"); param.Add("apiver", "v3"); param.Add("tt", (long)(util.ToUnixTimestamp(DateTime.Now) * 1000)); param.Add("gid", gid); param.Add("loginversion", "v4"); param.Add("traceid", ""); param.Add("callback", "bd__cbs__emmmmm"); var referer = new Parameters(); referer.Add("Referer", "https://pan.baidu.com/"); ns.HttpGet("https://passport.baidu.com/v2/getpublickey", urlParam: param, headerParam: referer); var api_result = ns.ReadResponseString(); api_result = _escape_callback_function(api_result); var json_api_result = JsonConvert.DeserializeObject(api_result) as JObject; var errno = json_api_result.Value <string>("errno"); if (errno != "0") { throw new LoginFailedException("failed to get getpublickey: " + json_api_result.ToString()); } return(new _getpublickey_result() { key = json_api_result.Value <string>("key"), pubkey = json_api_result.Value <string>("pubkey") }); } catch (LoginFailedException ex) { throw ex; } catch (Exception ex) { throw new LoginFailedException("get getpublickey failed", ex); } }
// method implementation of GET /v2/api/?getapi private string _v2_api__getapi(string gid) { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; try { Tracer.GlobalTracer.TraceInfo("Fetching: getapi"); var query_param = new Parameters(); query_param.Add("tpl", "netdisk"); query_param.Add("subpro", "netdisk_web"); query_param.Add("apiver", "v3"); query_param.Add("tt", (long)(util.ToUnixTimestamp(DateTime.Now) * 1000)); query_param.Add("class", "login"); query_param.Add("gid", gid); query_param.Add("loginversion", "v4"); query_param.Add("logintype", "basicLogin"); query_param.Add("traceid", ""); query_param.Add("callback", "bd__cbs__abcdef"); var referer = new Parameters(); referer.Add("Referer", "https://pan.baidu.com/"); ns.HttpGet("https://passport.baidu.com/v2/api/?getapi&" + query_param.BuildQueryString(), headerParam: referer); var api_result = ns.ReadResponseString(); api_result = _escape_callback_function(api_result); var json_api_result = JsonConvert.DeserializeObject(api_result) as JObject; var errno = json_api_result["errInfo"].Value <string>("no"); if (errno != "0") { throw new LoginFailedException("failed to get token: " + json_api_result.ToString()); } return(json_api_result["data"].Value <string>("token")); } catch (LoginFailedException ex) { throw ex; } catch (Exception ex) { throw new LoginFailedException("getapi failed", ex); } finally { ns.Close(); } }
private _regetcodestr_result _v2__reggetcodestr(string token, string vcodetype) { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; try { Tracer.GlobalTracer.TraceInfo("Fetching: reggetcodestr"); var param = new Parameters(); param.Add("token", token); param.Add("tpl", "netdisk"); param.Add("subpro", "netdisk_web"); param.Add("apiver", "v3"); param.Add("tt", (long)(util.ToUnixTimestamp(DateTime.Now) * 1000)); param.Add("fr", "login"); param.Add("loginversion", "v4"); param.Add("vcodetype", vcodetype); param.Add("traceid", ""); param.Add("callback", "bd__cbs__nyanya"); var referer = new Parameters(); referer.Add("Referer", "https://pan.baidu.com/"); ns.HttpGet("https://passport.baidu.com/v2/?reggetcodestr&" + param.BuildQueryString(), headerParam: referer); var api_result = ns.ReadResponseString(); api_result = _escape_callback_function(api_result); var json_api_result = JsonConvert.DeserializeObject(api_result) as JObject; var errno = json_api_result["errInfo"].Value <string>("no"); if (errno != "0") { throw new Exception("get captcha failed"); } return(new _regetcodestr_result() { verifysign = json_api_result["data"].Value <string>("verifySign"), verifystr = json_api_result["data"].Value <string>("verifyStr") }); } finally { ns.Close(); } }
/// <summary> /// 获取当前用户的名称 /// </summary> /// <returns></returns> private void _init_user_nickname() { try { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; ns.RetryDelay = 1000; ns.RetryTimes = 3; ns.HttpGet(_BAIDU_ROOT_URL); var response_data = ns.ReadResponseString().Replace("\r", "").Replace("\n", ""); var reg = Regex.Match(response_data, "bds\\.comm\\.user\\s*=\\s*\"(?<user>[^\"]*)\";"); if (reg.Success) { _nickname = reg.Result("${user}"); } ns.Close(); } catch (Exception ex) { Tracer.GlobalTracer.TraceError(ex); } }
//初始化token并返回token private string _get_token() { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; try { if (_token == null) { Tracer.GlobalTracer.TraceInfo("Fetching netdisk main page"); ns.HttpGet("https://pan.baidu.com/"); ns.Close(); _token = _v2_api__getapi(_get_guid()); } } finally { ns.Close(); } return(_token); }
// method implementation of /cgi-bin/genimage private Image _cgi_bin_genimage(string codestring) { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; try { Tracer.GlobalTracer.TraceInfo("Fetching: genimage"); ns.HttpGet("https://passport.baidu.com/cgi-bin/genimage?" + codestring); var binary_data = ns.ReadResponseBinary(); var ms = new MemoryStream(binary_data); return(Image.FromStream(ms)); } catch (Exception ex) { throw ex; } finally { ns.Close(); } }
public static string DoChallenge() { _challenge = string.Empty; _validate = string.Empty; try { //前戏: 获取有关geetest的参数 //string gt & string challenge var challenge_url = string.Format(_challenge_url, Convert.ToInt64(util.ToUnixTimestamp(DateTime.Now) * 1000)); var req = new NetStream(); var xhr_param = new Parameters(); xhr_param.Add("X-Requested-With", "XMLHttpRequest"); xhr_param.Add("Referer", "https://passport.bilibili.com/login"); req.HttpGet(challenge_url, xhr_param); var rep = req.ReadResponseString(); var json_rep = JsonConvert.DeserializeObject(rep) as JObject; var challenge = json_rep["data"].Value <string>("challenge"); var gt = json_rep["data"].Value <string>("gt"); req.Close(); //string path & string static_server var ref_param = new Parameters(); ref_param.Add("Referer", "https://passport.bilibili.com/login"); var gettype_url = string.Format(_gettype_url, gt); req.HttpGet(gettype_url, ref_param); rep = req.ReadResponseString(); json_rep = JsonConvert.DeserializeObject(rep.Substring(3, rep.Length - 4)) as JObject; var path = json_rep["data"].Value <string>("path"); var static_server = json_rep["data"]["static_servers"].Value <string>(0); req.Close(); //Image fullbg & Image slice & Image bg var get_url = string.Format(_get_url, gt, challenge, path); req.HttpGet(get_url, ref_param); rep = req.ReadResponseString(); json_rep = JsonConvert.DeserializeObject(rep.Substring(3, rep.Length - 4)) as JObject; var bg = json_rep.Value <string>("bg"); //with source var fullbg = json_rep.Value <string>("fullbg"); var slice = json_rep.Value <string>("slice"); challenge = json_rep.Value <string>("challenge"); req.Close(); //image downloading var fullbg_img = _load_image_from_url("https://" + static_server + "/" + fullbg); var bg_img = _load_image_from_url("https://" + static_server + "/" + bg); var slice_img = _load_image_from_url("https://" + static_server + "/" + slice); //sorting the images fullbg_img = _sort_image(fullbg_img); bg_img = _sort_image(bg_img); //find difference var target_pos = _difference(fullbg_img, bg_img); //simulating mouse track var target_x = target_pos.Left - 6; var sim_path = _load_random_path(target_x); var sim_path_enc = _encrypt(sim_path); //building request data var passtime = 0; foreach (var item in sim_path) { passtime += item[2]; } var dst_target_x = -sim_path[0][0]; foreach (var item in sim_path) { dst_target_x += item[0]; } var validate_param = new Parameters(); validate_param.Add("gt", gt); validate_param.Add("challenge", challenge); validate_param.Add("userresponse", _get_user_response(dst_target_x, challenge)); validate_param.Add("passtime", passtime); var imgload = _rnd.Next(0, 200) + 50; Thread.Sleep(passtime); validate_param.Add("imgload", imgload); validate_param.Add("a", sim_path_enc); validate_param.Add("callback", "cb"); var ajax_url = _ajax_url; req.HttpGet(ajax_url, urlParam: validate_param, headerParam: ref_param); rep = req.ReadResponseString(); json_rep = JsonConvert.DeserializeObject(rep.Substring(3, rep.Length - 4)) as JObject; Debug.Print(json_rep.Value <string>("message")); int success = json_rep.Value <int>("success"); if (success == 1) { _validate = json_rep.Value <string>("validate"); _challenge = challenge; //writing data //var str_json = JsonConvert.SerializeObject(sim_path); //var json = new JObject(); //json.Add("length", target_x); //json.Add("data", str_json); //var fs = new StreamWriter("apis/traineddata.txt", true); //fs.WriteLine(JsonConvert.SerializeObject(json)); //fs.Close(); } req.Close(); } catch (Exception) { } return(_validate); }
/// <summary> /// 将网盘的文件异步转换成秒传数据文件(将产生一个原文件名.symbollink的文件) /// </summary> /// <param name="path">原文件路径</param> /// <param name="callback">回调函数</param> /// <param name="dst_path">保存的文件名</param> /// <param name="state">附加参数</param> public void ConvertToSymbolLinkAsync(string path, ObjectMetaCallback callback = null, string dst_path = null, object state = null) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } ThreadPool.QueueUserWorkItem(delegate { if (_enable_function_trace) { _trace.TraceInfo("BaiduPCS.ConvertToSymbolLinkAsync called: string path=" + path + "ObjectMetaCallback callback=" + callback?.ToString() + ", string dst_path=" + dst_path); } var url = GetLocateDownloadLink(path); if (url.Length == 0) { _trace.TraceWarning("Locate url length is zero"); callback?.Invoke(false, new ObjectMetadata(), state); return; } var ns = new NetStream(); ns.RetryTimes = 3; ns.CookieKey = _auth.CookieIdentifier; try { var buffer = new byte[BUFFER_SIZE]; var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); int rbytes, total = 0; ns.HttpGet(url[0]); var content_length = ns.HTTP_Response.ContentLength; if (content_length < VALIDATE_SIZE) { _trace.TraceWarning("Content_length is too small, exited"); callback?.Invoke(false, new ObjectMetadata(), state); return; } var stream = ns.ResponseStream; do { rbytes = stream.Read(buffer, 0, BUFFER_SIZE); rbytes = (int)Math.Min(VALIDATE_SIZE - total, rbytes); md5.TransformBlock(buffer, 0, rbytes, buffer, 0); total += rbytes; } while (rbytes > 0 && total < VALIDATE_SIZE); md5.TransformFinalBlock(buffer, 0, 0); var slice_md5 = util.Hex(md5.Hash); //从response处获取其他参数 var content_md5 = ns.HTTP_Response.Headers["Content-MD5"]; var content_crc32 = ns.HTTP_Response.Headers["x-bs-meta-crc32"]; uint int_crc32 = uint.Parse(content_crc32); content_crc32 = int_crc32.ToString("X2").ToLower(); if (string.IsNullOrEmpty(content_crc32) || string.IsNullOrEmpty(content_md5)) { _trace.TraceWarning("Empty content_crc32 or content_md5 detected, pls report this status to developer by opening new issue"); callback?.Invoke(false, new ObjectMetadata(), state); } //尝试发送rapid upload请求 var temp_path = "/BaiduCloudSyncCache/temp-rapid-upload-request-" + Guid.NewGuid().ToString(); var rapid_upload_info = RapidUploadRaw(temp_path, (ulong)content_length, content_md5, content_crc32, slice_md5); DeletePath("/BaiduCloudSyncCache"); if (string.IsNullOrEmpty(rapid_upload_info.MD5) || rapid_upload_info.FS_ID == 0) { _trace.TraceWarning("Validate check: post rapid upload failed, operation aborted"); callback?.Invoke(false, new ObjectMetadata(), state); return; } //rapid upload通过,整合成json格式的文件上传到服务器 var json = new JObject(); json.Add("content_length", content_length); json.Add("content_md5", content_md5); json.Add("content_crc32", content_crc32); json.Add("slice_md5", slice_md5); var str_json = JsonConvert.SerializeObject(json); var bytes_json = Encoding.UTF8.GetBytes(str_json); var stream_to_write = new MemoryStream(); stream_to_write.Write(bytes_json, 0, bytes_json.Length); stream_to_write.Seek(0, SeekOrigin.Begin); if (dst_path == null) { dst_path = path + ".symbollink"; } var file_meta = UploadRaw(stream_to_write, (ulong)bytes_json.Length, dst_path); stream_to_write.Close(); callback?.Invoke(true, file_meta, state); } catch (Exception ex) { _trace.TraceError(ex); } finally { ns.Close(); } }); }
/// <summary> /// 将网盘的秒传数据文件异步转成原文件(将产生一个去掉末尾.symbollink的文件) /// </summary> /// <param name="path">原文件路径</param> /// <param name="callback">回调函数</param> /// <param name="dst_path">保存的文件名</param> /// <param name="state">附加参数</param> public void ConvertFromSymbolLinkAsync(string path, ObjectMetaCallback callback = null, string dst_path = null, object state = null) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } ThreadPool.QueueUserWorkItem(delegate { if (_enable_function_trace) { _trace.TraceInfo("BaiduPCS.ConvertFromSymbolLinkAsync called: string path=" + path + ", ObjectMetaCallback callback=" + callback?.ToString() + ", string dst_path=" + dst_path); } var url = GetLocateDownloadLink(path); if (url.Length == 0) { _trace.TraceWarning("Locate url length is zero"); callback?.Invoke(false, new ObjectMetadata(), state); return; } var ns = new NetStream(); ns.RetryTimes = 3; ns.CookieKey = _auth.CookieIdentifier; try { ns.HttpGet(url[0]); var response_json = ns.ReadResponseString(); var json = JsonConvert.DeserializeObject(response_json) as JObject; var content_length = json.Value <ulong>("content_length"); var content_md5 = json.Value <string>("content_md5"); var content_crc32 = json.Value <string>("content_crc32"); var slice_md5 = json.Value <string>("slice_md5"); if (content_length == 0 || string.IsNullOrEmpty(content_md5) || string.IsNullOrEmpty(content_crc32)) { callback?.Invoke(false, new ObjectMetadata(), state); return; } if (dst_path == null) { dst_path = path.EndsWith(".symbollink") ? path.Substring(0, path.Length - 11) : (path + "." + path.Split('.').Last()); } var data = RapidUploadRaw(dst_path, content_length, content_md5, content_crc32, slice_md5); callback?.Invoke(true, data, state); } catch (Exception ex) { _trace.TraceError(ex); callback?.Invoke(false, new ObjectMetadata(), state); } finally { ns.Close(); } }); }
private static bool _sso_auth() { try { if (!_check_sso_expired()) { return(true); //sso auth succeeded from local cache file } if (_sso_refresh_thread != null) { _sso_refresh_thread.Abort(); } var ns = new NetStream(); ns.UserAgent = ANDROID_USER_AGENT; var param = new Parameters(); param.Add("access_key", _access_token); param.Add("appkey", APPKEY); param.Add("build", "513000"); param.Add("gourl", "https://www.bilibili.com/"); param.Add("mobi_app", "android"); param.Add("platform", "android"); param.Add("ts", (long)util.ToUnixTimestamp(DateTime.Now)); param.Add("sign", CalculateSign(param)); ns.HttpGet(_URL_AUTH_SSO, urlParam: param); //var response = ns.ReadResponseString(); ns.Close(); //sso success, check cookie status; var cookies = NetStream.DefaultCookieContainer.GetCookies(new Uri("https://passport.bilibili.com/")); if (cookies.Count == 0) { //cookie check failed throw new InvalidOperationException("Could not found cookies after sso request"); } else { DateTime dede_user_expire_time = DateTime.MinValue; foreach (Cookie item in cookies) { if (item.Name == "DedeUserID") { dede_user_expire_time = item.Expires; } } if (dede_user_expire_time == DateTime.MinValue) { //dede user check failed throw new InvalidOperationException("Could not found DedeUserID cookie after sso request"); } else { //auth success, creating next cd _sso_refresh_thread = new Thread(new ThreadStart(delegate { while (dede_user_expire_time > DateTime.Now) { var ts = (dede_user_expire_time.AddSeconds(1) - DateTime.Now).TotalMilliseconds; var sleep_time = (int)Math.Min(ts, 3600000); if (sleep_time > 0) { Thread.Sleep(sleep_time); } } _sso_auth(); })); _sso_refresh_thread.IsBackground = true; _sso_refresh_thread.Name = "SSO Refresh Thread"; _sso_refresh_thread.Start(); } } } catch (ThreadAbortException) { } catch (Exception ex) { Tracer.GlobalTracer.TraceError(ex.ToString()); //error encountered while sso request if (_sso_refresh_thread != null) { //handling async mode in sso thread _sso_refresh_thread = new Thread(new ThreadStart(delegate { Thread.Sleep(15000); _sso_auth(); })); _sso_refresh_thread.IsBackground = true; _sso_refresh_thread.Name = "SSO Refresh Thread (Failed State)"; _sso_refresh_thread.Start(); } } return(!_check_sso_expired()); }
//登陆的一些参数,由抓包得来 private void _init_pcs_auth_data() { lock (_external_auth_lock) { if (!string.IsNullOrEmpty(_sign2) && (DateTime.Now - util.FromUnixTimestamp(long.Parse(_timestamp))).TotalMinutes < 10) { return; } Tracer.GlobalTracer.TraceInfo("BaiduOAuth._init_pcs_auth_data called: void"); try { var ns = new NetStream(); ns.CookieKey = _cookie_identifier; ns.RetryDelay = 1000; ns.RetryTimes = 3; ns.HttpGet(_PAN_ROOT_URL); var str = ns.ReadResponseString(); ns.Close(); //_trace.TraceInfo(str); var match = Regex.Match(str, "\"bdstoken\":\"(\\w+)\""); if (match.Success) { _bdstoken = match.Result("$1"); } match = Regex.Match(str, "\"sign1\":\"(\\w+)\""); if (match.Success) { _sign1 = match.Result("$1"); } match = Regex.Match(str, "\"sign3\":\"(\\w+)\""); if (match.Success) { _sign3 = match.Result("$1"); } match = Regex.Match(str, "\"timestamp\":(\\d+)"); if (match.Success) { _timestamp = match.Result("$1"); } //calculate for sign2 var j = Encoding.UTF8.GetBytes(_sign3); var r = Encoding.UTF8.GetBytes(_sign1); byte[] a = new byte[256], p = new byte[256]; var o = new byte[r.Length]; int v = j.Length; for (int q = 0; q < 256; q++) { a[q] = j[q % v]; p[q] = (byte)q; } int u = 0; for (int q = 0; q < 256; q++) { u = (u + p[q] + a[q]) % 256; byte t = p[q]; p[q] = p[u]; p[u] = t; } int i = 0; u = 0; for (int q = 0; q < r.Length; q++) { i = (i + 1) % 256; u = (u + p[i]) % 256; byte t = p[i]; p[i] = p[u]; p[u] = t; byte k = p[(p[i] + p[u]) % 256]; o[q] = (byte)(r[q] ^ k); } _sign2 = Convert.ToBase64String(o); Tracer.GlobalTracer.TraceInfo("Initialization complete.\r\nbdstoken=" + _bdstoken + "\r\nsign1=" + _sign1 + "\r\nsign2=" + _sign2 + "\r\nsign3=" + _sign3 + "\r\ntimestamp=" + _timestamp); //test TestFunc(); //next update thread if (__next_update_thread != null) { try { var thd = __next_update_thread; __next_update_thread = null; ThreadPool.QueueUserWorkItem(delegate { thd.Abort(); }); } catch { } } __next_update_thread = new Thread(() => { var ts = TimeSpan.FromMinutes(10); Thread.Sleep(ts); __next_update_thread = null; _init_pcs_auth_data(); }); __next_update_thread.IsBackground = true; __next_update_thread.Name = "网盘登陆数据刷新线程"; __next_update_thread.Start(); } catch (ThreadAbortException) { } catch (Exception ex) { Tracer.GlobalTracer.TraceError(ex.ToString()); //next update thread (exception raised mode) if (__next_update_thread != null) { try { var thd = __next_update_thread; __next_update_thread = null; ThreadPool.QueueUserWorkItem(delegate { thd.Abort(); }); } catch { } } __next_update_thread = new Thread(() => { var ts = TimeSpan.FromSeconds(15); Thread.Sleep(ts); _init_pcs_auth_data(); __next_update_thread = null; }); __next_update_thread.IsBackground = true; __next_update_thread.Name = "网盘登陆数据刷新线程"; __next_update_thread.Start(); __next_update_thread.Join(); } } }