开源跨平台运行服务插件TaskCore.MainForm

本次将要很大家分享的是一个跨平台运行的服务插件 - TaskCore.MainForm,此框架是使用.netcore来写的,现在netcore已经支持很多系统平台运行了,所以将以前的Task.MainForm改良成跨平台的服务共大家使用和相互交流;本来这篇应该分享的是nginx+iis+redis+Task.MainForm构建分布式架构后续文章,但使用.netcore来定义一个服务插件和跨平台测试经过让我既兴奋又头痛,不说了下次再分享分布式后续文章吧;那么开始今天的分享内容,希望各位多多支持:

. 框架结构介绍及运行效果图

. 如何生成nuget包和使用开源框架TaskCore.MainForm

. win7和ubuntu16.04运行TaskCore.MainForm的两种方式和测试截图(也可认为.netcore项目在win7和ubuntu系统运行的两种方式)

. 框架代码解读及感悟

下面一步一个脚印的来分享:

. 框架结构介绍及运行效果图

首先,咋们先来认识下项目源码的工程目录结构如图:

结构看上去应该够清晰了,源码文件量也很少,不过的确实现了动态加载程序集dll来执行任务,后面会给出相应的执行截图,我们再来看下TaskCore.MainForm项目通过vs2015生成之后Bin文件夹中的文件如图:

如果安装了.netcore sdk的话在windows上您只需要上面截图的文件就能运行插件了;再来我们在已经安装过core sdk的win7系统上执行一下如下命令dotnet TaskCore.MainForm.dll就能看到如图的效果:

没错这就是插件运行起来的效果图,因为.netcore现目前暂时没有提供类似于winform那样的皮肤界面效果,所有只能通过命令行来做跨平台运行程序

. 如何生成nuget包和使用TaskCore.MainForm

首先,我们要明确服务是由两部分构成(TaskCore.MainForm和TaskCore.Plugin);TaskCore.MainForm主要用来运行程序,TaskCore.Plugin用来作为子任务需要继承的父类插件;当我们下载TaskCore.MainForm运行包之后(如图2结构),我们还需要做的就是继承TaskCore.Plugin.dl中的TPlugin这个类,来重写自己的任务内容,因此我们新建一个项目取名为:TaskCore.Test,再来我们通过vs2015引用功能直接添加TaskCore.MainForm运行包中的TaskCore.Plugin.dl引用,这个时候会提示一个错误:

错误意思是没法加载netcore版本的dll,因此这种直接在vs项目中引用方式添加dll依赖不行,需要通过nuget来添加依赖包(.netcore对类库的引用目前只能通过nuget来安装依赖,这个需要注意),所以我这里把TaskCore.Plugin项目通过dotnet pack命令来生成nuget包,然后以便我TaskCore.Test项目中来使用;

如何生成nuget包(win7系统dotnet命令来生成包的过程和下载):

直接在vs中右键您需要打包的类库项目-》选择"在资源管理器中打开文件夹"-》这样就到了您类库的根目录,然后退到类库根目录的上一级文件夹中-》按住键盘”shift"键并同时鼠标右键要打包类库的项目文件件(我这里是TaskCore.Plugin文件夹)-》选择“在此处打开命令窗体” 这个时候就进入了cmd命令窗体,当然有些朋友直接喜欢直接先cmd再来找对应的磁盘,反正我觉得第一种更快点(不同人不同选择吧),下面看下操作截图:

由上图可以看到,通过命令生成了nupkg文件,这文件就是咋们需要在项目中下载安装的TaskCore.Plugin插件包;接下来我们来在TaskCore.Test项目中安装这个插件如下步奏,右键TaskCore.Plugin项目中的“引用”-》选择“管理nuget程序包”-》然后选择右上角的这个图标

-》选择“Nuget包管理器”-》“程序包源”-》

-》然后选择新创建的包源,下面设置如图

这里的“源(S)”指定的本地路径就是刚才我们生成的nupkg文件文件的磁盘(当然我这里是吧刚才pack命令生成的文件复制到了MyNugPackage文件夹中方便测试)-》然后点击”确定“按钮-》然后在返回到

选择我们的包源MyNugPackage-》再浏览这里就能看到我们创建的nuget包了

-》选择并安装-》好安装好后我们可以查看“引用”下面有了如下变化

