清风博客 https://www.skyfinder.cc 关注IT世界,记录平凡生活 Fri, 12 Nov 2021 04:52:21 +0000 zh-CN hourly 1 https://wordpress.org/?v=5.8.2 Visual Studio(VS) 2022 密钥/激活码 https://www.skyfinder.cc/2021/11/12/visual-studio-2022-key/ https://www.skyfinder.cc/2021/11/12/visual-studio-2022-key/#respond Fri, 12 Nov 2021 04:52:21 +0000 https://www.skyfinder.cc/?p=3684

简介

Visual Studio 2022简称VS2022,包含了专业版、企业版以及社区版等版本,这是由微软推出的新一代集成开发环境,软件提供了丰富的工具集,可以带来更快的开发速度,新版本还拥有更可靠的代码开发速度。

下载

Visual Studio 2022Visual Studio 2022 For Mac

密钥/激活码

专业版/Professional

Visual Studio 2022 Professional

TD244-P4NB7-YQ6XK-Y8MMM-YWV2J

企业版/ Enterprise

Visual Studio 2022 Enterprise

VHF9H-NXBBB-638P6-6JHCY-88JWH

转载请注明:清风博客 » Visual Studio(VS) 2022 密钥/激活码

]]>
https://www.skyfinder.cc/2021/11/12/visual-studio-2022-key/feed/ 0
有些梦 https://www.skyfinder.cc/2021/11/07/%e6%9c%89%e4%ba%9b%e6%a2%a6/ https://www.skyfinder.cc/2021/11/07/%e6%9c%89%e4%ba%9b%e6%a2%a6/#respond Sun, 07 Nov 2021 14:02:58 +0000 https://www.skyfinder.cc/?p=3682 有些梦,是一种回忆,亦是一种折磨!有些梦,是一种救赎,亦是一种惭悔!有时想而又想,有时不想再想!万般滋味,衷肠难诉!

转载请注明:清风博客 » 有些梦

]]>
https://www.skyfinder.cc/2021/11/07/%e6%9c%89%e4%ba%9b%e6%a2%a6/feed/ 0
微信账单详情页金额字体 https://www.skyfinder.cc/2021/10/12/%e5%be%ae%e4%bf%a1%e8%b4%a6%e5%8d%95%e8%af%a6%e6%83%85%e9%a1%b5%e9%87%91%e9%a2%9d%e5%ad%97%e4%bd%93/ https://www.skyfinder.cc/2021/10/12/%e5%be%ae%e4%bf%a1%e8%b4%a6%e5%8d%95%e8%af%a6%e6%83%85%e9%a1%b5%e9%87%91%e9%a2%9d%e5%ad%97%e4%bd%93/#respond Mon, 11 Oct 2021 16:38:17 +0000 https://www.skyfinder.cc/?p=3675 背景

一个朋友让我给他使用PS处理一个图片,将图中的支付金额换一下。试了好多字体,但是差距依然很大。最后,通过强大的互联网搜索引擎找到疑似相关字体文件。所以就下载尝试一下,经过测试效果还是不错。以下进行一个保存,以便以后使用!

下载

字体

转载请注明:清风博客 » 微信账单详情页金额字体

]]>
https://www.skyfinder.cc/2021/10/12/%e5%be%ae%e4%bf%a1%e8%b4%a6%e5%8d%95%e8%af%a6%e6%83%85%e9%a1%b5%e9%87%91%e9%a2%9d%e5%ad%97%e4%bd%93/feed/ 0
MySQL存储过程中使用游标 https://www.skyfinder.cc/2021/08/28/mysql-cursor/ https://www.skyfinder.cc/2021/08/28/mysql-cursor/#respond Sat, 28 Aug 2021 07:14:01 +0000 https://www.skyfinder.cc/?p=3664

游标

游标的设计是一种数据缓冲区的思想,用来存放SQL语句执行的结果。游标是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。

游标的特性

游标具有以下三个特性:

  • 不敏感(Asensitive)
    数据库可以选择不复制结果集
  • 只读(Read only)
  • 不滚动(Nonscrollable)
    游标只能向一个方向前进,并且不可以跳过任何一行数据

游标的优点

游标是针对行操作的,对从数据库中SELECT查询得到的结果集的每一行可以进行分开的独立的相同或不同的操作,是一种分离的思想。游标是面向集合与面向行的设计思想之间的一种桥梁。

游标的缺点

游标的主要缺点是性能不高。游标的开销与游标中进行的操作相关,如果在游标中进行复杂的操作,开销会非常高。

游标的适用场景

MySQL数据库中,可以在存储过程、函数、触发器、事件中使用游标。

使用步骤

  1. 定义游标:Declare 游标名称 CURSOR for table;(table也可以是select出来的结果集)
  2. 打开游标:Open 游标名称;
  3. 从结果集获取数据到变量:fetch 游标名称 into field1,field2;
  4. 执行语句:执行需要处理数据的语句
  5. 关闭游标:Close 游标名称;

示例



DELIMITER //
CREATE PROCEDURE  Proc_ProcessClassInfo(in classUid varchar(36))
BEGIN
  /* 定义变量*/
   DECLARE courseUid VARCHAR(36);

   # 声明游标结束变量
   DECLARE done INT DEFAULT 0;
  /* 声明游标*/
	DECLARE cur_list CURSOR FOR SELECT CourseUid  FROM class_course WHERE ClassUid=classUid;
	/*游标中的内容执行完后将done设置为1 */
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
	SET courseUid='';
	/* 打开游标 */
  OPEN cur_list;
	/* 执行循环 */
  read_loop : LOOP
	      /* 取游标中的值*/
        FETCH cur_list INTO courseUid;
				/* 判断是否结束循环,一定要放到FETCH之后,因为在fetch不到的时候才会设置done为1
         如果放到fetch之前,先判断done,这个时候done的值还是之前的循环的值,因此就会导致循环一次*/
        IF done THEN
            LEAVE read_loop;
        END IF;
				/*指定课件学习进度100%的内容*/
				CALL Proc_ProcessCourseComplete(courseUid);
				
	END LOOP read_loop;
  /* 释放游标 */
  CLOSE cur_list;
END 
//
DELIMITER ;

变量声明Declare需要注意的地方:

  • Declare声明本地变量必须放在最前列
  • Declare一般是先声明本地变量,再是游标,然后是条件和handler
  • Declare声明的本地变量名称与声明的游标名称不能相同

转载请注明:清风博客 » MySQL存储过程中使用游标

]]>
https://www.skyfinder.cc/2021/08/28/mysql-cursor/feed/ 0
深圳野生动物园 https://www.skyfinder.cc/2021/08/15/%e6%b7%b1%e5%9c%b3%e9%87%8e%e7%94%9f%e5%8a%a8%e7%89%a9%e5%9b%ad/ https://www.skyfinder.cc/2021/08/15/%e6%b7%b1%e5%9c%b3%e9%87%8e%e7%94%9f%e5%8a%a8%e7%89%a9%e5%9b%ad/#respond Sun, 15 Aug 2021 08:33:59 +0000 https://www.skyfinder.cc/?p=3629 背景

闲来无事,突然想去动物园看看。不过,深圳动物园好像只有深圳野生动物园这一家。在深圳去动物园好像也只能这一家,所以就去了这一家。没有去之前是对这家动物园抱很大期望的,去之后有失望还是很大的。

深圳野生动物园,位于广东省深圳市南山区西丽湖东侧, 占地面积60多万平方米,于1993年9月28日正式开业,是一家放养式的野生动物园。 是中国第一座集动物、森林、植物、科普等多种特色和观赏功能为一体的具有亚热带新型园林生态环境系统的风景区。

深圳野生动物园的设计、建设跳出了中国国内城市普遍采用的笼养模式,各种动物可以在开阔地带自由活动,使它们回到原来的生态环境。整个园区划分为三个区域,即食草动物区、猛兽谷、表演区。表演区内有动物瞭望塔、动物表演场、水族馆、猴山、杂食动物馆、美洲鬣晰馆、猿猴村、中型猛兽馆、熊猫馆等。

水豚

水豚(学名:Hydrochoerus hydrochaeris):是一种半水栖的食草动物,也是世界上最大的啮齿动物。躯体巨大,体长1-1.3米,肩高0.5米左右,体重27-50千克,体粗笨,头大,颈短,尾短,耳小而圆,眼的位置较接近顶部,鼻吻部异常膨大,末端粗钝,雄性成体的鼻吻部有一高起的裸露部位,内有肥大的脂肪腺体,上唇肥大,中裂为两瓣。前肢4趾,后肢3趾,呈放射状排列,趾间具半蹼,适于划水,趾端具近似蹄状的爪,雌兽有4对乳头。

浣熊

