Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to open source and run the service plug-in TaskCoreMainForm across platforms

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

In this issue, the editor will bring you about how to open source cross-platform service plug-in TaskCoreMainForm. The article is rich in content and analyzes and describes for you from a professional point of view. I hope you can get something after reading this article.

. Introduction of frame structure and running effect diagram

First of all, let's take a look at the project directory structure of the project source code as shown in the figure:

The structure should be clear enough, and the number of source code files is very small, but it does implement the dynamic loading of assembly dll to execute the task. The corresponding screenshot of execution will be given later. Let's take a look at the files in the Bin folder after the TaskCore.MainForm project is generated through vs2015 as shown below:

If you have installed .netcore sdk, you only need the above screenshot file to run the plug-in on windows; then we can execute the following command dotnet TaskCore.MainForm.dll on the win7 system that has already installed core sdk to see the effect shown in the figure:

Yes, this is the effect of the plug-in running, because .netcore currently does not provide a skin interface effect similar to winform, so you can only run programs across platforms through the command line.

. How to generate nuget packages and use TaskCore.MainForm

First of all, we need to make it clear that the service is made up of two parts (TaskCore.MainForm and TaskCore.Plugin); TaskCore.MainForm is mainly used to run programs, and TaskCore.Plugin is used as a parent plug-in for child tasks to inherit After we download the TaskCore.MainForm runtime package (see the structure in figure 2), all we need to do is to inherit the TPlugin class in TaskCore.Plugin.dl to rewrite our task content, so we create a new project named TaskCore.Test, and then we directly add the TaskCore.Plugin.dl reference in the TaskCore.MainForm runtime package through the vs2015 reference function, which will prompt an error:

The error means that the netcore version of dll cannot be loaded, so adding dll dependencies by referencing directly in the vs project is not good. You need to add dependency packages through nuget. (currently, references to class libraries by .netcore can only be installed through nuget, which requires attention), so I use the TaskCore.Plugin project to generate the nuget package through the dotnet pack command so that I can use it in my TaskCore.Test project.

How to generate nuget packages (the process and download of the win7 system dotnet command to generate packages):

Right-click the class library project you need to package directly in vs-"Select" Open folder in Explorer-"this will take you to the root directory of your class library. Then go back to the folder one level above the root directory of the class library-"hold down the keyboard" shift key and right mouse button at the same time to package the project file of the class library (here is the TaskCore.Plugin folder)-"Select" to open the command form here "will enter the cmd command form. Of course, some friends directly like to cmd first and then find the corresponding disk. Anyway, I think the first one is faster (different people choose it). Take a look at the screenshot of the operation:

As you can see from the above figure, the nupkg file is generated through the command, which is the TaskCore.Plugin plug-in package that we need to download and install in the project. Next, let's install the plug-in in the TaskCore.Test project by right-clicking "references"-"Select" manage nuget packages "-" in the TaskCore.Plugin project, and then select the icon in the upper right corner.

-"Select" Nuget package Manager "-" package Source "-"

"then select the newly created package source, as shown in the figure below

The local path specified by the "source (S)" here is the disk of the nupkg file we just generated (of course I copy the file generated by the pack command to the MyNugPackage folder for testing)-"then click the" OK "button-and then return to the

Select our package source MyNugPackage- "and browse here to see the nuget package we created."

-"Select and install -" after installation, we can check the "reference" and the following changes have been made

And dependencies are automatically added to the project.json file:

All right, when you get to our TaskCore.Test project, you can use the methods in the Task.Plugin package and other information.

Use TaskCore.MainForm:

The Task.Plugin package has been installed in the above operation TaskCore.Test project, so we create three subclasses in the project and inherit them from the parent class TPlugin of the Task.Plugin package and rewrite the method TPlugin_Load (). The corresponding file name is: BlogsObj.cs,BlogsObj01.cs,BlogsObj02.cs. Add the following code content:

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 ($"here is BlogsObj, get configuration file: {this.XmlConfig.Name}"); / / code block / / new WriteLog (). _ WriteLog ($"{DateTime.Now} test reference nuget package") } catch (Exception ex) {sbLog.Append ($"exception message: {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 ($"here is BlogsObj01, get configuration file: {this.XmlConfig.Name}"); / / code block / /} catch (Exception ex) {sbLog.Append ($"exception message: {ex.Message}") } finally {/ / Console.WriteLine ($"here is Blogs, get configuration file: {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 ($"here is Blogs, get configuration file: {this.XmlConfig.Name}"); PublicClass._WriteLog ($"here is BlogsObj02, get configuration file: {this.XmlConfig.Name}", this.XmlConfig.Name);}

All right, after the test code is written, let's generate it, and then copy the TaskCore.Test.dll to the TaskCore.MainForm runtime package. We also need to create screenshots corresponding to the configuration files of the subclasses inheriting TPlugin in the PluginXml folder (Note: here the xml configuration file name must be the same as the subclass name):

Configuration file content such as BlogsObj.xml:

1 get blog information 0 get blog information Shenniu Walk 3

Finally, add the TaskCore.Test.dll file name to the CrossFiles.xml configuration file, such as:

TaskCore.Test.dll

All right, let's run it on the windows development environment and take a look at the effect diagram:

Here we briefly summarize how to use the TaskCore.MainForm plug-in to install TaskCore.Plugin 's nuget package-"override the TPlugin_Load () method of the parent class TPlugin -" in your own project to build your own project. Copy the dll of the project to the TaskCore.MainForm runtime package-"add the xml file of the task subclass with the same class name in the PluginXml folder in the runtime package and configure the configuration information as above -" add the task dll file configuration in CrossFiles.xml-"use the command dotnet TaskCore.MainForm.dll to run the service plug-in, isn't it?

. Two ways for win7 and ubuntu16.04 to run TaskCore.MainForm and test screenshots (it can also be considered that .netcore projects run in win7 and ubuntu systems)

Due to the impact of the environment, I only test win7 and ubuntu16.04 for cross-platform running tests. For release tests of other systems, I hope my friends will let me know when they use the results. Let's first run them in win7:

1. Release run with netcore sdk environment installed

After installing sdk, you can directly run the service by dotnet TaskCore.MainForm.dll in the cmd command. The examples described above are all screenshots after installing sdk. The files required for service operation are shown in the figure:

Only these files (of course, some platform dependencies required by the program use files from the installed sdk, so it seems that very few files should actually contain files in netcore sdk to run), run through the command:

two。 Release run of uninstalled netcore sdk environment

It is important to run on the system to install the sdk platform, so that it can be said to be cross-platform. First of all, in order to get a better effect, let's copy the two files shown in the figure to the TaskCore.MainForm01 folder:

Yes, only these two files are needed, and then we need to modify the contents of the project.json file as follows:

{"version": "1.0.0 true *", "buildOptions": {"emitEntryPoint": true}, "dependencies": {"Microsoft.NETCore.App": {/ / "type": "platform". Cross-platform publishing requires notes "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"}} / / Cross-platform publishing requires adding the following node "runtimes": {"ubuntu.16.04-x64": {}, / / 64-bit system running on ubuntu.16.04 "win7-x64": {} / / 64-bit system running on win7}}

Then use cmd to enter and enter the instructions to run dotnet restore. At this time, a project.lock.json file will be automatically generated in the TaskCore.MainForm01 folder (please note below), and then enter the instruction dotnet publish-r win7-x64. You can see the command window information such as:

It means it is successful, and there is a path to return the generated running file. We follow the path to find the generated file publish folder, where there is no PluginXml configuration folder and configuration file and test project TaskCore.Test.dll. To facilitate copying the above configured configuration file directly to the publish folder, the screenshot below is the generated release file:

Yes, TaskCore.MainForm01.exe, this is the automatically generated run file, and then we double-click the run image:

Run successfully, some friends will ask you before the system is not installed SDK, this kind of test can count, what I want to say is that I sent this through QQ to my friend in QQ group @ Nangong Yiqi (don't blame me for posting your nickname) has tested, she has not installed sdk.

Ubuntu16.04 runs:

1. Release run with netcore sdk environment installed

First, we need to copy the project generated on win7 to the ubuntu system disk (we use the TaskCore.MainForm package configured above). Here, I copy the files to the ubuntu system disk in a shared directory, as shown in the figure:

Then, click the right mouse button in the blank space, select "Open in Terminal", and enter the following instruction dotnet TaskCore.MainForm.dll in the form. You can see the following running results:

Is the way of this command very much the same on win7? it is the same, as long as it is installed. netcore sdk this way can almost be shared.

two。 Release run of uninstalled netcore sdk environment

We need to pay attention to running without installing sdk environment. Let's take a look at how to generate files that can run on the ubuntu system. We copied a copy of the above TaskCore.MainForm01 project to TaskCore.MainForm02 for testing. Since we executed the commands dotnet restore and dotnet publish-r win7-x64 commands when we were talking about generating the win7 execution file, there are project.lock and bin folders in the file. In order to test, we need to delete some of the files, leaving only the file as shown in the figure. It is important to note that project.xml has been configured before and we do not need to modify it:

Then, execute and generate win7 running files with almost the same commands dotnet restore and dotnet publish-r ubuntu.16.04-x64. The difference is that the generated files are stored in different locations and in different running environments. The running result is as shown in the figure:

The files in the publish folder are the files executed on the ubuntu system. Then we need to copy the task configuration folder PluginXml and the test project TaskCore.Test.dll to this directory, and then we can copy the publish in the TaskCore.MainForm02 directory to ubuntu by sharing it. Then we need to set the permissions for the TaskCore.MainForm02 executable file, right-click on the TaskCore.MainForm02 executable file, select "Properties", select the "permissions" tab, and check "allow execution as a program", as shown in the figure:

Then, we right-click the blank space in the folder, select "Open in Terminal", then execute the following command. / TaskCore.MainForm02, and finally look at the running effect:

All right, release the steps for executing files and running on ubuntu systems, almost the same as on win7.

. Interpretation and perception of frame Code

After explaining how to use the cross-platform TaskCore.MainForm task framework, let's take a look at the main code Program.cs file:

Namespace TaskCore.MainForm {/ author Shenniu Walk 3 / contact 841202396@qq.com / des TaskCore.MainForm cross-platform plug-in provided by Shenniu Walk 3 / public class Program {private static Dictionary dicTasks = new Dictionary (); public static void Main (string [] args) {/ / register code to prevent garbled Encoding.RegisterProvider (CodePagesEncodingProvider.Instance); / / initialize assembly file _ Init () / / whether to continue to open the task. By default, there are no tasks to be executed, and if is not prompted (dicTasks.Count {try {/ / create task object 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}-exception message: {tp.XmlConfig.TpError}") } else {/ / timer 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; / / whether to close the paused task if (tpObj.XmlConfig.CloseTask) {return } _ Alert ($"{msg}-start execution... {tp.XmlConfig.Timer} minute"); / / Task entry tpObj.TPlugin_Load ();} catch (Exception ex) {_ Alert ($"{msg}-exception message: {ex.Message}");}}, tp, 0, 1000 * 60 * tp.XmlConfig.Timer) }} catch (Exception ex) {_ Alert ($"{DateTime.Now.ToString (" yyyy/MM/dd HH:mm ")}: {item.Name}-exception message: {ex.Message}";}});} _ LoopAlert ("monitoring the task being executed, do you want to exit? (y / N) "); initialize the assembly file / private static void _ Init () {try {_ Alert (" initializing task... "); / / get the file var files = PublicClass._GetPluginFile ("); if (files.Length crossFile.Contains (b.Name.ToUpper (); if (! choiceFiles.Any ()) {continue } taskFiles.AddRange (choiceFiles);} / / display file information _ Alert ($"to traverse {taskFiles.Count} file information."); 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 (); / / determine the specific task class and add the task 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 ($"get the number of tasks to be executed: {dicTasks.Count}");} catch (Exception ex) {_ Alert ($"exception message: {ex.Message}") } / message reminder / prompt message / whether the user input instruction / user input instruction private static string _ Alert (string msg = "Shenniu Walking 3-message reminder", bool isReadLine = false) {Console.WriteLine (msg); if (isReadLine) {return Console.ReadLine ();} return "" } private static void _ LoopAlert (string msg = "do you want to start the task? ) {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;}

The code in the TPlugin.cs file:

Using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Threading.Tasks;using System.Xml.Linq;namespace TaskCore.Plugin {/ plug-in base class / public class TPlugin: IDisposable {public TPlugin () {XmlConfig = _ InitConfig ();} # region initializes the Xml configuration file _ InitConfig + XmlConfig / xml configuration Information / public XmlConfig XmlConfig / initialize configuration information / public virtual XmlConfig _ InitConfig (string configPath = ") {XmlConfig config = new XmlConfig (); config.Timer = 1; config.Name = this.GetType (). Name; try {if (string.IsNullOrEmpty (configPath)) {/ / default each dllXml configuration 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} initialization configuration information exception: {ex.Message} "," BaseLog "); throw new Exception (ex.Message);} return config } # endregion # region initialization-start loading _ Load / initialization-start / public virtual void TPlugin_Load () {PublicClass._WriteLog ("test");} # endregion # region release resource public void Dispose () {GC.SuppressFinalize (this); / / there is no need to call this object's Finalize method} public virtual void Dispose (Action action) {action () } # endregion} # region profile XmlConfig public class XmlConfig {public XmlConfig () {} / customizer time (minutes) / public int Timer {get; set;} / run name / public string Name {get; set } / description (get dll description for the first time, then get xml profile description later) / public string Des {get; set;} / Interface account / public string UserName {get; set;} / Interface password / public string UserPwd {get; set } / Interface key / public string ApiKey {get; set;} / public string ApiUrl {get; set;} / whether to close the task / public bool CloseTask {get; set;} / error / public string TpError {get; set in the plug-in } / xml Information / public XDocument doc {get; set;}} # endregion}

There are comments in the specific instructions and logic processing code, which you can take a closer look at. What I want to talk about here is that the main principle of the framework is to dynamically load the task dll to create objects. Netcore's assembly class Assembly does not have as many methods as Assembly in framework. The Assembly.Load () I use here, netcore can only load the dll of the current system root directory (here I have spent several hours testing, friends with different results, please contact me in time. Thank you), the framework uses the Task.Run () method to create different tasks. To achieve the effect of parallel execution, and various error-prone places to use try...catch for fault tolerance, to avoid the exception of a subtask, resulting in a complete interruption of the framework, personally, I think it's actually good, right?

Here are several compression packages in different environments for use and reference:

TaskCore.MainForm- pure file TaskCore.MainForm01 git source code address

This is how the editor shared how to open source the service plug-in TaskCoreMainForm across platforms. If you happen to have similar doubts, please refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report