并且project.json文件中自动添加了依赖项:

好了到我们的TaskCore.Test项目中就可以使用Task.Plugin包里面的方法很类等信息了;

使用TaskCore.MainForm:

由上面的操作TaskCore.Test项目已经安装了Task.Plugin包,那么我们在项目中分别创建3个子类并继承自Task.Plugin包的父类TPlugin并重写方法TPlugin_Load(),对应文件名称分别为:BlogsObj.cs,BlogsObj01.cs,BlogsObj02.cs,分别添加入下代码内容:

BlogsObj.cs:

namespace TaskCore.Test
{
 // This project can output the Class library as a NuGet Package.
 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
 public class BlogsObj : TPlugin
 {
  public BlogsObj()
  {

  }

  public override void TPlugin_Load()
  {
   var sbLog = new StringBuilder(string.Empty);
   try
   {
    sbLog.Append($"这里是BlogsObj,获取配置文件:{this.XmlConfig.Name}");

    //代码块
    //

    new WriteLog()._WriteLog($"{DateTime.Now}测试引用nuget包");

   }
   catch (Exception ex)
   {
    sbLog.Append($"异常信息:{ex.Message}");
   }
   finally
   {

    PublicClass._WriteLog(sbLog.ToString(), this.XmlConfig.Name);
   }
  }
 }
}

BlogsObj01.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TaskCore.Plugin;

namespace TaskCore.Test
{
 // This project can output the Class library as a NuGet Package.
 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
 public class BlogsObj01 : TPlugin
 {
  public BlogsObj01()
  {

  }

  public override void TPlugin_Load()
  {
   var sbLog = new StringBuilder(string.Empty);
   try
   {
    sbLog.Append($"这里是BlogsObj01,获取配置文件:{this.XmlConfig.Name}");

    //代码块
    //
   }
   catch (Exception ex)
   {
    sbLog.Append($"异常信息:{ex.Message}");
   }
   finally
   {
    //Console.WriteLine($"这里是Blogs,获取配置文件:{this.XmlConfig.Name}");
    PublicClass._WriteLog(sbLog.ToString(), this.XmlConfig.Name);
   }
  }
 }
}

BlogsObj02.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TaskCore.Plugin;

namespace TaskCore.Test
{
 // This project can output the Class library as a NuGet Package.
 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
 public class BlogsObj02 : TPlugin
 {
  public BlogsObj02()
  {

  }

  public override void TPlugin_Load()
  {
   //Console.WriteLine($"这里是Blogs,获取配置文件:{this.XmlConfig.Name}");
   PublicClass._WriteLog($"这里是BlogsObj02,获取配置文件:{this.XmlConfig.Name}", this.XmlConfig.Name);
  }
 }
}

好了测试代码写完,咋们生成一下,然后把这个TaskCore.Test.dll拷贝到TaskCore.MainForm运行包中,还需要在PluginXml文件夹中分别创建继承TPlugin的子类的配置文件对应的截图如(注:这里xml配置文件名称必须和子类名称一样):

配置文件内容如BlogsObj.xml:

<!--
 1.xml配置模板
 2.utf-8文件
 3.复制到程序根目录下面PluginXml文件夹下
 4.每个任务建议创建和程序dll名称相同xml配置文件
-->
<TaskMain>
 <!--固定:执行任务时间计时器(分钟)-->
 <Timer>1</Timer>
 <!--固定:任务名称-->
 <Name>获取博客信息</Name>
 <!--固定:账号-->
 <UserName></UserName>
 <!--固定:密码-->
 <UserPwd></UserPwd>
 <!--固定:key-->
 <ApiKey></ApiKey>
 <!--固定:key-->
 <ApiUrl></ApiUrl>
 <!--固定:是否关闭任务 1:是 0:否-->
 <CloseTask>0</CloseTask>

<!--固定:描述-->
 <Des>获取博客信息</Des>
 <!--自定义:其他配置信息-->
 <Other>
 <ShenNiuBuXing3>神牛步行3</ShenNiuBuXing3>
 </Other>
</TaskMain>

最后在CrossFiles.xml配置文件中添加TaskCore.Test.dll文件名称如:

<!--
 CrossFiles指定对应任务的dll文件,必须存在的文件
-->
<TaskMain>
 <File>TaskCore.Test.dll</File>