北美浣熊(学名:Procyon lotor)是浣熊科、浣熊属动物。为中等体型食肉目动物,成年体长40-65厘米,尾长20-40厘米,体重4-10千克,雄性稍大于雌性。毛致密,全身毛色为灰棕色混杂,还可见到白化品种。面部有黑色眼斑,形象滑稽,绰号“蒙面大盗”;尾部有多条黑白相间的环纹,大约有5到7个环。爪子不能收缩,不锋利。手的灵活性极好,能抓住飞行的虫子。

猫鼬

狐獴(学名:Suricata suricatta),头尾长42-60厘米,是一种小型的哺乳动物。躯干修长笔直,四肢匀称,后足仅具4趾,趾间有蹼;尾长而圆,约为体长的2/3,上披小鳞片及稀疏的毛。背部毛色黑褐,杂以黄色毛尖,绒毛为深咖啡色;尾两色,上面棕黑色,尾基部和下部为淡黄色。

熊猫

大熊猫(学名:Ailuropoda melanoleuca):属于食肉目熊科大熊猫亚科大熊猫属唯一的哺乳动物。仅有二个亚种。雄性个体稍大于雌性。体型肥硕似熊、丰腴富态,头圆尾短,头躯长1.2-1.8米,尾长10-12厘米。体重80-120千克,最重可达180千克,体色为黑白两色,脸颊圆,有很大的黑眼圈,标志性的内八字的行走方式,也有解剖刀般锋利的爪子。大熊猫皮肤厚,最厚处可达10毫米。黑白相间的外表,有利于隐蔽在密林的树上和积雪的地面而不易被天敌发现。

鳄鱼

鳄鱼为肉食性卵生脊椎类爬行动物,是两亿多年前与恐龙同时代的最古老爬行动物,也是迄今生存着的最原始动物之一。 鳄鱼因强盛的生命力而生存和繁衍,成为地球上最古老的生物“活化石”之一。鳄鱼属于濒危野生保护动物,被国际上列为 I 类保护的濒危野生动植物。

鹦鹉

鹦鹉是鹦形目(学名:Psittaciformes)众多羽毛艳丽、爱叫的鸟。典型的攀禽,对趾型足,两趾向前两趾向后,适合抓握,鸟喙强劲有力,可以食用硬壳果。羽色鲜艳,它们以其美丽的羽毛,善学人语技能的特点,更为人们所欣赏和钟爱。鹦鹉中体形最大的当属紫蓝金刚鹦鹉,体长可达100厘米,最小的是蓝冠短尾鹦鹉 ,体长仅有12厘米。

是鹮亚科(拉丁学名:Threskiornithinae)鸟类的统称,与鹭有亲缘关系的涉禽(ibis),分布于东西两半球的温暖地带。以水生动物及两栖动物为食,特征是有一个细长而向下弯的喙。中国常见的有白鹮和少见的有朱鹮

老虎

(学名:Panthera tigris ;英文名:Tiger):是哺乳纲的大型猫科动物;毛色浅黄或棕黄色,满身黑色横纹;头圆、耳短,耳背面黑色,中央有一白斑甚显著;四肢健壮有力;尾粗长,具黑色环纹,尾端黑色。

(Canis lupus L),食肉目犬科犬属,又名野狼、豺狼、灰狼。为国家二级保护野生动物。

(英文名称:Bear):是食肉目熊科动物的通称,熊平时还算温和,但是受到威胁或遇到危险时,容易暴怒,打斗起来非常凶猛。分布在北半球。在南半球,除了南美洲北部外,其他地方没有它的踪迹。熊科是个大家族,可分为4属:懒熊属 、眼镜熊属、马来熊属、熊属,8种。

豹子

(学名:Panthera pardus):是哺乳纲、猫科、豹属的大型肉食性动物,体长100-150厘米,体重50-100千克。体形似虎,但明显较小;躯体均匀,四肢中长,趾行性。视、听、嗅觉均很发达。头小尾长,四肢短健,前足5趾,后足4趾,爪灰白色,能伸缩。

水母

水母(英文名称:Jelly Fish):是水生环境中重要的浮游生物,包括刺丝胞动物、钵水母纲、十字水母纲、立方水母纲动物。水母是一种非常漂亮的水生动物。它的身体外形就像一把透明伞,伞状体的直径有大有小,大水母的伞状体直径可达2米。伞状体边缘长有一些须状的触手,有的触手可长达20-30米。

总结

设备陈旧,某些区域臭气熏天。动物无精打采。禽类动物掉毛一地,特别是孔雀,那掉毛的孔雀真的惨不忍睹。还有很多很多,不想再讲了!

转载请注明:清风博客 » 深圳野生动物园

]]>
https://www.skyfinder.cc/2021/08/15/%e6%b7%b1%e5%9c%b3%e9%87%8e%e7%94%9f%e5%8a%a8%e7%89%a9%e5%9b%ad/feed/ 0
Mysql脚本实现行转列 https://www.skyfinder.cc/2021/08/09/mysql-row-to-column/ https://www.skyfinder.cc/2021/08/09/mysql-row-to-column/#respond Mon, 09 Aug 2021 08:09:43 +0000 https://www.skyfinder.cc/?p=3612 背景

某项目数据统计,为了更加直观显示一些数据,刚好有这个行转列的一个需求。行转列的需求其实在平常业务中也是比较常见的,在数据统计中使用的比较频繁。行转列以前也遇到过,之前数据库使用的是Microsoft SQL Server。目前使用的是MySQL数据库,这里也做一下简单的记录。

实现

结构与数据准备

为了更好的理解行转列,这里准备一张结构简单都表以及数据。


DROP TABLE IF EXISTS `project_completion_rate`;

