SharpBrowser,使用 C# 和CefSharp构建的全功能网页浏览器,下载SharpBrowser的源码_GitHub_帮酷

mikel阅读(2626)

来源: SharpBrowser,使用 C# 和CefSharp构建的全功能网页浏览器,下载SharpBrowser的源码_GitHub_帮酷

SharpBrowser源代码下载

  • Git URL:
    git://www.github.com/sharpbrowser/SharpBrowser.git
  • Git Clone代码到本地:
    git clone http://www.github.com/sharpbrowser/SharpBrowser
  • Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/sharpbrowser/SharpBrowser
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    

SharpBrowser

SharpBrowser是最快的开放源码 C# 网络浏览器 ! 在渲染网页时比 Google Chrome 稍快一些,因为它是轻量级的CEF渲染器。 我们比较了每个可用的.NET 浏览浏览引擎,最终确定了高性能的 CefSharp。 许可许可许可许可许可。

特性

  • HTML5,CSS3,JS,HTML5视频,3,等等
  • 标签式浏览
  • 地址栏( 也打开 Google )
  • 后退,前进,停止,刷新
  • 开发工具开发工具
  • 搜索栏( 也高亮显示所有实例)
  • 下载管理器
  • 自定义错误页
  • 自定义上下文菜单
  • 轻松添加厂商特定品牌,按钮或者热键
  • 查看联机&脱机网页

热键

热键函数

Ctrl+T 添加新标签
Ctrl+N 添加新窗口
Ctrl+W 关闭活动选项卡
F5 刷新活动选项卡
F12 开发人员工具
Ctrl+Tab 切换到下一个标签
Ctrl+Shift+Tab 切换到前一选项卡
Ctrl+F 打开搜索栏( 输入查找下一个,Esc关闭)

代码

  • SharpBrowser使用 CefSharp 51,NET框架 4.5.2
  • MainForm.cs – 主网页浏览器用户界面和相关功能
  • Handlers – 我们注册在CefSharp中的各种处理程序,使我们能够更深入地集成我们的CefSharp和
  • Data/JSON.cs – 快速JSON序列化器/解串器
  • bin – 由于需要复杂的CefSharp设置,bin 文件夹中包含二进制文件。 不清空这里文件夹。
  • 下载管理器和自定义错误页面需要 bin/storage – HTML和 JS

Credits

Winform 自定义TabControl实现浏览器标签 - InkGenius - 博客园

mikel阅读(1767)

来源: Winform 自定义TabControl实现浏览器标签 – InkGenius – 博客园

实现效果
作者:Gavin(daisong.michelangelo@gmail.com)
时间: Nov, 2015
封面图片为Gavin原创,请勿未经允许私自引

最近因为工作需要,要做一个桌面浏览器,和大多数浏览器一样,我的这个浏览器也需要有标签栏,效果就像这样:目标效果图
在网上查了很多资料,大多数做法都是自定义Winform中TabControl控件,具体的做法有多种。
首先让我们来见识一下winform原生的TabControl是什么样子的:这里写图片描述
怎么样,有没有让你有种思考人生的冲动?
下面我们来分析怎么将它改造成我们想要的模样这里写图片描述
TabControl有由一个个TabPage组成,每个TabPage有一个TabItem(也就是页签)
让我们从这个页签开始,它由以下三部分组成:

  1. 标签页左边是一个图标
  2. 中间是网页的Title
  3. 右边是标签的关闭按钮

要实现这三个部分,我们可以重写TabControl.DrawItem 事件,在这之前我们当然要继承Winform 的TabControl 组件:
public partial class TabControl1 : TabControl
然后还要记得将DrawMode 设置成 TabDrawMode.OwnerDrawFixed,这样我们就可以自己画TabItem了,否则你在DrawItem里面干的事可就白干了。
然后,我们就可以重写DrawItem事件,开始画也签了

this.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.MainTab_DrawItem);

首先,我们可以先设置标签页的背景,而且标签在选中和未选中的时候背景是不一样的。

// 获取当前选项卡区域
 Rectangle bounds = GetTabRect(e.Index); 
 Brush br = SystemBrushes.ActiveCaptionText;
 if (e.Index == this.SelectedIndex)    //当前选中的Tab页,设置不同的样式以示选中  
 {
   e.Graphics.FillRectangle(Brushes.White, bounds); //改变选中选项卡标签的背景色   
 }
 else
  {
e.Graphics.FillRectangle(Brushes.DarkRed, bounds); //改变非选中的选项卡标签的背景色
    br = SystemBrushes.GrayText;    //置灰非选中项
}