</TaskMain>

好了完成了,我们在windows开发环境上运行看下效果图:

到这里我们来简单总结下怎么使用TaskCore.MainForm插件,在自己项目中安装TaskCore.Plugin的nuget包-》重写父类TPlugin的TPlugin_Load()方法-》生成自己的项目,拷贝项目的dll到TaskCore.MainForm运行包中-》在运行包中PluginXml文件夹中增加任务子类相同类名的xml文件并配置如上的配置信息-》增加CrossFiles.xml中的任务dll文件配置-》使用命令dotnet TaskCore.MainForm.dll运行服务插件,挺简单的吧

. win7和ubuntu16.04运行TaskCore.MainForm的两种方式和测试截图(也可认为.netcore项目在win7和ubuntu系统运行的两种方式)

由于环境影响,这里跨平台运行测试我只测试win7和ubuntu16.04,其他系统的发布测试希望朋友们在使用过程中得到结果告知我下谢谢;先来讲在win7中运行:

1. 安装了netcore sdk环境的发布运行

安装了sdk后直接可以在cmd命令中dotnet TaskCore.MainForm.dll来运行服务,开篇上面讲解的示例都是在安装了sdk后的截图,服务运行所需要的文件如图:

就只有这些文件(当然程序需要的某些平台依赖项使用的是安装的sdk中的文件,所以看起来很少实际应该包含netcore sdk里面的文件才能运行),通过命令运行的效果图:

2. 未安装netcore sdk环境的发布运行

在为安装sdk平台上系统上运行才是重点,这样才可以说是跨平台;首先,为了更好看效果我们复制一份如图的两个文件到TaskCore.MainForm01文件夹中:

没错,只需要这两个文件,然后我们需要修改project.json文件的内容如下注释的地方:

{
 "version": "1.0.0-*",
 "buildOptions": {
 "emitEntryPoint": true
 },

 "dependencies": {
 "Microsoft.NETCore.App": {
  //"type": "platform", 跨平台发布需要注释
  "version": "1.0.0"
 },
 "System.IO.FileSystem": "4.0.1",
 "System.Reflection": "4.1.0",
 "System.Text.Encoding.CodePages": "4.0.1",
 "System.Threading.Timer": "4.0.1",
 "System.Xml.XDocument": "4.0.11",
 "TaskCore.Plugin": "1.0.0"
 },

 "frameworks": {
 "netcoreapp1.0": {
  "imports": "dnxcore50"
 }
 },
 //跨平台发布需要添加如下节点
 "runtimes": {
 "ubuntu.16.04-x64": { }, //运行在ubuntu.16.04的64位系统
 "win7-x64": { } //运行在win7的64位系统
 }
}

然后使用cmd分别录入并回车运行指令dotnet restore此时TaskCore.MainForm01文件夹中会自动生成一个project.lock.json文件(大家注意看下),然后再录入指令dotnet publish -r win7-x64,可以看到命令窗信息如:

就表示成功了,并且有返回生成运行文件的路径,我们按照路径找到生成的文件publish文件夹,里面没有PluginXml配置文件夹和配置文件和测试项目TaskCore.Test.dll,我们为了方便直接复制上面配置好的配置文件到publish文件夹中如下截图就是生成的发布文件:

没错TaskCore.MainForm01.exe这个就是自动生成的运行文件,然后我们双击运行效果图:

运行成功了,有朋友会问您之前系统不是安装了sdk么,这种测试能算么,我想说的是这个我通过QQ发给qq群里面的朋友@南宫亦琦(不要怪我贴出了您的昵称)测试过了,她没有安装过sdk的;

ubuntu16.04运行:

1. 安装了netcore sdk环境的发布运行

首先,我们需要把在win7上生成的项目复制到ubuntu系统磁盘中(我们使用上面配置好的TaskCore.MainForm包),我这里采用共享目录的方式把文件拷贝到ubuntu系统磁盘上,如图:

然后,鼠标右键点击空白地方,选择“在终端打开”,然后在窗体中录入如下指令dotnet TaskCore.MainForm.dll,能看到如下运行起的结果:

这个命令方式是不是很上面win7上的方式很相同,本来就是一样的,只要安装了.netcore sdk这种方式几乎可以共用

2. 未安装netcore sdk环境的发布运行