CREATE TABLE `project_completion_rate` (
  `id` int(8) NOT NULL,
  `project_user` varchar(20) DEFAULT NULL,
  `project_content` varchar(20) DEFAULT NULL,
  `project_rate` int(8) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


insert  into `project_completion_rate`(`id`,`project_user`,`project_content`,`project_rate`) values 
(1,'张三','机器人设计',80),
(2,'张三','图像识别',70),
(3,'张三','虚拟化技术',90),
(4,'张三','CPU设计',60),
(5,'李四','机器人设计',95),
(6,'李四','图像识别',96),
(7,'李四','虚拟化技术',97),
(8,'李四','CPU设计',99),
(9,'王五','机器人设计',100),
(10,'王五','虚拟化技术',100);

原始数据示例展示

固定行转列

当需要行转列的项比较少且显示项数目无频繁变动的时候,可以使用以下方式实现行转列的需求。如果行转列的项变动频繁或者项比较多,此种方式实现行转列就不适合。



SELECT project_user AS '项目人员'
	    ,Max(CASE  WHEN p.project_content='CPU设计' THEN p.project_rate ELSE 0 END) AS  'CPU设计'
	    ,Max(CASE  WHEN p.project_content='图像识别' THEN p.project_rate ELSE 0 END) AS  '图像识别'
	    ,Max(CASE  WHEN p.project_content='机器人设计' THEN p.project_rate ELSE 0 END) AS  '机器人设计'
         ,Max(CASE  WHEN p.project_content='虚拟化技术' THEN p.project_rate ELSE 0 END) AS  '虚拟化技术'
FROM project_completion_rate p GROUP BY p.project_user;

动态行转列

动态行转列的实现方式,是为了解决行转列中的项变动频繁或者项比较多的时候而出现的。不固定的项的行转列就可以使用以下方式尝试完成。


-- 动态行转列脚本实现
SET @sql = NULL;
SELECT
 GROUP_CONCAT(DISTINCT
  CONCAT(
   'Max(IF(p.project_content = ''',
   p.project_content,
   ''', p.project_rate, 0)) AS ''',
   p.project_content, ''''
  )
 ) INTO @sql
FROM project_completion_rate p;
 
SET @sql = CONCAT('Select project_user AS ''项目人员'',', @sql, 
            ' From project_completion_rate p Group by p.project_user' );
						
PREPARE stmt FROM @sql;  -- 动态生成脚本
EXECUTE stmt;            -- 动态执行脚本
DEALLOCATE PREPARE stmt; -- 释放

最终结果展示

结语

无论是SQL Server,还是MySQL,其实现行转列的方式也是比较多的。其中Mysql可以实现的方式都包括但不仅限于以上内容。

转载请注明:清风博客 » Mysql脚本实现行转列

]]>
https://www.skyfinder.cc/2021/08/09/mysql-row-to-column/feed/ 0
抹零开始变得不要脸 https://www.skyfinder.cc/2021/08/08/%e6%8a%b9%e9%9b%b6%e5%bc%80%e5%a7%8b%e5%8f%98%e5%be%97%e4%b8%8d%e8%a6%81%e8%84%b8/ https://www.skyfinder.cc/2021/08/08/%e6%8a%b9%e9%9b%b6%e5%bc%80%e5%a7%8b%e5%8f%98%e5%be%97%e4%b8%8d%e8%a6%81%e8%84%b8/#respond Sun, 08 Aug 2021 03:50:51 +0000 https://www.skyfinder.cc/?p=3604 背景

周六上午去商场转了一圈,买了点东西吃。付款完成后就等餐了,闲着无事就看了下小票。突然发现一个很有意思的事情,小票上显示的抹零竟然和我的认知产生冲突。抹零,应该是免付零头,这是我知道抹零这词以来的一贯认知,而这张小票也让我对抹零有一个重新的认识。这商家的抹零是让客户凑整。小票我久久没有扔掉,为的是再次查一下抹零的含义。

抹零

付款时只付整数,免付零头。

我重新查了一些相关资料,我对抹零的认识应该是没有问题。价格是商家定的,重量是商家称的,计算出多少就是多少大家也觉得没有问题,为什么抹零就坑客户了呢?为什么商家毫无忌惮的开始以客户凑整而实现抹零?也许是金额小,也许是大多数客户都未曾在意。客户兴趣小票都未曾看过!个人来讲,之前吃饭、买东西也从来没有看过小票呀!其实就算看过小票又能怎么样呢?金额这么小,争论感觉又不划算!这也许是商家肆无忌惮的原因之一吧!

查了一下,遇到这种情况的并非个例,而是普遍存在!!!!

事情虽小,却反映出许多问题,很多商家无视客户的利益,象这样的消费小票,也许消费者平时根本没想过去多看两眼,直接就无视掉了。即便看到,为了几毛钱跟商家争执也犯不上,而商家或许就是利用消费者这种心理,堂而皇之的占消费者的“便宜”。

不管怎么说,金额虽小,这种行为让我感觉不舒服。其实这种抹零的方式也不是不行,商家要公示呀,要让客户知道有这么一回事。事情摆在明面上不是挺好吗?大家各自选择!但是我依然很好奇,现在商场现金支付少之又少,太多的人使用微信、支付宝等支付方式。这种方式压根不需要抹零呀!

价格欺诈、霸王条款、收费陷阱、旅游宰客在我们生活中层出不穷!他妈的,下次老子要挣一挣!

转载请注明:清风博客 » 抹零开始变得不要脸

]]>
https://www.skyfinder.cc/2021/08/08/%e6%8a%b9%e9%9b%b6%e5%bc%80%e5%a7%8b%e5%8f%98%e5%be%97%e4%b8%8d%e8%a6%81%e8%84%b8/feed/ 0
OpenSSL SSL_read: Connection was aborted, errno 10053 异常处理 https://www.skyfinder.cc/2021/08/06/git-openssl-read-connection-was-aborted-error/ https://www.skyfinder.cc/2021/08/06/git-openssl-read-connection-was-aborted-error/#respond Fri, 06 Aug 2021 04:39:58 +0000 https://www.skyfinder.cc/?p=3595 背景

运行一个Vue项目,使用npm进行依赖安装出现以下异常信息:

异常信息

npm ERR! code 128
npm ERR! Command failed: git clone –depth=1 -q -b 2.2.0-c https://github.com/nhn/raphael.git D:\Program Files\nodejs\node_cache_cacache\tmp\git-clone-a498c440 –config core.longpaths=true
npm ERR! warning: templates not found in C:\Users\finder\AppData\Local\Temp\pacote-git-template-tmp\git-clone-c4102267
npm ERR! fatal: unable to access ‘https://github.com/nhn/raphael.git/’: OpenSSL SSL_read: Connection was aborted, errno 10053

异常处理

因为node使用了git克隆了github上的相关联的项目,所以这个异常需要对git进行相关设置。打开git命令行,依次输入以下命令回车即可:


git config --global http.postBuffer 524288000
git config --global http.sslVerify "false"

转载请注明:清风博客 » OpenSSL SSL_read: Connection was aborted, errno 10053 异常处理

]]>
https://www.skyfinder.cc/2021/08/06/git-openssl-read-connection-was-aborted-error/feed/ 0
单击游戏《抗日血战上海滩》在Windows 10系统打不开的解决办法 https://www.skyfinder.cc/2021/07/06/game-shanghai-windows-10/ https://www.skyfinder.cc/2021/07/06/game-shanghai-windows-10/#respond Mon, 05 Jul 2021 16:15:00 +0000 https://www.skyfinder.cc/?p=3572

背景

《抗日血战上海滩》是一款很早的单击游戏,很早以前在网吧看到好玩的单击游戏之一。个人笔记本也有这一款游戏,闲来无事的时候就玩一下。这款有游戏陪我经历过Windows XP、Windows VISTA 、Windows 7等版本系统,也算的上风雨同路啦!最近整理相关文件发现了《抗日血战上海滩》这款游戏,于是尝试解压出来娱乐一下。很遗憾!这款游戏打开后就无异常提示的情况下退出运行,通过设置各个兼容模式打开依然没有任何效果。通过查找部分资料,得到一些解决方案。

解决方案

  • 首先在桌面上创建此游戏的快捷方式,例如:shanghai.exe
  • 鼠标移动到刚才创建的快捷方式上,鼠标右键菜单弹出选择属性
  • 在“目标程序”加一个参数 -windows(前面有个空格)
  • 随后双击快捷方式以窗口模式进入游戏
  • 游戏设置中的将分辨率设置为1024x768
  • 随后再把电脑的显示分辨率设置为1024x768,点击“创建的快捷方式”运行即可

设置参数后,双击快捷方式以窗口的形式打开游戏,点击进入游戏设置

将分辨率由800×600设置为1024×768

打开Windows 10 显示设置,将显示分辨率设置为1024×768

设置完成后,重新打开《抗日血战上海滩》即可打开运行。

抗日血战上海滩中文版游戏背景

抗日血战上海滩游戏背景为1937年卢沟桥事变后,中日在上海进行的抗日历史上规模很大的会战——淞沪会战,是役两国投入总兵力超过200万人,战斗持续时间长达3个月。

而作为中国特种部队一员的你,就是要孤身一人去执行一系列不可能的任务,突破层层封锁杀入日军总部,最后亲手用小手枪(或刀杀)击毙敌酋——长谷川清大将。当然,为了见到这位最后的大BOSS,玩家必须要先跟大大小小的日军士兵、军曹、武士、忍者、自杀式炸弹人、生化兵、等等等等,作亲密的殊死搏斗。

总之,就是在你用手枪、冲锋枪、机枪、狙击枪、重机枪手榴弹、火箭筒干掉数万日军后,再踏着BOSS的尸体过关。为了达到好的战斗效果,游戏中所有BOT的动作全部用动作采集完成,预计仅此一项,就会创国产游戏的制作记录。

抗日血战上海滩中文版游戏秘籍

进入抗日血战上海滩游戏后按下键盘左上角的~键打开控制台,输入如下指令,回车即可。

god_on 开启无敌

god_off 关闭无敌

haveallweapon 拥有所有武器

addammo 给已有的武器加满弹药

ammonolimit 已有的武器子弹无限

      

      

      

      

转载请注明:清风博客 » 单击游戏《抗日血战上海滩》在Windows 10系统打不开的解决办法

]]>
https://www.skyfinder.cc/2021/07/06/game-shanghai-windows-10/feed/ 0
.Net访问Windows共享目录 https://www.skyfinder.cc/2021/06/29/net-access-shared-folder/ https://www.skyfinder.cc/2021/06/29/net-access-shared-folder/#respond Tue, 29 Jun 2021 01:00:00 +0000 https://www.skyfinder.cc/?p=3538 背景

无意见又翻到了曾经的一些项目,看到了关于.Net访问Windows共享目录的一些代码。曾经在内网通过共享目录作为服务器文件的存储方式,个人觉得部分的实现代码可以记录下来作为备份。所以,整理了以下代码。

代码实现

公用内容


    /// <summary>
    ///  IdentityScope 的摘要说明
    /// </summary>
    public class IdentityScope : IDisposable
    {
        // obtains user token
        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        // closes open handes returned by LogonUser

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

        extern static bool CloseHandle(IntPtr handle);


        [DllImport("Advapi32.DLL")]
        static extern bool ImpersonateLoggedOnUser(IntPtr hToken);

        [DllImport("Advapi32.DLL")]
        static extern bool RevertToSelf();

        // logon types
        const int LOGON32_LOGON_INTERACTIVE = 2;
        const int LOGON32_LOGON_NETWORK = 3;
        const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
        // logon providers
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_PROVIDER_WINNT50 = 3;
        const int LOGON32_PROVIDER_WINNT40 = 2;
        const int LOGON32_PROVIDER_WINNT35 = 1;

        private bool disposed;

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="sUsername">用户名</param>
        /// <param name="sDomain">第二个参数是域名,有域名的话写域名,没有域名写目标机器的IP·</param>
        /// <param name="sPassword">密码</param>
        public IdentityScope(string sUsername, string sDomain, string sPassword)
        {

            // initialize tokens
            IntPtr pExistingTokenHandle = new IntPtr(0);
            IntPtr pDuplicateTokenHandle = new IntPtr(0);
            try
            {

                // get handle to token
                bool bImpersonated = LogonUser(sUsername, sDomain, sPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);
                if (bImpersonated)
                {
                    if (!ImpersonateLoggedOnUser(pExistingTokenHandle))
                    {
                        int nErrorCode = Marshal.GetLastWin32Error();
                        // throw new Exception("ImpersonateLoggedOnUser error;Code=" + nErrorCode);
                        throw new Exception("文件服务器远程连接异常,请稍后再试!");
                    }

                }
                else
                {
                    int nErrorCode = Marshal.GetLastWin32Error();
                    //throw new Exception("LogonUser error;Code=" + nErrorCode);
                    throw new Exception("文件服务器远程连接异常,请稍后再试!");

                }

            }
            finally
            {
                // close handle(s)
                if (pExistingTokenHandle != IntPtr.Zero)
                {

                    CloseHandle(pExistingTokenHandle);
                }

                if (pDuplicateTokenHandle != IntPtr.Zero)
                {

                    CloseHandle(pDuplicateTokenHandle);
                }
            }

        }

        protected virtual void Dispose(bool disposing)
        {

            if (!disposed)
            {
                RevertToSelf();
                disposed = true;
            }

        }

        public void Dispose()
        {
            Dispose(true);
        }
    }

访问调用

      
using ShareAccess.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ShareAccess
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
               
                using (IdentityScope c = new IdentityScope("Administrator","192.168.0.102","1234567"))
                {
                    FileInfo fileInfo = new FileInfo("C:\\Users\\finder\\Desktop\\taskapp2.zip");
                    fileInfo.CopyTo("\\\\192.168.0.102\\Share\\" + fileInfo.Name);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{ex}");
            }
            Console.Read();
        }
    }
}

示例下载

.Net访问Windows共享目录示例

转载请注明:清风博客 » .Net访问Windows共享目录

]]>
https://www.skyfinder.cc/2021/06/29/net-access-shared-folder/feed/ 0
System.Data.OracleClient需要Oracle 客户端软件version 8.1.7或更高版本 https://www.skyfinder.cc/2021/06/23/system-data-oracle-client-error/ https://www.skyfinder.cc/2021/06/23/system-data-oracle-client-error/#respond Wed, 23 Jun 2021 10:45:48 +0000 https://www.skyfinder.cc/?p=3541 背景

因业务需求需要进行数据同步,客户又没有提供相关的接口。经过协商,客户提供相关视图直连他们数据库。

数据库:Oracle 11g

问题

使用.net访问Oracle数据出现以下错误:

System.Data.OracleClient 需要Oracle 客户端软件 version 8.1.7 或 更高版本

解决

  • 找到Oracle安装文件夹找到oci.dlloraociei11.dll两个dll文件
  • 将以上两个文件放到system32目录下或者程序的bin目录下

下载

Oracle_11g提取码:hrbc
以上下载地址中的文件就是本文中提到的两个DLL文件

转载请注明:清风博客 » System.Data.OracleClient需要Oracle 客户端软件version 8.1.7或更高版本

]]>
https://www.skyfinder.cc/2021/06/23/system-data-oracle-client-error/feed/ 0
.NET读取Pem证书私钥解密 https://www.skyfinder.cc/2021/06/14/dot-net-rsa-pem/ https://www.skyfinder.cc/2021/06/14/dot-net-rsa-pem/#respond Mon, 14 Jun 2021 03:57:53 +0000 https://www.skyfinder.cc/?p=3532 背景

因业务需求的需要,要与第三方进行相关的数据对接,按照第三方规定需要对其数据通过私钥进行RSA解密。第三方提供了相关的Pem证书文件,但是这种格式的证书文件.NET并不能直接使用,需要进行相关的转换。

pem在转XML时需要依赖一个第三方库BouncyCastle

下载

BouncyCastle
如果通过官网下载比较慢,可以使用本博以上链接下载。

代码实现


using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

namespace CommonTool.Share.Util
{
    /// <summary>
    /// 非对称RSA解密
    /// </summary>
    public class PemRsaEncrypt
    {
       /// <summary>
       /// RSA解密
       /// </summary>
       /// <param name="filePath">pem私钥证书路径</param>
       /// <param name="content">加密的文本</param>
       /// <returns>解密后的明文</returns>
       public static string Decrypt(string filePath,string content)
       {
           using (var fileStream = File.OpenText(filePath))
           {
               string privateJavaKey = fileStream.ReadToEnd().Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "");
               RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateJavaKey));
               string xmlPrivateKey = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
                            Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
                            Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
                            Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
                            Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
                            Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
                            Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
                            Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
                            Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));

               RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
               byte[] cipherbytes;
               rsa.FromXmlString(xmlPrivateKey);
               cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);
               return Encoding.UTF8.GetString(cipherbytes);
           }
       }
    }
}

转载请注明:清风博客 » .NET读取Pem证书私钥解密

]]>
https://www.skyfinder.cc/2021/06/14/dot-net-rsa-pem/feed/ 0
新冠疫苗接种 https://www.skyfinder.cc/2021/05/29/covid-19-vaccination/ https://www.skyfinder.cc/2021/05/29/covid-19-vaccination/#respond Sat, 29 May 2021 06:18:37 +0000 https://www.skyfinder.cc/?p=3509

新冠疫苗国家很早就开始打疫苗,根据情况划分了建议接种的年龄阶段,以及确定了不宜接种的各种情况。很早之前并没有参与任何接种,原因也很简单,身体不太舒服一直在吃要,所以就暂缓了。

第一剂新冠疫苗接种

前天(2021-05-27)决定去接种新冠疫苗,根据通知当天下午16:4020:00期间进行接种。下午请假2个小时去,我想这样已经够提前了吧。但是,这种想法还是过于草率了,赶到社康的时候已经有了好多人在排队,这样的队伍长到无法想象。维持秩序的警察以及义工都不建议后来者再进行排队等待,我看到这么多人也就放弃了当天接种想法。

突然,群里接到最新疫苗接种信息,可以领取小票凭据,到第二天在指定时间排队接种。于是,在昨天(2021-05-28)早上到社康排队接种,本以为自己去的已经很早了,万万没有想到队伍已经有50人左右。在等待1个小时左右终于完成了新冠疫苗(北京生物)的接种,留观37分钟并没有发现任何异常。临走的时候听到社康工作人员说的一句话:”你们出去以后,再出现任何问题都和我们没有关系啦!”。听到社康工作人员说这句话后,我的心突然颤抖一下。原以为半小时内没有不良反应,以后就不回有任何的副作用,我觉得自己可能又要想多了。

不良反应

事情的发展往往不会朝着自己意愿方向发展,接种新冠疫苗后的不良反应下午开始出现了。接种部位疼痛加重,头部头痛开始,头痛晚上达到高峰,发困、乏力。无奈晚上就提前躺下休息一下,就在这难受中就睡着了。今天(2021-05-29)早上醒来,头痛的症状消失。但接种部位周围起了红疹,不过这种症状并不是全身性的,先观察再说吧。

这个疫苗接种真的是有个体的差异,有些同事朋友接种没有任何症状反应。

疫苗接种部位周围红疹在7天内慢慢消退!

转载请注明:清风博客 » 新冠疫苗接种

]]>
https://www.skyfinder.cc/2021/05/29/covid-19-vaccination/feed/ 0
Microsoft SQL Server跨服务器查询 https://www.skyfinder.cc/2021/05/23/microsoft-sql-server-remote-query/ https://www.skyfinder.cc/2021/05/23/microsoft-sql-server-remote-query/#respond Sun, 23 May 2021 01:00:00 +0000 https://www.skyfinder.cc/?p=3501 创建链接服务器

sp_addlinkedserver

创建链接服务器。 链接服务器让用户可以对 OLE DB 数据源进行分布式异类查询。 使用 sp_addlinkedserver 创建链接服务器后,可对该服务器运行分布式查询。 如果链接服务器定义为 SQL Server实例,则可执行远程存储过程。

语法


sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ]   
     [ , [ @provider= ] 'provider_name' ]  
     [ , [ @datasrc= ] 'data_source' ]   
     [ , [ @location= ] 'location' ]   
     [ , [ @provstr= ] 'provider_string' ]   
     [ , [ @catalog= ] 'catalog' ]

参数

[ @server =] ‘ 服务器 ‘
要创建的链接服务器的名称。 server 的数据类型为 sysname,无默认值。

[ @srvproduct =] ‘ product_name ‘
要添加为链接服务器的 OLE DB 数据源的产品名称。 product_name 为 nvarchar ( 128 ),默认值为 NULL。 如果不需要指定 SQL Server、 provider_name、 data_source、 位置、 provider_string 和 目录 。

[ @provider =] ‘ provider_name ‘
与此数据源对应的 OLE DB 访问接口的唯一编程标识符 (PROGID)。 对于当前计算机上安装的指定 OLE DB 提供程序, provider_name 必须是唯一的。 provider_name 为 nvarchar (128),默认值为 NULL;但是,如果省略 provider_name ,则使用 sqlncli.msi。

使用 SQLNCLI.MSI 将重定向 SQL Server 到 SQL Server Native Client OLE DB 提供程序的最新版本。 OLE DB 提供程序应以指定的 PROGID 在注册表中注册。

以前的 Microsoft OLE DB Provider for SQL Server (SQLOLEDB) 和 SQL Server Native Client OLEDB 提供程序 (SQLNCLI) 仍然不推荐使用,不建议在新的开发工作中使用它们。 相反,请使用新的 Microsoft OLE DB Driver for SQL Server (MSOLEDBSQL),其将使用最新的服务器功能进行更新。

[ @datasrc =] ‘ data_source ‘
由 OLE DB 访问接口解释的数据源的名称。 data_source (4000 ) 为 nvarchar。 data_source 作为 DBPROP_INIT_DATASOURCE 属性传递以初始化 OLE DB 提供程序。

[ @location =] ‘ 位置 ‘
由 OLE DB 访问接口解释的数据库的位置。 location (4000 ) 为 NVARCHAR,默认值为 NULL。 location 作为 DBPROP_INIT_LOCATION 属性传递以初始化 OLE DB 提供程序。

[ @provstr =] ‘ provider_string ‘
OLE DB 访问接口特定的连接字符串,它可标识唯一的数据源。 provider_string 为 nvarchar ( 4000 ),默认值为 NULL。 provstr 传递给 IDataInitialize,或设置为 DBPROP_INIT_PROVIDERSTRING 属性以初始化 OLE DB 提供程序。

当针对 SQL Server Native Client OLE DB 提供程序创建链接服务器时,可以通过使用 server 关键字 as server =servername \ instancename 指定的特定实例来指定实例 SQL Server 。 servername 是运行的计算机的名称 SQL Server , instancename 是 SQL Server 用户将连接到的特定实例的名称。

若要访问镜像数据库,则连接字符串必须包含数据库名称。 该名称是数据访问接口启用故障转移尝试所必需的。 可以在 @ provstr 或 @ catalog 参数中指定数据库。 此外,连接字符串还可以提供故障转移伙伴名称。

返回代码值

0(成功)或 1(失败)

sp_addlinkedsrvlogin

创建或更新 SQL Server 本地实例上的登录名与远程服务器中安全帐户之间的映射。

语法


sp_addlinkedsrvlogin [ @rmtsrvname = ] 'rmtsrvname'   
     [ , [ @useself = ] { 'TRUE' | 'FALSE' | NULL } ]   
     [ , [ @locallogin = ] 'locallogin' ]   
     [ , [ @rmtuser = ] 'rmtuser' ]   
     [ , [ @rmtpassword = ] 'rmtpassword' ]

参数

[ @rmtsrvname = ] 'rmtsrvname'
应用登录映射的链接服务器的名称。 rmtsrvname 的值为 sysname,无默认值。

[ @useself = ] { 'TRUE' | 'FALSE' | NULL }'
确定是通过模拟本地登录名连接到 rmtsrvname ,还是显式提交登录名和密码。 数据类型为 varchar ( 8 ),默认值为 TRUE。

如果值为 TRUE,则指定登录名使用其自己的凭据连接到 rmtsrvname,并忽略 rmtuser 和 rmtpassword 参数。 FALSE 指定 rmtuser 和 rmtpassword 参数用于连接到指定 locallogin 的 rmtsrvname 。 如果将 rmtuser 和 RMTPASSWORD 设置为 NULL,则不会使用登录名或密码连接到链接服务器。

[ @locallogin = ] 'locallogin'
本地服务器上的登录。 locallogin 的值为 sysname,默认值为 NULL。 NULL 指定此条目适用于连接到 rmtsrvname 的所有本地登录名。 如果不为 NULL,则 locallogin 可以为 SQL Server 登录名或 Windows 登录名。 对于 Windows 登录来说,必须以直接的方式或通过已被授权访问的 Windows 组成员身份授予其访问 SQL Server 的权限。

[ @rmtuser = ] 'rmtuser'
当为 FALSE 时,用于连接到 rmtsrvname 的远程登录名 @useself 。 当远程服务器是 SQL Server 不使用 Windows 身份验证的实例时, rmtuser 是一个 SQL Server 登录名。 rmtuser 的值为 sysname,默认值为 NULL。

[ @rmtpassword = ] 'rmtpassword'
与 rmtuser 关联的密码。 rmtpassword 的值为 sysname,默认值为 NULL。

返回代码值

0(成功)或 1(失败)

sp_droplinkedsrvlogin 

删除运行 SQL Server 的本地服务器上的登录与链接服务器上的登录之间的现有映射。

语法


sp_droplinkedsrvlogin [ @rmtsrvname= ] 'rmtsrvname' ,   
   [ @locallogin= ] 'locallogin'

参数

[ @rmtsrvname = ] 'rmtsrvname' 应用登录映射的链接服务器的名称 SQL Server 。 rmtsrvname 的值为 sysname,无默认值。 rmtsrvname 必须已存在。

[ @locallogin = ] 'locallogin'SQL Server本地服务器上的登录名,它具有到链接服务器的映射 rmtsrvname。 locallogin 的值为 sysname,无默认值。 必须已经存在 locallogin 到 rmtsrvname 的映射。 如果为 NULL,则会删除 sp_addlinkedserver 创建的默认映射,该映射将本地服务器上的所有登录名映射到链接服务器上的登录名。

返回代码值

0(成功)或 1(失败)

sp_dropserver 

从本地 SQL Server 实例中的已知远程服务器和链接服务器的列表中删除服务器。

语法


sp_dropserver [ @server = ] 'server'   
     [ , [ @droplogins = ] { 'droplogins' | NULL} ]

参数

服务器
要删除的服务器。 server 的数据类型为 sysname,无默认值。 服务器 必须存在。

droplogins
指示如果指定了 droplogins ,则还必须删除 服务器 的相关远程服务器和链接服务器登录名。 @droplogins 为 char (10),默认值为 NULL。

返回代码值

0(成功)或 1(失败)

示例

异地服务器, 数据库之间的查询

创建链接服务器


EXEC sp_addlinkedserver
@server = 'SourceHost', -- 目标服务器别名
@srvproduct = 'MSSQL',  -- 产品名称
@datasrc = '192.168.0.132\MSSQLSERVER2012' , -- 目标服务器名称
@provider = 'SQLOLEDB'

登录链接服务器


EXEC sp_addlinkedsrvlogin
@rmtsrvname = 'SourceHost' , -- 与以上 @server 同名
@useself = 'false' ,
@locallogin = NULL ,
@rmtuser = 'sa' ,
@rmtpassword = '123'

删除登录与链接服务器的映射


--删除登录与链接服务器的映射
exec sp_droplinkedsrvlogin  @rmtsrvname= 'SourceHost' ,   
    @locallogin= 'locallogin'  

删除链接服务器


--删除链接服务器 
exec sp_dropserver 'SourceHost', 'droplogins'

查询异地服务器的目标数据库


select * from SourceHost.目标数据库名称.dbo.表名

转载请注明:清风博客 » Microsoft SQL Server跨服务器查询

]]>
https://www.skyfinder.cc/2021/05/23/microsoft-sql-server-remote-query/feed/ 0
杂交水稻之父袁隆平逝世 https://www.skyfinder.cc/2021/05/22/fatherofhybridrice/ https://www.skyfinder.cc/2021/05/22/fatherofhybridrice/#respond Sat, 22 May 2021 06:21:43 +0000 https://www.skyfinder.cc/?p=3490

”杂交水稻之父“、中国工程院院士、“共和国勋章”获得者袁隆平,2021年5月22日13点07分在湖南长沙逝世,享年91岁。袁隆平是我国研究与发展杂交水稻的开创者,也是世界上第一个成功利用水稻杂种优势的科学家,被誉为“杂交水稻之父”。直到今年年初,他还坚持在海南三亚南繁基地开展科研工作。

看到关于袁隆平逝世的新闻,我的第一反应是难以置信,是不是有人在造谣。真的让人难以置信,最后确认还是真的。最初知道袁隆平这个名字,是在书本上,知道他的杂交水稻,知道他是杂交水稻之父,知道他是一个位伟大的科学家,很早我们对他的认知也仅仅如此而已。有没有后来者我不知道,我在想他的成就绝对是前无古人。想说些什么,但又不知道说些什么。唯有致敬!唯有缅怀!

袁隆平,男,1930年9月出生于北京,1953年毕业于西南农学院农学系。毕业后,一直从事农业教育及杂交水稻研究。1980-1981年赴美任国际水稻研究所技术指导。1982年任全国杂交水稻专家顾问组副组长。1991年受聘联合国粮农组织国际首席顾问。1995年被选为中国工程院院士。1971年至今任湖南农业科学院研究员,并任湖南省政协副主席、全国政协常委、国家杂交水稻工程技术研究中心主任。
  袁隆平院士是世界著名的杂交水稻专家,是我国杂交水稻研究领域的开创者和带头人,为我国粮食生产和农业科学的发展做出了杰出贡献。他的主要成就表现在杂交水稻的研究、应用与推广方面。
  七十年代初,袁隆平利用助手发现的天然雄性不育的“野败”作为杂交水稻的不育材料并发表了水稻杂种优势利用的观点,打破了世界性的自花授粉作物育种的禁区。七十年代中期,以他为首的科技攻关组完成了三系配套并培育成功杂交水稻,实现了杂交水稻的历史性突破。现我国杂交水稻的各个优良品种已占全国水稻种植面积的50%,平均增产20%。此后,他又提出“两系法亚种间杂种优势利用”的发展概念,国家“863”计划据此将两系法列为重要项目,经项目组科技人员6年的刻苦研究,已掌握两系法技术,并推广种植,现占水稻面积的10%,效果良好。
  1997年,他在国际“超级稻”的概念基础上,提出了“杂交水稻超高产育种”的技术路线,在实验田取得良好效果,亩产近800公斤,且米质类粳稻,引起国际上的高度重视。为进一步解决大面积、大幅度提高水稻产量难题奠定了基础。
  在全国农业科技工作者的共同努力下,1976年至1999年累计推广种植杂交水稻35亿多亩,增产稻谷3500亿公斤。近年来,全国杂交水稻年种植面积2.3亿亩左右,约占水稻总面积的50%,产量占稻谷总产的近60%,年增稻谷可养活6000万人口,社会和经济效益十分显著。
  袁隆平院士热爱祖国、品德高尚,他的成就和贡献,在国内外产生了强烈反响。杂交水稻的研究成果获得我国迄今为止唯一的发明特等奖。并先后荣获联合国教科文组织、粮农组织等多项国际奖励。袁隆平虽已年届70岁,仍然一如既往地活跃在科研与生产实践的第一线,从不间断地进行着研究、实验与应用。

转载请注明:清风博客 » 杂交水稻之父袁隆平逝世

]]>
https://www.skyfinder.cc/2021/05/22/fatherofhybridrice/feed/ 0
docker查看日志 https://www.skyfinder.cc/2021/05/19/docker-log-view/ https://www.skyfinder.cc/2021/05/19/docker-log-view/#respond Wed, 19 May 2021 04:56:39 +0000 https://www.skyfinder.cc/?p=3480 在工作当中有时候需要查看指定容器的日志记录,当日志比较多的时可以通过参数来进一步筛选。

命令格式


Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
      --details           显示更多的信息
  -f, --follow           跟踪实时日志
      --since string   显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟)
      --tail string      从日志末尾显示多少行日志, 默认是all
  -t, --timestamps  显示时间戳
      --until string    显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)

使用示例

查看指定容器全部日志


docker logs  容器ID或者容器名称

实时查看容器前100条日志


docker logs -f -t --tail 100 容器ID或者容器名称

查看某时间段日志


ocker logs -t --since="2021-05-18T13:23:37" --until "2021-05-19T12:23:37" 容器ID或者容器名称

查看最近10分钟的日志


docker logs --since 10m 容器ID或者容器名称

查看某时间之后的日志


docker logs -t --since="2021-05-18T13:23:37" 容器ID或者容器名称

转载请注明:清风博客 » docker查看日志

]]>
https://www.skyfinder.cc/2021/05/19/docker-log-view/feed/ 0
网站被恶意镜像的简单快速处理方法 https://www.skyfinder.cc/2021/05/02/mirror-site/ https://www.skyfinder.cc/2021/05/02/mirror-site/#respond Sun, 02 May 2021 15:08:28 +0000 https://www.skyfinder.cc/?p=3457 背景

站点网上飘,哪有不挨刀。总是遇到千奇百怪的问题,让人猝不及防。在51日的前一天,发现博客被人镜像了,这是一个非常糟心的问题,我非常肯定的是这次的镜像不怀好意。为什么我会这么说呢?因为镜像站点域名太不像话了,太长了,有没有特殊的含义,所以我认为这种镜像网站是非常有恶意的。如下图:

镜像站点域名

JavaScript简单紧急处理

这种恶意的镜像站点无法绝对的杜绝,只能尽可能的减小影响。此次处理非常简单,直接使用Javascript对当前域名进行判断,与指定域名不符就跳转回指定的域名。

版本一


var local=window.location.host;
if(local.indexOf("skyfinder.cc")==-1){
   location.href = location.href.replace(local,"skyfinder.cc");
}

版本二

为了更好的预防其简单替换域名,将我们对比的域名的各个字符ASCII码保存起来,通过转换重新组合为域名后再与当前host进行对比,不同则需要跳转原站点,反之则不需要任何的操作。


var local=window.location.host;
var myHost=[115,107,121,102,105,110,100,101,114,46,99,99];
var myurl=[];
for(var item in myHost){
   myurl.push(String.fromCharCode(myHost[item]));
}
if(local.indexOf(myurl.join(""))==-1){
   location.href = location.href.replace(local,myurl.join(""));
}

版本三

这个版本是使用以上其他版本对Javascript代码进行混淆的,希望这种方式使他们的操作增加更多的工作量。



var I1=window['\x6c\x6f\x63\x61\x74\x69\x6f\x6e']['\x68\x6f\x73\x74'];var sRPPOUO2=[115,107,121,102,105,110,100,101,114,46,99,99];var dzhW$3=[];for(var tMYXRE4 in sRPPOUO2){dzhW$3['\x70\x75\x73\x68'](window["\x53\x74\x72\x69\x6e\x67"]['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65'](sRPPOUO2[tMYXRE4]))}if(I1['\x69\x6e\x64\x65\x78\x4f\x66'](dzhW$3['\x6a\x6f\x69\x6e'](""))==-1){window['\x6c\x6f\x63\x61\x74\x69\x6f\x6e']['\x68\x72\x65\x66']['\x72\x65\x70\x6c\x61\x63\x65']();location['\x68\x72\x65\x66']=location['\x68\x72\x65\x66']['\x72\x65\x70\x6c\x61\x63\x65'](I1,dzhW$3['\x6a\x6f\x69\x6e'](""))}

效果展示

封禁IP

第一步 获取镜像站点的IP

新建一个php文件,将以下代码复制到文件中并命名为“ip.php”上传到网站根目录。


<?php
$file = "ip.txt";//保存的文件名
$ip = $_SERVER['REMOTE_ADDR'];
$handle =fopen($file,'a');
fwrite($handle,"IP Address:");
fwrite($handle,"$ip");
fwrite($handle,"\n");
fclose($handele);
?>

第二步 访问获取镜像站点地址

访问镜像站点,在镜像域名地址后面加ip.php,然后就会在自己网站根目录找到ip.txt文件了,打开复制里面的ip地址。

添加恶意镜像站点IP.htaccess

使用Deny from来将指定的IP加入黑名单,如下所示


#AIOWPS_IP_BLACKLIST_START
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from all
Deny from 112.213.97.64
Deny from 37.187.78.50
Deny from 47.90.76.5
Deny from 5.188.0.0/16
Deny from 61.160.232.95
Deny from 61.160.232.94
Deny from 125.77.16.108
</IfModule>
<IfModule mod_authz_core.c>
<RequireAll>
Require all granted
Require not ip 112.213.97.64
Require not ip 37.187.78.50
Require not ip 47.90.76.5
Require not ip 5.188.0.0/16
Require not 61.160.232.95
Require not 61.160.232.94
Require not ip 125.77.16.108
</RequireAll>
</IfModule>
#AIOWPS_IP_BLACKLIST_END

将指定IP加入黑名单后,刷新镜像站点后显示403被禁止访问。使用这种方式需要维护黑名单列表,如果有新的镜像站点就继续要添加记录。

结语

我个人十分难以理解这种行为,个人博客而已,只是记录点生活的一些琐事、工作中的一些问题处理以及学习中的一些疑问。镜像一个没有商业价值的个人博客,真的值得吗?

关于其他解决恶意镜像站点的方法,以后在寻找。目前仅使用Javascript来做最简单快速的方法。

转载请注明:清风博客 » 网站被恶意镜像的简单快速处理方法

]]>
https://www.skyfinder.cc/2021/05/02/mirror-site/feed/ 0
Linux快速回收连接TIME-WAIT的连接 https://www.skyfinder.cc/2021/04/21/linuxtime-wait-recovery/ https://www.skyfinder.cc/2021/04/21/linuxtime-wait-recovery/#respond Wed, 21 Apr 2021 03:49:28 +0000 https://www.skyfinder.cc/?p=3448 发现Centos系统中出现了很多 TIME-WAIT的空闲连接,连接资源感觉即将耗尽,并且这些TIME-WAIT释放缓慢。

配置修改


vi /etc/sysctl.conf

编辑文件,加入以下内容:


# 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
net.ipv4.tcp_syncookies = 1

# 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1

# 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_tw_recycle = 1

# 修改系統默认的TIMEOUT时间
net.ipv4.tcp_fin_timeout = 30 

执行以下指令,让新增的配置生效.


/sbin/sysctl -p

完成修改之后,使用以下命令查看TIME_WAIT连接数


netstat -ant |grep “TIME_WAIT” |wc -l

转载请注明:清风博客 » Linux快速回收连接TIME-WAIT的连接

]]>
https://www.skyfinder.cc/2021/04/21/linuxtime-wait-recovery/feed/ 0
Docker容器在Centos使用脚本查看日志与清理 https://www.skyfinder.cc/2021/04/10/dockercentoslogclear/ https://www.skyfinder.cc/2021/04/10/dockercentoslogclear/#respond Sat, 10 Apr 2021 05:04:36 +0000 https://www.skyfinder.cc/?p=3425 背景

jenkins突然无法自动构建镜像,经过确认并非是无法构建,而是磁盘空间满了。 关于手动清理Docker日志的方法,自己曾经也处理过,但是容器多起来就相当麻烦。

linux上,容器日志一般存放在/var/lib/docker/containers/container_id/下面, 以json.log结尾的文件.

查看


#!/bin/sh
echo "======== docker containers logs file size ========"
logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
do
ls -lh $log
done

清理


#!/bin/sh
echo "======== start clean docker containers logs ========"
logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
do
echo "clean logs : $log"
cat /dev/null > $log
done
echo "======== end clean docker containers logs ========"

限制Docker容器日志大小

全局设置

新建/etc/docker/daemon.json,若是存在编辑即可。添加log-dirverlog-opts参数,示例如下:


# vim /etc/docker/daemon.json
{
  "log-driver":"json-file",
  "log-opts": {"max-size":"500m", "max-file":"3"}
}

max-size设置日志文件的大小的上线,max-file一个容器有多少个日志。

设置的日志大小,只对新建的容器有效.

// 重启docker守护进程
systemctl daemon-reload
systemctl restart docker

单个容器设置

通过配置容器docker-composemax-size选项来实现。


  consul-server-bootstrap:
    container_name: consul-server-bootstrap
    image: consul:latest
    logging: 
      driver: “json-file” 
      options: 
        max-size: “5g”

重新使用docker-compose运行即可完成最后设置。

转载请注明:清风博客 » Docker容器在Centos使用脚本查看日志与清理

]]>
https://www.skyfinder.cc/2021/04/10/dockercentoslogclear/feed/ 0
删除Docker中为none的Image/镜像 https://www.skyfinder.cc/2021/04/08/dockernoneimagermove/ https://www.skyfinder.cc/2021/04/08/dockernoneimagermove/#respond Thu, 08 Apr 2021 15:26:45 +0000 https://www.skyfinder.cc/?p=3422 docker build 或是 pull 命令就会产生临时镜像。


//删除无效的临时镜像
docker rmi $(docker images -f "dangling=true" -q)

其他方法

停止容器


docker stop $(docker ps -a | grep "Exited" | awk '{print $1 }')

删除容器


docker rm $(docker ps -a | grep "Exited" | awk '{print $1 }')

删除镜像


docker rmi $(docker images | grep "none" | awk '{print $3}')

转载请注明:清风博客 » 删除Docker中为none的Image/镜像

]]>
https://www.skyfinder.cc/2021/04/08/dockernoneimagermove/feed/ 0
WordPress博客Gravatar头像无法显示问题 https://www.skyfinder.cc/2021/04/04/wordpress-gravatar/ https://www.skyfinder.cc/2021/04/04/wordpress-gravatar/#respond Sat, 03 Apr 2021 18:10:34 +0000 https://www.skyfinder.cc/?p=3412

Gravatar

Gravatar,全称Globally Recognized Avatar。翻译成中文为全球通用头像

Gravatar的概念首先是在国外的独立WordPress博客中兴起的,当你到任何一个支持Gravatar的网站留言时,这个网站都会根据你所提供的Email地址为你显示出匹配的头像。当然,这个头像,是需要你事先到Gravatar的网站注册并上传的,否则,在这个网站上,就只会显示成一个默认的头像。

注册使用

使用该服务时需要去官网中注册一个账号,并上传头像。

注意头像上传后会审核,然后管理员会按图片包含的内容划分一个等级(G 普通级、PG 辅导级、R 和 X 为限制级)。通过之后这个头像就可以使用了。在任何支持Gravatar的地方,在评论填写email地址时,请填写你申请注册头像用的这个email地址。你的头像就会出现在留言中。

网站调用

本博客使用的是WordPress,突然发现Gravatar头像已经无法显示了,成了裂图。经过证实链接被阻断了,所以无法显示。打开当前主题中functions.php文件进行编辑,新增以下代码并保存更新。


//v2ex国内gravatar头像缓存
function get_ssl_avatar($avatar){ 
	$avatar = preg_replace('/.*\/avatar\/(.*)\?s=([\d]+)&.*/','<img src="https://cdn.v2ex.com/gravatar/$1?s=$2" class="avatar avatar-$2" height="50px" width="50px">',$avatar);
	return $avatar; 
} 
add_filter('get_avatar', 'get_ssl_avatar');

如果您的WordPress网站中没用使用Gravatar头像功能,则没用任何影响.

Gravatar镜像源

本来博客中gravatar不可以使用,改为v2ex镜像一段时间后又重新不可以使用,只能继续找其他镜像来替代,以下是通过互联网收集一些支持gravatar的一些镜像.

官方的www  https://www.gravatar.com/avatar/

官方的en  https://en.gravatar.com/avatar/

官方的cn  https://cn.gravatar.com/avatar/

官方的secure  https://secure.gravatar.com/avatar/

V2EX  https://cdn.v2ex.com/gravatar/

Loli  https://gravatar.loli.net/avatar/

极客族  https://sdn.geekzu.org/avatar/

zeruns’s Blog https://gravatar.zeruns.tech/avatar/

转载请注明:清风博客 » WordPress博客Gravatar头像无法显示问题

]]>
https://www.skyfinder.cc/2021/04/04/wordpress-gravatar/feed/ 0
移除.net解决方案中TFS的绑定控制 https://www.skyfinder.cc/2021/03/26/removenetcodetfs/ https://www.skyfinder.cc/2021/03/26/removenetcodetfs/#respond Fri, 26 Mar 2021 11:23:56 +0000 https://www.skyfinder.cc/?p=3396 TFS与解决方案绑定信息清理

tfs与解决方案之间有相关信息需要清理,以下是相关的清理步骤。

删除关联文件以及文件夹

删除项目目录下所有的*.vssscc*.vspscc为后缀的文件,删除隐藏文件夹$tf

修改项目的解决方案文件

在目录中找到以*.sln为后缀名的解决方案文件,打开文件进行编辑。删除TeamFoundationVersionControl所在的整块内容并保存。

GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 2
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccTeamFoundationServer = http:///tfs/defaultcollection
SccLocalPath0 = .
SccProjectUniqueName1 = .csproj
//Scc……
EndGlobalSection

修改项目文件

在项目目录中,找到以*.csproj为后缀的项目文件,打开进行编辑。

删除<SccProjectName><SccLocalPath><SccAuxPath><SccProvider>这四个节点。

代码实现

为了方便以后使用,所以这里使用.net 5 写一个小工具来清理这些TFS绑定信息。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DisassociateSourceCodeManagementTFS
{
    public partial class DisassociateTFS : Form
    {
        
        public DisassociateTFS()
        {
            InitializeComponent();
        }
        private void btnDisassociateTFS_Click(object sender, EventArgs e)
        {
            string path = txtSourceFolder.Text;
            if (string.IsNullOrWhiteSpace(path))
            {
                MessageBox.Show("请选择需要解除TFS绑定的源码目录","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
                return;
            }
            if (!Directory.Exists(path))
            {
                return;
            }
            btnDisassociateTFS.Enabled = false;
            var vssscc = Directory.EnumerateFiles(path, "*.vssscc", SearchOption.AllDirectories);
            var vspscc = Directory.EnumerateFiles(path, "*.vspscc", SearchOption.AllDirectories);
            DeleteFolderOrFiles(vssscc);
            DeleteFolderOrFiles(vspscc);
            var sln = Directory.EnumerateFiles(path, "*.sln", SearchOption.AllDirectories);
            RewriteFileContent(sln,(item)=> { 
               return Regex.Replace(item, @"GlobalSection\(TeamFoundationVersionControl\)[\s\S]+?EndGlobalSection", "");
            });
            var csproj = Directory.EnumerateFiles(path, "*.csproj", SearchOption.AllDirectories);
            RewriteFileContent(csproj, (item) => {
                item = Regex.Replace(item, @"<SccProjectName>.+?</SccProjectName>", "");
                item = Regex.Replace(item, @"<SccLocalPath>.+?</SccLocalPath>", "");
                item = Regex.Replace(item, @"<SccAuxPath>.+?</SccAuxPath>", "");
                item = Regex.Replace(item, @"<SccProvider>.+?</SccProvider>", "");
                return item;
            });
            var tf = Directory.EnumerateDirectories(path, "$tf", SearchOption.AllDirectories);
            DeleteFolderOrFiles(tf);
            btnDisassociateTFS.Enabled = true;
            MessageBox.Show("解除TFS绑定的源码目录成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void DeleteFolderOrFiles(IEnumerable<string> files)
        {
            if (files == null)
            {
                return;
            }
            foreach (var item in files)
            {
                if (File.Exists(item))
                {
                    File.Delete(item);
                    continue;
                }
                if (Directory.Exists(item))
                {
                    Directory.Delete(item, true);
                }
            }
        }
        private void RewriteFileContent(IEnumerable<string> files,Func<string,string> contentOperation)
        {
            foreach (var item in files)
            {
                if (!File.Exists(item))
                {
                    continue;
                }
                Encoding textEncoding = GetFileEncodeType(item);
                StreamReader reader = new StreamReader(item, textEncoding);
                string fileContent = reader.ReadToEnd();
                reader?.Close();
                reader?.Dispose();
                if (contentOperation != null)
                {
                    fileContent = contentOperation(fileContent);
                }
                StreamWriter writer = new StreamWriter(item, false, textEncoding);
                writer.Write(fileContent);
                writer.Flush();
                writer?.Close();
                writer?.Dispose();
            }
        }
        /// <summary>
        /// 获取指定文件的编码
        /// 以防止在不知道文件编码格式的情况下处理文件而造成的乱码问题
        /// </summary>
        /// <param name="filename">文件路径</param>
        /// <returns></returns>
        private System.Text.Encoding GetFileEncodeType(string filename)
        {
            if (!File.Exists(filename))
            {
                return System.Text.Encoding.Default;
            }
            System.Text.Encoding ReturnReturn = null;
            System.IO.FileStream fs = null;
            System.IO.BinaryReader br = null;
            try
            {
                fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                br = new System.IO.BinaryReader(fs);
                byte[] buffer = br.ReadBytes(2);
                if (buffer.Length > 0 && buffer[0] >= 0xEF)
                {
                    if (buffer[0] == 0xEF && buffer[1] == 0xBB)
                    {
                        ReturnReturn = System.Text.Encoding.UTF8;
                    }
                    else if (buffer[0] == 0xFE && buffer[1] == 0xFF)
                    {
                        ReturnReturn = System.Text.Encoding.BigEndianUnicode;
                    }
                    else if (buffer[0] == 0xFF && buffer[1] == 0xFE)
                    {
                        ReturnReturn = System.Text.Encoding.Unicode;
                    }
                    else
                    {
                        ReturnReturn = System.Text.Encoding.Default;
                    }
                }
                else if (buffer.Length > 0 && buffer[0] == 0xe4 && buffer[1] == 0xbd) //无BOM的UTF-8 
                {
                    ReturnReturn = System.Text.Encoding.UTF8;
                }
                else
                {
                    ReturnReturn = System.Text.Encoding.Default;
                }
            }
            catch
            {
                ReturnReturn = System.Text.Encoding.Default;
            }
            finally
            {
                br?.Close();
                fs?.Close();
                fs?.Dispose();
            }
            return ReturnReturn;
        }
        private void btnOpenFloder_Click(object sender, EventArgs e)
        {
            if (fbdFolderSelect.ShowDialog() == DialogResult.OK)
            {
                txtSourceFolder.Text = fbdFolderSelect.SelectedPath;
            }
        }
        private void txtSourceFolder_DragDrop(object sender, DragEventArgs e)
        {
            string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
            if (File.Exists(path))
            {
                FileInfo fileInfo = new FileInfo(path);
                path=fileInfo.DirectoryName;
            }
            txtSourceFolder.Text = path;
        }
        private void txtSourceFolder_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;//重要代码:表明是所有类型的数据,比如文件路径
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }

        }
    }
}

示例下载

解除解决方案与TFS绑定
以上示例请使用Microsoft Visual Studio 2019 打开

转载请注明:清风博客 » 移除.net解决方案中TFS的绑定控制

]]>
https://www.skyfinder.cc/2021/03/26/removenetcodetfs/feed/ 0
博客园整改 https://www.skyfinder.cc/2021/03/21/cnblogs-rectify/ https://www.skyfinder.cc/2021/03/21/cnblogs-rectify/#respond Sun, 21 Mar 2021 04:46:26 +0000 https://www.skyfinder.cc/?p=3391 博客园是国内最出名的IT从业者的技术交流社区。

博客园是一个面向开发者的知识分享社区。自创建以来,博客园一直致力并专注于为开发者打造一个纯净的技术交流社区,推动并帮助开发者通过互联网分享知识,从而让更多开发者从中受益。博客园的使命是帮助开发者用代码改变世界。

不知为何,浏览博客园任何帖子都会跳转到整改公告,具体整改原因不详!也不晓得哪里违规了!不管怎么样,希望尽快完成整改,合规合法运营!

为了遵守相关法律法规,合法合规运营,网站进行全面整改,整改工作于2021年3月18日12:00开始,预计于3月25日11:59结束,整改期间全站无法发布任何内容,之前发布的内容重新审核后才能访问,由此给您带来很大的麻烦,请您谅解。

转载请注明:清风博客 » 博客园整改

]]>
https://www.skyfinder.cc/2021/03/21/cnblogs-rectify/feed/ 0
关于HOST文件中出现不明网址记录 https://www.skyfinder.cc/2021/03/15/microdone-cn/ https://www.skyfinder.cc/2021/03/15/microdone-cn/#respond Mon, 15 Mar 2021 04:33:11 +0000 https://www.skyfinder.cc/?p=3376 因局域网源代码管理服务器地址做了变更,所以就重新更改下HOST文件中的IP地址。意外发现HOST文件中多了一条记录,而我对这条记录竟然没有一点印象。好奇怪!!!!哪来的呢?172.17.187.161 windows10.microdone.cn,其中IP172.17.187.161又是本地局域网。然后就通过浏览器尝试访问域名windows10.microdone.cn,结果根本无法连接,最后尝试了顶级域microdone.cn,这下就出现了内容。如下图所示:

我仔细回忆一下,自己最近几天究竟做了什么,好像也没有做什么呀!于是,我就在控制面板中打开程序和功能查看一下。最近几个月的程序安装记录,由安装时间来看,也没有太多内容。如下图所示:

我结合之前打开域名microdone.cn来看,这条HOST记录必然和中国邮政储蓄银行网上银行安全控件有关。看到了此记录,也逐渐想起自己的确安装过这个控件。既然现在用不到这个网上银行,就索性把它给卸载吧。最后,把HOST文件的那条记录也删除。我很疑惑为什么会有这种行为,一些开发人员总是搞些千奇百怪的事情,也不晓得意图是什么。

转载请注明:清风博客 » 关于HOST文件中出现不明网址记录

]]>
https://www.skyfinder.cc/2021/03/15/microdone-cn/feed/ 0
深圳龙华清湖春季车展 https://www.skyfinder.cc/2021/03/13/shenzhenlonghuaicocarshow/ https://www.skyfinder.cc/2021/03/13/shenzhenlonghuaicocarshow/#respond Sat, 13 Mar 2021 15:37:58 +0000 https://www.skyfinder.cc/?p=3366 突然,有一种念想,想买一辆代步车。所以,关注了一些车展的相关消息。春季车展还是不少的,其3月4日至7日宝安体育馆,13日至14日深圳市龙华星河iCO广场都有相关车展的活动。这前后两次的车展活动规模都相对较小,品牌以及车型都不是很多。今天让人意想不到的的是,这小小的车展活动竟然会请车模。没有错,有车模,不过仅仅只有两个车模。车展活动的车我都已经看一遍了,各个品牌车的价格都不算贵,但是我还是没有订购。我觉得还是要多了解下,要不然总感觉太草率了!车没拍,车模拍了几张。

转载请注明:清风博客 » 深圳龙华清湖春季车展

]]>
https://www.skyfinder.cc/2021/03/13/shenzhenlonghuaicocarshow/feed/ 0