注意,一定要先画背景,在画其他的东西,不然后画背景会将之前画的东西擦除掉。
接着我们就可以来画图标了,TabControl 有一个ImageList可以存放图片,可以通过key和index获取到。原生的TabControl已经实现了这个功能,但是我们重写了整个TabItem的绘制方法,所以我们还是要自己实现。

 //绘制图标  
 if (this.ImageList != null)
 {
     int index = this.TabPages[e.Index].ImageIndex;
     string key = this.TabPages[e.Index].ImageKey;
     Image icon = new Bitmap(icoSize, icoSize);
     if (index > -1)
     {
         icon = this.ImageList.Images[index];
     }
     if (!string.IsNullOrEmpty(key))
     {
         icon = this.ImageList.Images[key];
     }
     e.Graphics.DrawImage(icon, bounds.X + startX, bounds.Top + 2);
}

好了,我们快要完成了,Graphics有绘制各种形状的方法,参数大多含有坐标,坐标控制就不多说了,MSDN里的方法说的很清楚了。
接下来,我们要画文字了,很简单,TabPages[i].Text就是我们的Title

 e.Graphics.DrawString(this.TabPages[i].Text, font, br, bounds.X + startX, bounds.Y + 6);

最后,我们还是一样的方法画出关闭按钮。closeImage可以先导入到资源文件

bounds.Offset(bounds.Width - (CLOSE_SIZE + 5), 2);
e.Graphics.DrawImage(closeImage, bounds.X, bounds.Y);

好了,页签的外观我们已经大工告成了,接下来我们要响应关闭按钮来关闭页签。
方法是监听鼠标点击事件,如果点击区域是在我们画关闭按钮的区域呢,我们就冲tabPages中将这个Page移除。

 //计算关闭区域  
 Rectangle bounds = this.GetTabRect(this.SelectedIndex);
 bounds.Offset(bounds.Width - (CLOSE_SIZE + 5), 2);
 bounds.Width = CLOSE_SIZE;
 bounds.Height = CLOSE_SIZE;
 //如果鼠标在区域内就关闭选项卡  
 bool isClose = x > bounds.X && x < bounds.Right
  && y > bounds.Y && y < bounds.Bottom;
 if (isClose == true)
 {
     int index = this.SelectedIndex;
     TabPage tab = this.SelectedTab;
     this.TabPages.Remove(tab);
     tab.Dispose();
 }

好了,看来我们已经完美地做出了一个美观的TabItem了,如果你没有别的需要的话,这样的组件就可以使用了。
但如我之前所说,实现方法有多种,因为需求总是在变,所以我们还是需要一种更全面的方法。
如果我需要改变整个TabControl 的背景色透明要怎么办呢?
仅仅重写DrawTabItem是远远不够的。

好了,下面进入今天的主题,怎么重写TabControl的OnPaint()方法来实现我们之前所实现的功能。
首先,我们当然要继承TabControl,还要设置几个属性

 this.SetStyle(
     ControlStyles.UserPaint |                      // 控件将自行绘制,而不是通过操作系统来绘制  
    ControlStyles.OptimizedDoubleBuffer |  // 该控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁  
    ControlStyles.AllPaintingInWmPaint |           // 控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁  
    ControlStyles.ResizeRedraw |                   // 在调整控件大小时重绘控件  
    ControlStyles.SupportsTransparentBackColor,    // 控件接受 alpha 组件小于 255 的 BackColor 以模拟透明  
       true);                                         // 设置以上值为 true  
this.UpdateStyles();

最终要的一个就是要设置ControlStyles.UserPaint 为True,不然你就思考人生吧!但是设置了这个属性我们就要告别过去,从一张白纸开始了,当然这也意味着我们就可以尽情发挥了。
首先,我们就可以重写OnPaint方法了,这里我们绘制背景就很方便了,只要画一张图片就好了。

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Rectangle rec = this.ClientRectangle;           // 获取TabControl主控件的工作区域
Image backImage = Properties.Resources.bgImage; //获取背景图片,我的背景图片在项目资源文件中。
e.Graphics.DrawImage(backImage, 0, 0, this.Width, this.Height);  //绘制主控件的背景
//绘制标签样式
for (int i = 0; i < this.TabPages.Count; i++)
{
  //....这里和绘制上面的标签页类似
}
}

好了,先写到这吧,一个简单的自定义TabControl就实现了。
参考资料:

一步一步玩控件:自定义TabControl——从山寨Safari开始

chrome升级后LODOP打印插件无法使用 - James.H.Fu - 博客园

mikel阅读(1241)

来源: chrome升级后LODOP打印插件无法使用 – James.H.Fu – 博客园