不安装sdk环境运行才是咋们需要关注的,下面就来看下怎么生成再ubuntu系统上能运行的文件;我们复制一份上面的TaskCore.MainForm01项目到TaskCore.MainForm02中来测试,由于之前我们在讲生成win7执行文件时候,执行了命令dotnet restore和dotnet publish -r win7-x64命令所以文件中有project.lock和bin文件夹,为了测试我们需要删除掉部分文件,只剩下如图文件,这里需要注意的是之前已经配置过project.xml我们无需在修改了:

然后,分别执行和生成win7运行文件几乎相同的命令dotnet restore和dotnet publish -r ubuntu.16.04-x64不同之处在于生成的文件存放的位置不同和使用的运行环境不同,运行结果如图:

publish文件夹中的文件就是在ubuntu系统执行的文件,然后我们需要把任务配置文件夹PluginXml和测试项目TaskCore.Test.dll复制到该目录中,再来咋们通过共享吧TaskCore.MainForm02目录中的publish复制到ubuntu中;然后我们需要把TaskCore.MainForm02可执行文件设置下权限,鼠标右键点击TaskCore.MainForm02可执行文件,选择“属性”,再选择“权限”选项卡,勾选“允许作为程序执行”,如图:

然后,我们右键文件夹中空白处,选择“在终端打开”,再执行如下命令./TaskCore.MainForm02,最后看运行效果图:

好了,发布在ubuntu系统上执行文件和运行的步奏就这些,几乎和win7上相同

. 框架代码解读及感悟

怎么使用跨平台TaskCore.MainForm任务框架讲解完了,下面来具体看下主要代码Program.cs文件中:

namespace TaskCore.MainForm
{
 /// <summary>
 /// author 神牛步行3
 /// contact 841202396@qq.com
 /// des TaskCore.MainForm跨平台插件由神牛步行3提供
 /// </summary>
 public class Program
 {

  private static Dictionary<string, MoAssembly> dicTasks = new Dictionary<string, MoAssembly>();