今天帮朋友使用LODOP实现一个套打程序时,发现LODOP打印插件在chrome下始终无法使用。分析后发现是自己才升级了chrome,chrome新版默认是禁用npapi的,因此需要手动启用一下,启用方法如下:

 在谷歌浏览器地址栏输入:
chrome://flags/#enable-npapi
然后找到“启用NPAPI”,点击启用,根据提示重启chrome即可。

C# ToShortDateString() ToString() 设置日期格式的区别 - wusir - 博客园

mikel阅读(1030)

来源: C# ToShortDateString() ToString() 设置日期格式的区别 – wusir – 博客园

C#中,ToShortDateString()是用于显示短日期格式的方法,如果使用下面的语句:

Label1.Text = DateTime.Now.ToShortDateString();

那么,在Label1中会显示什么样的短日期格式呢?

答案是:不确定。

可能是:2013-07-26

也可能是:2013/07/26

也可能是:2013.07.26

等等等等,虽然许多文章中认为应该是“2013-07-26”,实际上,ToShortDateString()方法所显示出的短日期字符串不是由它本身所能控制的,实际它是由所处区域及人为设置所影响的。

进入“控制面板”,打开“区域和语言”,在“格式”签下可以看到短日期的设置方式,比如上述ToShortDateString()所产生的三种可能的输入分别对应了:“yyyy-MM-dd”、“yyyy/MM/dd”、“yyyy.MM.dd”三种设置的短日期格式。

因此,电脑所处的区域不同,或者电脑用户的个人偏好不同,而设置了不同的短日期格式,那么在C#开发的Windows应用或者Web应用,短日期就会以不同的格式显示。

但在设计开发中,为了保持界面的统一性,往往希望短日期格式在任何情况下都是固定不变的,不使其受到用户对短日期格式设置的影响。这时候,需要使用ToString的方式,强行指定日期的显示格式,而不提取客户机上用户设定的格式。

具体使用方法是:

Label1.Text = DateTime.Now.ToString(“yyyy-MM-dd”);

这样做的结果,无论客户机是什么样的短日期格式设置,可以确定地说,这个日期的显示格式必然是:

“2013-07-26”

 

同样地,如果要在各种电脑上都显示出统一的长日期、时间等信息,都可以使用ToString方法。

 

总结:如果强调统一的界面,可以使用ToString的办法指定不变的日期或时间格式;如果考虑应用要灵活适应不同区域(比如可以全球访问的网站)的用户,则使用ToShortDateString办法。

利用echarts展示旅行足迹 - champyin - 博客园

mikel阅读(1370)

来源: 利用echarts展示旅行足迹 – champyin – 博客园

前言

一直有个环游世界的梦,周游列国,体验不同国家的人类文明,寻山访水,体验造物主大自然的伟大造化。毕竟人生不止眼前的苟且,还有诗和远方。这么多年以来,陆续走过了一些地方,每到一个地方,都让我离梦想又近了一些。虽然我知道这比起环游世界来说,还差不知道多少个山头,但是我一直在往这个梦努力,靠近。希望终有一天,我可以笑着对自己说,你做到了!

6年前,因为工作的原因,我接触过地图应用的开发,从那时起,我对地图的热爱就埋在了心底。今年年中我带爸妈旅了旅游,去了一些我没去过的地方,我好想有个地图可以让我点亮一下,记录一下我到过的新的“领土”。搜了下市面上已经存在的地图应用,都不是我想要的,唯一比较符合我的需求的是百度旅游里面的一个小功能,叫做足迹地图,但是似乎早就停止了维护,数据停留在2016年。。。

找不到趁手的工具,那就自己打造一把。是啊,为什么不自己开发一个呢?说干就干。

工程搭建

首先用 cyt-cli 快速搭建项目框架。cyt-cli地址

cyt-cli 是一款可以快速创建前端工程的脚手架,具有比较完善的webpack4配置,目前支持纯js、vue、react等语言版本。
如果没有安装 cyt-cli ,先全局安装一下:npm i -g cyt-cli

cyt-cli create footprint
✔ fetching template ...
? please choose a template to create roject (Use arrow keys)
❯ swan-template 
  swan-vue-template 
  swan-react-template 

因为想快速做出雏形来,所以使用最简单的模版就行,选择第一个 swan-template
等待一会,工程就搭建好了。
生成的工程目录:

|--build/ # webpack配置文件
|    |-- webpack.base.js
|    |-- webpack.dev.js
|    |-- webpack.prod.js
|--public/ # 首页模版
|    |-- index.html
|--src/
|    |-- assets/ # 静态资源,比如中国地图数据
|    |-- components/ # 项目组件
|    |       |--  foo.js
|    |       |--  bar.js
|    |-- icon/ # 字体图标
|    |-- images/ # 图片资源
|    |-- theme/ # 样式文件
|    |-- index.js # 项目入口
|--.babel.js # babel配置
|--.browserslistrc.json # 浏览器支持规则
|--.gitignore 
|--package.json
|--postcss.config.js # postcss插件配置
|--README.md