  public static void Main(string[] args)
  {
   //注册编码,防止乱码
   Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

   //初始化程序集文件
   _Init();

   //是否继续开启任务,默认没有待执行任务,不提示
   if (dicTasks.Count <= 0) { _LoopAlert("是否退出?(Y/N)"); return; }
   _LoopAlert("是否开始执行任务?(Y / N)");

   //执行任务
   foreach (var item in dicTasks.Values)
   {
    //使用Task防止异常后相互影响
    Task.Run(() =>
    {
     try
     {

      //创建任务对象
      var tp = item.Asm.CreateInstance(item.FullName) as TPlugin;
      if (!string.IsNullOrEmpty(tp.XmlConfig.TpError)) { _Alert($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{tp.XmlConfig.Name} - 异常信息:{tp.XmlConfig.TpError}"); }
      else
      {

       //timer定时器
       var timer = new Timer((param) =>
       {
        var msg = $"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{tp.XmlConfig.Name}";
        try
        {
         var tpObj = param as TPlugin;
         //是否关闭暂停任务
         if (tpObj.XmlConfig.CloseTask) { return; }
         _Alert($"{msg} - 开始执行...{tp.XmlConfig.Timer}分钟一次");
         //任务入口
         tpObj.TPlugin_Load();
        }
        catch (Exception ex) { _Alert($"{msg} - 异常信息:{ex.Message}"); }
       }, tp, 0, 1000 * 60 * tp.XmlConfig.Timer);
      }

     }
     catch (Exception ex)
     {
      _Alert($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{item.Name} - 异常信息:{ex.Message}");
     }
    });
   }
   _LoopAlert("正在监控执行的任务,是否退出?(Y / N)");
  }

  /// <summary>
  /// 初始化程序集文件
  /// </summary>
  private static void _Init()
  {
   try
   {

    _Alert("初始化任务中...");
    //获取文件
    var files = PublicClass._GetPluginFile("");
    if (files.Length <= 0) { _Alert("未能找到可用的程序集,请检查配置"); return; }

    //读取任务文件
    _Alert("读取CrossFiles.xml配置中...");
    var baseAddr = Path.Combine(Directory.GetCurrentDirectory(), "PluginXml", "CrossFiles.xml");
    var doc = XDocument.Load(baseAddr);
    var fileables = files.AsEnumerable();
    var taskFiles = new List<FileInfo>();
    foreach (var item in doc.Root.Nodes())
    {
     var crossFile = item.ToString().ToUpper();
     var choiceFiles = fileables.Where(b => crossFile.Contains(b.Name.ToUpper()));
     if (!choiceFiles.Any()) { continue; }

     taskFiles.AddRange(choiceFiles);
    }

    //展示文件信息
    _Alert($"待遍历{taskFiles.Count}个文件信息...");
    foreach (var item in taskFiles.OrderBy(b => b.CreationTime))
    {
     var asmName = new AssemblyName($"{item.Name.Replace(".dll", "")}");
     Assembly sm = Assembly.Load(asmName);
     if (sm == null) { continue; }
     var ts = sm.GetTypes();
     //判断特定的任务类,加入任务dic
     foreach (var t in ts.Where(b => b.Name != "TPlugin" && b.GetMethod("TPlugin_Load") != null))
     {

      dicTasks.Add(
       t.FullName,
       new MoAssembly
       {
        Asm = sm,
        FullName = t.FullName,
        Name = t.Name
       });
     }
    }
    _Alert($"获取待执行任务量:{dicTasks.Count}个");
   }
   catch (Exception ex)
   {
    _Alert($"异常信息:{ ex.Message}");
   }
  }

  /// <summary>
  /// 消息提醒
  /// </summary>
  /// <param name="msg">提示信息</param>
  /// <param name="isReadLine">是否需要用户输入指令</param>
  /// <returns>用户录入的指令</returns>
  private static string _Alert(string msg = "神牛步行3-消息提醒", bool isReadLine = false)
  {
   Console.WriteLine(msg);
   if (isReadLine) { return Console.ReadLine(); }
   return "";
  }

  private static void _LoopAlert(string msg = "是否开始执行任务?(Y/N)")
  {
   do
   {
    var readKey = _Alert(msg, true);
    if (readKey.ToUpper().Contains("Y")) { break; }
   } while (true);
  }
 }

 public class MoAssembly
 {
  public Assembly Asm { get; set; }
  public string FullName { get; set; }

  public string Name { get; set; }
 }
}

TPlugin.cs文件中代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace TaskCore.Plugin
{
 /// <summary>
 /// 插件基类
 /// </summary>
 public class TPlugin : IDisposable
 {

  public TPlugin()
  {

   XmlConfig = _InitConfig();
  }

  #region 初始化Xml配置文件 _InitConfig +XmlConfig

  /// <summary>
  /// xml配置信息
  /// </summary>
  public XmlConfig XmlConfig;

  /// <summary>
  /// 初始化配置信息
  /// </summary>
  /// <param name="configPath">配置文件对应路径</param>
  /// <returns></returns>
  public virtual XmlConfig _InitConfig(string configPath = "")
  {
   XmlConfig config = new XmlConfig();
   config.Timer = 1;
   config.Name = this.GetType().Name;
   try
   {

    if (string.IsNullOrEmpty(configPath))
    {

     //默认各个dllXml配置
     var defaultConfigFolder = "PluginXml";
     var baseAddr = Directory.GetCurrentDirectory();
     configPath = Path.Combine(baseAddr, defaultConfigFolder, config.Name + ".xml");
    }

    var doc = XDocument.Load(configPath);
    config.doc = doc;
    var taskMain = doc.Root;

    config.Timer = Convert.ToInt32(taskMain.Element(XName.Get("Timer", "")).Value);
    config.Name = taskMain.Element(XName.Get("Name", "")).Value;
    config.Des = taskMain.Element(XName.Get("Des", "")).Value;

    config.UserName = taskMain.Element(XName.Get("UserName", "")).Value;
    config.UserPwd = taskMain.Element(XName.Get("UserPwd", "")).Value;
    config.ApiKey = taskMain.Element(XName.Get("ApiKey", "")).Value;
    config.ApiUrl = taskMain.Element(XName.Get("ApiUrl", "")).Value;
    config.CloseTask = taskMain.Element(XName.Get("CloseTask", "")).Value == "1";

   }
   catch (Exception ex)
   {
    config.TpError = ex.Message;
    PublicClass._WriteLog($"{config.Name}初始化配置信息异常:{ex.Message}", "BaseLog");
    throw new Exception(ex.Message);
   }
   return config;
  }
  #endregion

  #region 初始化-开始加载 _Load

  /// <summary>
  /// 初始化-开始起
  /// </summary>
  public virtual void TPlugin_Load()
  {

   PublicClass._WriteLog("测试");
  }

  #endregion

  #region 释放资源

  public void Dispose()
  {

   GC.SuppressFinalize(this);//不需要再调用本对象的Finalize方法
  }

  public virtual void Dispose(Action action)
  {

   action();
  }

  #endregion
 }

 #region 配置文件 XmlConfig

 public class XmlConfig
 {
  public XmlConfig()
  {

  }

  /// <summary>
  /// 定制器时间(分钟)
  /// </summary>
  public int Timer { get; set; }

  /// <summary>
  /// 运行名称
  /// </summary>
  public string Name { get; set; }

  /// <summary>
  /// 描述(第一次获取dll描述,后面获取xml配置文件描述)
  /// </summary>
  public string Des { get; set; }

  /// <summary>
  /// 接口账号
  /// </summary>
  public string UserName { get; set; }

  /// <summary>
  /// 接口密码
  /// </summary>
  public string UserPwd { get; set; }

  /// <summary>
  /// 接口秘钥
  /// </summary>
  public string ApiKey { get; set; }

  /// <summary>
  /// 接口地址
  /// </summary>
  public string ApiUrl { get; set; }

  /// <summary>
  /// 是否关闭任务
  /// </summary>
  public bool CloseTask { get; set; }

  /// <summary>
  /// 插件中错误
  /// </summary>
  public string TpError { get; set; }

  /// <summary>
  /// xml信息
  /// </summary>
  public XDocument doc { get; set; }
 }

 #endregion
}

具体的说明和逻辑处理代码中都有注释,各位可以详细看下;这里要诉说的是该框架主要原理是动态加载任务dll来创建对象,netcore的程序集类Assembly不像framework里面的Assembly一样那么多可以用方法,我这里用的Assembly.Load(),netcore只能加载当前系统根目录的dll(这里我花了几个小时测试,有不同结果的朋友,请及时联系我谢谢),框架使用Task.Run()方法创建不同任务,实现并行执行的效果,并且各个容易出错地方使用try...catch来容错,避免了某个子任务异常后,导致框架全部中断运行,个人觉得其实还是不错的是吧;

下面给出几个不同环境下的压缩包,以供使用和参考:

TaskCore.MainForm-纯文件 TaskCore.MainForm01 git源码地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 简单谈谈.NET Core跨平台开发

    对于.NET开源计划想必关注的人已经跃跃欲试了,但是真正将其用于开发的目前来说不多.毕竟截至本文发布时.NET Core才发布到1.0RC2版本.正式版预计还有一段时间.况且大多数人都是持观望态度,就算开发仍然用的还是.NET Framework.另外不得不说的一点就是.NET开源的进度很惊人但是社区建设还有待提升,很多配套的东西还不齐全.Java在语言层级上可能落后.NET但是Java的社区力量是.NET远不及的. 一.安装SDK .NET Core发布版:https://www.micros

  • Asp.NetCore1.1版本去掉project.json后如何打包生成跨平台包

    本章将要和大家分享的是Asp.NetCore1.1版本去掉了project.json后如何打包生成跨平台包, 为了更好跟进AspNetCore的发展,把之前用来做netcore开发的vs2015卸载后并安装了vs2017,这给我带来的直接好处是把我报红的C盘腾出10GB左右的空间,从这里直接能感受到vs2017体积如此之小:之前有写过一篇开源netcore服务的文章开源一个跨平台运行的服务插件 - TaskCore.MainForm,里面有讲述netcore项目生成和部署在win7和ubuntu

  • 开源跨平台运行服务插件TaskCore.MainForm

    本次将要很大家分享的是一个跨平台运行的服务插件 - TaskCore.MainForm,此框架是使用.netcore来写的,现在netcore已经支持很多系统平台运行了,所以将以前的Task.MainForm改良成跨平台的服务共大家使用和相互交流:本来这篇应该分享的是nginx+iis+redis+Task.MainForm构建分布式架构后续文章,但使用.netcore来定义一个服务插件和跨平台测试经过让我既兴奋又头痛,不说了下次再分享分布式后续文章吧:那么开始今天的分享内容,希望各位多多支持:

  • Android编程获取手机后台运行服务的方法

    本文实例讲述了Android编程获取手机后台运行服务的方法.分享给大家供大家参考,具体如下: public static String getRunningServicesInfo(Context context) { StringBuffer serviceInfo = new StringBuffer(); final ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.A

  • Android实现Service在前台运行服务

    前言 在做手机音乐播放器的时候,让我非常苦恼的一件事就是手机有清理内存的软件,比如百度,360等等,一点击清理音乐就停止播放了,去后台查看发现Service已经被停止并重新启动了,这显然不是我想要的,我希望音乐能够在后台播放,并且自己能控制什么时候退出,不想让系统给我清理了,就像酷狗一直在通知栏显示那样,于是我就知道了在前台运行的服务. 实现 我们先看一下结果图: 这是运行在通知栏的界面,这样就是让服务在前台运行,再清理的时候就不会导致服务被关闭了. 好了,我们直接上代码,因为要开启服务,所以我

  • IntelliJ IDEA安装运行python插件方法

    IDEA 工具是我们常用的开发工具,全称:IntelliJ IDEA,它的功能强大就在于我们可以添加各种插件来编写不同的代码,当然也可以用来编写python,这篇文章我们来讲解,如何用IDEA来安装python插件,以及运行python 1.首先打开IDEA,然后找到Configure 2.点击后,我们可以看到Plugins,也就是插件的意思,然后点击 3.在搜索框中,我们输入python,会提示我们没有找到该插件 4.然后点击search in repositories(在仓库里搜索),我们就

  • 关于Vue项目跨平台运行问题的解决方法

    记录一下踩坑 前几天,从同事手上接手了一个Vue的项目.(Ps:刚入职两周,老哥还专门写了一个readMe,感谢): 问题来了,从gitLab上面把项目上clone下来了,node环境什么的都配置好了, npm install npm run dev 无法运行,报错信息如下: > NODE_ENV=development webpack-dev-server --open --inline --hot   'NODE_ENV' 不是内部或外部命令,也不是可运行的程序 或批处理文件. npm ER

  • 如何使用VSCode 运行调试插件代码

    VSCode 运行插件,现在我们对这个插件的实现方式和注册方式已经有了了解,下面就到了运行和调试代码的时候了.VS Code 的插件代码脚手架已经为我们提供了 launch.json ,所以我们只需要按下 F5 即可启动代码. 代码启动后,VS Code 会打开一个新的窗口,这个窗口中就运行着我们本地书写的代码.此时我们打开命令面板,搜索 "Hello World" 并且执行. 上面我提到了,这个插件只有在 "Hello World" 命令被执行时才会被激活.那下面

  • C#开发Windows服务实例之实现禁止QQ运行

    本实例主要实现下面三个基本功能 1.C#开发windows服务 2.禁止QQ等程序运行 3.为windows服务创建自动安装程序 下面针对这三个基本功能进行实现 一.C#开发windows服务 Windows服务在VS以前的版本中叫NT服务,在VS.NET启用了新的名称.用C#创建windows服务不是一件困难的事,下页针对服务创建.启动.停止做详细介绍 1.首先在vs中添加一winform程序KillService 2.在解决方案添加新项中添加Windows服务 3.打开服务页面,切换至代码页

  • 基于.NET平台常用的框架和开源程序整理

    自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就继续补充这篇日志,日积月累,就能形成一个自己的组件经验库. 分布式缓存框架: Microsoft Velocity:微软自家分布式缓存服务框架. Memcahed:一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度. Redis:是一个高性能的KV数据库. 它的出现很大程度补偿了Mem

  • Elasticsearch插件及nodejs的安装配置

    目录 Elasticsearch插件介绍 核心插件 第三方插件 插件安装 第一种:命令行 第二种:url安装 第三种:离线安装 安装nodejs 一 nodejs介绍 二 查看原来的镜像地址 三 npm切换阿里源 四 安装cmpm 五 改变原有的环境变量 Elasticsearch插件介绍 es插件是一种增强Elasticsearch核心功能的途径.它们可以为es添加自定义映射类型.自定义分词器.原生脚本.自伸缩等等扩展功能. es插件包含JAR文件,也可能包含脚本和配置文件,并且必须在集群中的

随机推荐