安装一下依赖包。

cd footprint
npm i

地图选型

地图展示我选择了 echarts。 echarts官网

npm i --save echarts

应用开发

我的核心需求很简单,就是可以把我去过的国家、省、市在地图上展示出来即可。
先实现国内的省,开发逻辑很简单:

1.引入echarts

按需引用

import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/map';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
import 'echarts/lib/component/visualMap';
import 'echarts/lib/component/legend';
import 'echarts/lib/component/toolbox';

2.处理用户数据

seriesdata用。

let handleData = function(rawdata) {
    rowData.forEach(item => {
        item.value = FREQUENCY[item.value]
        if (item.value !== NEVER) {
            item.label = { show: true, color: LEBEL_COLOR }
        }
        if (item.value === NEVER) {
            never.push(item);
        } else if (item.value === ONECE) {
            onece.push(item);
        } else if (item.value === AFEWTIMES) {
            afewtimes.push(item);
        } else {
            usually.push(item);
        }
    });
    series = [usually, afewtimes, onece, never].map((item, index) => {
        let temp = {
            type: 'map',
            map: mapType,
            roam: true,
            itemStyle: {
                emphasis: { label: { show: true } },
                areaColor: '#fff'
            }
        };
        temp.name = legendData[index];
        temp.data = item;
        return temp;
    })
}

handleData(userData);

3.注册map

echarts有个registerMap方法,echarts.registerMap(mapName, geoJson, specialAreas).

- mapName:地图名称,一定要与option->series->map对应的值相同。
- geoJson:GeoJson格式的数据,具体格式见 http://geojson.org/。
- specialAreas:可选。将地图中的部分区域缩放到合适的位置,可以使得整个地图的显示更加好看。

geoJson是地理信息数据,一般都很大,当然通过异步获取。

util.get('assets/china.json').then(data => {
    let chinaJson = data;
    myChart.hideLoading();
    // 注册地图
    echarts.registerMap(mapName, chinaJson, {})
})

ECharts3提供的矢量地图数据,在4版本后已经不提供下载服务了。官网的解释是“由于部分数据不符合国家《测绘法》规定”。不过,只要不商用,这些矢量数据还是可以使用的。有需要可以到我这里获取 https://github.com/yc111/echarts3-geojson

4.配置option显示地图

注册地图后进行其他配置

// 指定图表的配置项和数据
let option = {
    color: _color,
    title: _title,
    tooltip: _tooltip,
    legend: _legend,
    visualMap: _visualMap,
    toolbox: _toolbox,
    series: series
};
// 使用刚指定的配置项和数据显示图表
myChart.setOption(option);

添加Travis CI持续集成

花了大概一天时间,雏形做好(感觉很大一部分时间在调地图颜色…)。我把项目部署在了github page上,但是每次build之后,都要手动部署,太麻烦。

于是我用 Travis CI 给项目做了持续集成,现在只要代码一提交,就会自动部署了。

具体关于Travis的详细配置,可以参考我的另一篇文章:利用Travis CI+GitHub实现持续集成和自动部署

效果预览

项目预览地址:http://champyin.com/footprint/
footprint.jpg

暂时还比较简陋,并且只支持省。以后我会把世界地图,和城市地图都加进来(毕竟也是出过境的人,哈哈),实现地图下钻,并且优化用户数据设置,不断完善下去。

项目源码地址:https://github.com/yc111/footprint
欢迎star。如果你喜欢,可以fork本项目,然后打造属于你自己的足迹应用。


欢迎转载,转载请注明出处:
https://champyin.com/2019/09/27/%E5%88%A9%E7%94%A8echarts%E5%B1%95%E7%A4%BA%E6%97%85%E8%A1%8C%E8%B6%B3%E8%BF%B9/

本文同步发表于:
利用echarts展示旅行足迹 | 掘金

处理程序 SafedogIISAuditor32 错误代码 0x80070003 - 加菲猫and大白 - 博客园

mikel阅读(961)

来源: 处理程序 SafedogIISAuditor32 错误代码 0x80070003 – 加菲猫and大白 – 博客园

卸载服务器安全狗 常会有卸载残留 如出现以下情况 可参考本人解决方法解决 仅是本人经验之谈 不一定全面 仅供参考

解决办法: 打开iis信息服务管理器 删除isapi筛选器 和 程序处理映射里面对应的带有安全狗的配置,然后重新启动网站

.NET之Hangfire快速入门和使用 - 追逐时光 - 博客园

mikel阅读(1383)

来源: .NET之Hangfire快速入门和使用 – 追逐时光 – 博客园

 

文章正文:

前言:

定时任务调度问题,是一个老生常谈的问题。网上有许多定时任务调度的解决方案,对于我而言很早以前主要是使用Window计划和Window服务来做任务定时执行,然后就开始使用定时任务调度框架Quartz.Net。但是却一直没有上手过Hangfire这个自带后台任务调度面板,可以在后台手动执行任务的神奇的任务调度框架。前段时间终于开始对他下手了,通过在网上查阅了一些资料和查看了Hangfire在Github中的demo,终于在我自己的项目中用上了Hangfire。在该篇文章中主要简单介绍一下什么是Hangfire,Hangfire的基本特征与优点和分别使用MySQL,MS SQL Server作为存储使用。

一、Hangfire是什么:

Hangfire是一个开源的.NET任务调度框架,提供了内置集成化的控制台,可以直观明了的查看作业调度情况,并且Hangfire不需要依赖于单独的应用程序执行(如:windows服务,window计划)。并且支持持久性存储。

二、Hangfire使用条件:

Hangfire与特定的.NET应用程序类型无关。您可以在ASP.NET Web应用程序,非ASP.NET Web应用程序,控制台应用程序或Windows服务中使用它。以下是要求:

1.NET Framework 4.5

2.永久存储(Hangfire将后台作业和其他与处理有关的信息保留在永久性存储器中,所以需要存储库来存储如:MS SQL Server,Redis,MySQL,PostgreSql等)

3.Newtonsoft.Json库≥5.0.1

三、Hangfire的基本特征与优点:

通过官网中的一张图片便可知道它是一个多么优秀的任务调度框架,如下图所示:

 

 

四、Hangfire安装和使用:

在NuGet上有关于Hangfire的 一系列软件包:

详情地址: https://www.nuget.org/packages?q=Hangfire

通过在程序包管理控制台中输入安装命令安装Hangfire所需NuGet包:

使用MS SQL Server作为存储时我们需要安装的NuGet:

在ASP.NET 应用程序下使用Hangfire安装:

1
Install-Package Hangfire

在控制台应用程序或者window server中处理作业:

1
2
Install-Package Hangfire.Core
Install-Package Hangfire.SQLServer

注意,在控制台应用程序或者window server中不推荐直接安装:Install-Package Hangfire ,因为它只是一个快速启动软件包,并包含您可能不需要的依赖项(例如,Microsoft.Owin.Host.SystemWeb等无关依赖项)。

使用MySQL作为存储时我们需要安装的NuGet:

在ASP.NET 应用程序下使用Hangfire安装:

1
Install-Package Hangfire.Core

我们还需要安装一个MySql存储(Hangfire.MySqlStorage)的拓展,注意因为Hangfire本身是不支持MySQL存储的,这是名为:Arnoldas Gudas作者拓展的:

Nuget地址:https://www.nuget.org/packages/Hangfire.MySqlStorage/

安装命令:

注意:因为我的项目是.NET Framework,Version=v4.5.1版本的,所以只能安装1.0.7版本的,大家看需求而定

1
Install-Package Hangfire.MySqlStorage -Version 1.0.7

当我们要使用(宿主)IIS托管ASP.NET应用程序时,我们还需要安装:

1
Install-Package Microsoft.Owin.Host.SystemWeb -Version 4.0.1

 

添加和配置OWIN Startup.cs,及其连接对应的存储数据库:

添加OWIN Startup.cs

这里是当你的项目中不存在Startup.cs时才需要执行添加的操作!

什么是OWIN Startup.cs:

简单概述:是.NET 平台开放的web接口,Startup则是.Net与web通讯管道,起到转发,沟通的作用。

详情介绍:https://www.cnblogs.com/wj033/p/6065145.html

在Startup.cs中连接需要使用的存储库:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void Configuration(IAppBuilder app)
{
    //运用SQLServer存储,对应web.config中的connectionStrings中的name
    GlobalConfiguration.Configuration.UseSqlServerStorage("sqlserver_connection");<br>           
    //注意,当你使用的是MySql作为存储时,需要如下配置
    //运用MySql存储,对应web.config中的connectionStrings中的name
    GlobalConfiguration.Configuration.UseStorage(new MySqlStorage("mysql_connection"));
    app.UseHangfireDashboard();//配置后台仪表盘
    app.UseHangfireServer();//开始使用Hangfire服务
}

Web.config数据库配置:

1.MS SQL Server中:

1
2
<connectionStrings>
    <add name="sqlserver_connection" connectionString="Data Source=.;Initial Catalog=MyFirstDb;Integrated Security=True" providerName="System.Data.SqlClient" /><br>  </connectionStrings>

2.MySQL中:

1
2
<connectionStrings>
   <add name="mysql_connection" providerName="System.Data.MySqlClient" connectionString="Server=123.xxx.xxx.xx;Port=3306;Database=MyFirstDb;Uid=root;<br>     Pwd=youpassword;charset=utf8;SslMode=none;Allow User Variables=True" /><br>  </connectionStrings>

运行程序,访问调度控制面板:

当我们已经完成了上面的相关配置后,且程序能够正常无bug的运行时,我们的Hangfire Dashboard(仪表盘)在我们的本地就可以正常访问了(Hangfire仪表盘默认只支持本地访问),假如需要远程可访问的话我们还需要做对应的配置授权操作!

运行成功,查看数据库中是否生成了与Hangfire相关的表:

首次运行成功后,打开数据库可以看到Hangfire已经自动为我们创建了定时任务的一些定时任务列表,定时队列,服务,状态等相关的数据表(展现了Hangfire作用的持久化特性),如下图所示:

a.MS SQL Server中生成的表:

 

 b.MySQL中生成的表:

 

 访问调度控制面板:

本地访问方式:https://localhost:端口号/hangfire/

调度控制面板效果图:

 

 后台常用任务调度创建和使用:

复制代码
//支持基于队列的任务处理:任务执行不是同步的,而是放到一个持久化队列中,以便马上把请求控制权返回给调用者。
var jobId = BackgroundJob.Enqueue(() => WriteLog("队列任务"));

//延迟任务执行:不是马上调用方法,而是设定一个未来时间点再来执行,延迟作业仅执行一次
var jobId = BackgroundJob .Schedule(()=> Console .WriteLine(""),TimeSpan .FromDays(1));//一天后执行该任务

//循环任务执行:一行代码添加重复执行的任务,其内置了常见的时间循环模式,也可基于CRON表达式来设定复杂的模式。【用的比较的多】
RecurringJob.AddOrUpdate(() => WriteLog("每分钟执行任务"), Cron.Minutely); //注意最小单位是分钟

//延续性任务执行:类似于.NET中的Task,可以在第一个任务执行完之后紧接着再次执行另外的任务
BackgroundJob.ContinueWith(jobId, () => WriteLog("连续任务"));
复制代码

总结:

通过本次项目实践的确让我感受到了Hangfire的魅力所在,真的可以说是上手简单,开箱即用的一个任务调度框架。并且该框架做的最好的是,官方文档详细,并且还提供了完整的demo示例。最后要为Hangfire的作者点赞!

Hangfire相关使用学习资料:

官网地址:https://www.hangfire.io/

GitHub源码:https://github.com/HangfireIO/Hangfire

中文文档:https://www.bookstack.cn/read/Hangfire-zh-official/README.md

GitHub使用示例源码:https://github.com/HangfireIO/Hangfire.Samples(包括控制台应用程序,window服务,ASP.NET MVC,WebForm)

Hangfire使用文章汇总:https://www.bbsmax.com/R/xl56E0nrJr/

MSDTC不可用怎么办(轉) - maanshancss - 博客园

mikel阅读(1008)

来源: MSDTC不可用怎么办(轉) – maanshancss – 博客园

问题:安装完金蝶KIS商贸版产品后,在新建账套的过程中,系统显示以下提示信息“数据库升级失败!SQL文件不全或SQL语句有误!”
错误描述:number:-2147217900
Source:Microsoft OLE DB Provider for SQL Server
Description:服务器’PC-200906041643’上的MSDTC不可用。
如下图:

导致新建账套不成功。
【分析】:
msdtc.exe是微软分布式传输协调程序,该进程用于调用Windows系统的Microsoft Personal Web Server和Microsoft SQL Server。MSDTC服务是一个系统服务,它是金蝶商贸版软件运行不可缺少的系统服务组件。如果MSDTC服务不能正常运行,则新建账套将遇到错误。出现这种情况,一般是发生在使用了某些电脑城装机版的Ghost系统,在这些系统中,MSDTC服务默认没有启动或没有安装,需要手工设置它的启动或安装。
【处理】:
1、检查服务器上的MSDTC是否正常启动
以管理员身份登录操作系统,通过控制面板–》管理工具–》服务,找到MSDTC服务,检查它是否处于自动运行状态:

如果没有,则设置为自动启动状态。
2、重新安装并重置MSDTC服务
如果上述设置无法使用MSDTC服务正常运行,则需要重新安装MSDTC服务。一般情况下,安装并重置MSDTC服务,可以按以下过程进行:
1)先用“msdtc -uninstall”卸了它,
2)再用“msdtc -install”重新装上,
3)然后用“msdtc -resetlog”创建日志文件,
4)最后用“net start msdtc”启动服务
其中,上述命令可以通过在运行中输入后,确定即可,如:

确定后,系统显示这样的类似信息:

在上述设置过程中,根据系统提示,如果需要重启操作系统,请按提示操作。
3、说明事项
1、出现这种情况,一般是发生在使用了某些电脑城装机版的Ghost系统,在这些系统中,MSDTC服务默认没有启动或没有安装,需要手工设置它的启动或安装。正常安装的系统中较少出现这样的问题。
2、导致MSDTC服务不可用的原因有很多(如病毒、木马等等),解决方法也有很多种。上述方法只是其中最常用的方法之一。而且这涉及到对系统服务的一些操作,对问题处理者的要求相对要高一些,因此在遇到相似的问题时,可以多参考网上的资料,如:msdtc不可用MSDTC等等。因此出现此类错误,需要仔细分析原因,针对性地进行处理。
3、如果在金蝶KIS专业版、金蝶K/3或其他需要涉及到MSDTC服务的应用中,遇到此类错误也可参考此方法处理。

下面的链接:http://tangjun141.blog.163.com/blog/static/56462350200963073824318/

问题:商贸版2.0新建帐套时出现错误,提示如下图:
图片失效

解决
电脑公司装机用的Ghost版的XP系统由于进行过优化,会关闭系统的一些服务!启动服务软件能够正常使用了!!上面所述问题,主要和Windows的Distributed Transaction Coordinator服务没有启动有关。下面来启动Distributed Transaction Coordinator(msdtc)服务:
控制面板—管理工具—服务—Distributed Transaction Coordinator—-右键启动,如果启动失败
请尝试开始菜单—运行—输入CMD—在弹出的窗体输入如下命令:
Msdct –resetlog回车
Net Start msdtc
如果启动失败,请检查C:\WINDOWS\system32\MsDtc目录下是否有MSDTC.LOG文件!!如果没有请通过记事本手工建立该文件,重新执行上述命令!!
此时应该可以启动Distributed Transaction Coordinator服务了,如若还启动不了,我们需要重新安装来修复Distributed Transaction Coordinator服务,在命令行输入如下命令:
Net stop msdtc
Msdtc –uninstal
Msdtc –instal
net start msdtc
此时服务能够正常启动了!!

收藏
关注
评论
作者:王思明
出处:http://www.cnblogs.com/maanshancss/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

layui自定义js模块(实例) - UglyCode - CSDN博客

mikel阅读(822)

来源: layui自定义js模块(实例) – UglyCode – CSDN博客

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_36571185/article/details/78140969
注意:layui自定义模块,整个过程就两步,步骤虽少,但还是要多注意的细节问题,不然在定义模块上花费太多精力就不值得了。
第一步:定义模块
tablechecked.js

layui.define([‘layer’], function(exports) {
“use strict”;

var $ = layui.JQuery,
layer = layui.layer;

var table = {
/**
* 带有选择框的表格绑定多选事件
* @param tblId
*/
tableBindCheckClick: function (tblId) {
var tblObj = $(“#” + tblId);

tblObj.on(‘click’, ‘thead input[type=”checkbox”]’, function () {
var obj = $(“#” + tblId + ” tbody input[type=’checkbox’]:checkbox”);
if (this.checked) {
obj.prop(“checked”, true);
} else {
obj.prop(“checked”, false);
}
});

},
/**
* 获取带有选择框的表格选中的记录Ids
* @param tblId
* @returns {string}
*/
getTableCheckedRowIds: function (tblId) {
var ids = ”;
var tblObj = $(“#” + tblId);

tblObj.find(” tbody input[type=checkbox]:checked”).each(function(){
ids += $(this).val() + ‘,’;
});

// 去除最后一位逗号
ids = ids.substr(0, (ids.length-1));
return ids;
}

};
//expotts(“key”,value)
//key你懂吧? 待会在第二步就要用key值来获取var table这个对象。继而调用对象中函数
exports(‘tablechecked’, table);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
截图:

第二步:在js中使用模块
<script th:src=”@{/layui/layui.js}”></script>
<script type=”text/JavaScript” th:inline=”JavaScript”>
//一般直接写在一个js文件中
layui.config({
base:’/selfjs/’
});
//这里先use,表示使用 base:’/selfjs/’目录下的tablechecked.js文件

layui.use([‘form’,’element’,’layer’,’tablechecked’], function(){
var $ = layui.JQuery,
//layui.key通过key来获取对象
tools=layui.tablechecked;

//顶部新增事件监听
console.log(“准备新增”);
$(‘#addBtn’).on(‘click’,function(){
top.layer.open({
type:2,
area:[‘450px’,’380px’],
resize:false,
title:’商品添加’,
content:’/sys_stuff/edit’
});
});
//更新事件
console.log(“准备更新”);

$(‘.smt-update’).on(‘click’,function(){
top.layer.open({
type:2,
area:[‘450px’,’400px’],
resize:false,
title:’用户编辑’,
content:’/sys_stuff/edit?id=’+$(this).data(‘id’)
});
});
//删除事件
console.log(“准备删除”);

$(‘#btnDelete’).on(‘click’, function(){
var ids = tools.getTableCheckedRowIds(“myTable”);
if(!ids) return layer.msg(‘请先选择需要删除的记录。’, {time:1500, icon:0});
layer.confirm(‘确定删除?’, {icon: 3, title:’提示’}, function(index){
$.ajax({
type: ‘POST’,

url: /*[[@{/sys_stuff/delete}]]*/”,
data: {ids: ids },
dataType: ‘json’,
success: function (result) {
if (result.code == 0) {
layer.msg(‘删除成功’, {icon: 1,time: 1000});
setTimeout(function(){
parent.refreshIframe();
},800);

}
else {
layer.msg(‘删除失败!’+result.msg, {time:1000,icon: 2});
}
},
error: function(result, type) {
layer.msg(‘删除失败!’, { time:1000,icon: 2 });
}
});

});
});

});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
教程到此结束。
番外:
待注意事项:

exports(‘tablechecked’, tablechecked); //key你懂吧? 待会在第二步就要用key值来获取var table这个对象。继而调用对象中函数
layui.use([tablechecked])表示 ,使用这个模块,也就是咱自定义的js文件。
通过layui.key通过key来获取对象var tools=layui.tablechecked;
到此,番外也结束了,以上这些,基本上够用了。更多的我暂时不知道,如果你在阅读中遇见任何问题,欢迎你随时给我留言。
————————————————
版权声明:本文为CSDN博主「欧吃伞」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_36571185/article/details/78140969

Layui自定义模块的使用方式 - 张超博客 - CSDN博客

mikel阅读(876)

来源: Layui自定义模块的使用方式 – 张超博客 – CSDN博客

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_30036559/article/details/79120303
layui是一个极其不错的前端UI框架、是后端程序员的福音。总之如果你是一个后端开发者、如果你苦于你的界面“惨不忍睹”、选择layui来开发是个极好的选择。

之前的项目也有使用过layui、只是没有过多的关注其框架本身。对于项目上、拿来即用即可!

为什么要自定义模块呢?好处很多、比如可以大量重用代码……

我也是一个极其懒惰的人、总是想办法让代码可重用

根据layui官方的文档说明、首先第一步是要确定你要扩展的模块名称

我现在做的是登录功能、因此我的扩展模块名叫  login

使用layui.define()方法来扩展模块、当然模块中你也可以使用layui的其他方法、如下

layui.define(‘layer’, callback);
在定义扩展模块的时候、我需要使用layui的layer模块、然后在回调函数中定义自己的方法
layui.define([“layer”,”JQuery”],function (exports) {
var obj = {
login : function (url,data,$,targetUrl) {
$.post(url,{code:data.code},function (res) {
if (res.code&&res.code==400){
layer.msg(res.msg,{icon:1},function () {
window.location.href = targetUrl;
});
}else{
layer.msg(res.msg,{icon:1},function () {
window.location.href = targetUrl;
});
}
});
}
}
exports(“login”,obj);
});
上述代码中定义了一个login模块、以便在我登录的时候、不需要写过度的代码即可实现登录、让页面看起来更清爽【无任何杂质】
那么模块定义完了、怎么使用呢?

<script type=”text/JavaScript”>
layui.config({
base: ‘/static/admin/js/module/’//模块存放的目录
}).use([‘JQuery’,’element’,’form’,’login’],function () {
var $ = layui.JQuery,
form = layui.form,
element = layui.element,
login = layui.login;
form.on(“submit(subBtn)”,function (data) {
//获取表单的值
var field = data.field;
login.login(“{:url(‘Login/doLogin’)}”,field,$,”{:url(‘Index/index’)}”);
return false;
});
});
</script>
嗯、就这样、在登录的时候、直接将参数传递过去即可、在上述代码中url部分是使用TP的方法生成的、这里不用过多的研究【如果你是写前端的话】。
嗯、就这样、整个模块定义完成!!展示的效果如下

————————————————
版权声明:本文为CSDN博主「张超博客」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30036559/article/details/79120303