diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/.gitignore b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/.gitignore
new file mode 100644
index 00000000..96d33b94
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/.gitignore
@@ -0,0 +1,10 @@
+.vscode
+node_modules
+dist
+*.db-journal
+package-lock.json
+DatabaseUtils\bin
+DatabaseUtils\obj
+build
+./src/assets/dbUtil
+.vs
\ No newline at end of file
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/DatabaseUtils.cs b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/DatabaseUtils.cs
new file mode 100644
index 00000000..7577292d
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/DatabaseUtils.cs
@@ -0,0 +1,53 @@
+using Microsoft.Data.Sqlite;
+using MongoDB.Bson;
+using MongoDB.Driver;
+using MySql.Data.MySqlClient;
+using Npgsql;
+using System;
+using System.Data.SqlClient;
+using System.Globalization;
+using System.IO;
+
+namespace DatabaseUtils
+{
+ ///
+ /// Database utility functions
+ ///
+ public static class DatabaseUtils {
+ ///
+ /// Test connection string is correct
+ ///
+ /// Database
+ /// Connection string
+ public static void TestConnectionString(string database, string connectionString) {
+ if (string.Compare(database, "MSSQL", true, CultureInfo.InvariantCulture) == 0) {
+ using (var connection = new SqlConnection(connectionString)) {
+ connection.Open();
+ }
+ } else if (string.Compare(database, "MySQL", true, CultureInfo.InvariantCulture) == 0) {
+ using (var connection = new MySqlConnection(connectionString)) {
+ connection.Open();
+ }
+ } else if (string.Compare(database, "PostgreSQL", true, CultureInfo.InvariantCulture) == 0) {
+ using (var connection = new NpgsqlConnection(connectionString)) {
+ connection.Open();
+ }
+ } else if (string.Compare(database, "SQLite", true, CultureInfo.InvariantCulture) == 0) {
+ var tempDir = Path.GetDirectoryName(Path.GetTempPath());
+ connectionString = connectionString.Replace("{{App_Data}}", tempDir);
+ using (var connection = new SqliteConnection(connectionString)) {
+ connection.Open();
+ }
+ } else if (string.Compare(database, "InMemory", true, CultureInfo.InvariantCulture) == 0) {
+ // Do nothing
+ } else if (string.Compare(database, "MongoDB", true, CultureInfo.InvariantCulture) == 0) {
+ var mongoUrl = new MongoUrl(connectionString);
+ var mongoDatabase = new MongoClient(mongoUrl).GetDatabase(mongoUrl.DatabaseName);
+ mongoDatabase.ListCollections().ToBsonDocument();
+ } else {
+ throw new ArgumentException(
+ $"Unsupported database {database}, please check it yourself");
+ }
+ }
+ }
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/DatabaseUtils.csproj b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/DatabaseUtils.csproj
new file mode 100644
index 00000000..99b3d7e4
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/DatabaseUtils.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Exe
+ netcoreapp2.0
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/Program.cs b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/Program.cs
new file mode 100644
index 00000000..7842e0ca
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/DatabaseUtils/Program.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DatabaseUtils
+{
+ static class Program
+ {
+ static void Main(string[] args)
+ {
+ if (args.Length==2)
+ {
+ var dbtype = args[0];
+ var connectionString = args[1];
+ DatabaseUtils.TestConnectionString(dbtype, connectionString);
+ }
+ else
+ {
+ throw new ArgumentException();
+ }
+
+ }
+ }
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/helpers.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/helpers.js
new file mode 100644
index 00000000..2ba024e2
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/helpers.js
@@ -0,0 +1,9 @@
+var path = require("path");
+var _root = path.resolve(__dirname, "..");
+
+function root(args) {
+ args = Array.prototype.slice.call(arguments, 0);
+ return path.join.apply(path, [_root].concat(args));
+}
+
+exports.root = root;
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma-dummy.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma-dummy.js
new file mode 100644
index 00000000..e69de29b
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma-test-shim.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma-test-shim.js
new file mode 100644
index 00000000..4fe8b6d4
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma-test-shim.js
@@ -0,0 +1,21 @@
+Error.stackTraceLimit = Infinity;
+
+require("core-js/es6");
+require("core-js/es7/reflect");
+
+require("zone.js/dist/zone");
+require("zone.js/dist/long-stack-trace-zone");
+require("zone.js/dist/proxy");
+require("zone.js/dist/sync-test");
+require("zone.js/dist/jasmine-patch");
+require("zone.js/dist/async-test");
+require("zone.js/dist/fake-async-test");
+
+var appContext = require.context("../src", true, /\.spec\.ts/);
+
+appContext.keys().forEach(appContext);
+
+var testing = require("@angular/core/testing");
+var browser = require("@angular/platform-browser-dynamic/testing");
+
+testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma.conf.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma.conf.js
new file mode 100644
index 00000000..1cbc522d
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/karma.conf.js
@@ -0,0 +1,52 @@
+var webpackConfig = require("./webpack.test");
+
+module.exports = function (config) {
+ var _config = {
+ basePath: "",
+
+ frameworks: ["jasmine"],
+ browserNoActivityTimeout: 0,
+
+ files: [
+ { pattern: "./karma-dummy.js", watched: false }, // For some reason an empty file is required
+ { pattern: "./karma-test-shim.js", watched: false },
+ ],
+
+ preprocessors: {
+ "./karma-dummy.js": ["electron"], // And dummy file must be preprocessed too
+ "./karma-test-shim.js": ["electron", "webpack", "sourcemap"],
+ },
+
+ webpack: webpackConfig,
+
+ webpackMiddleware: {
+ stats: "errors-only"
+ },
+
+ webpackServer: {
+ noInfo: true
+ },
+
+ reporters: ["spec"],
+ specReporter: {
+ maxLogLines: 3, // limit number of lines logged per test
+ suppressErrorSummary: true, // do not print error summary
+ suppressFailed: false, // do not print information about failed tests
+ suppressPassed: false, // do not print information about passed tests
+ suppressSkipped: false, // do not print information about skipped tests
+ showSpecTiming: false // print the time elapsed for each spec
+ },
+
+ port: 9876,
+ colors: true,
+ logLevel: config.LOG_INFO,
+ autoWatch: false,
+ browsers: ["Electron"],
+ singleRun: true,
+ client: {
+ useIframe: false,
+ },
+ };
+
+ config.set(_config);
+};
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.common.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.common.js
new file mode 100644
index 00000000..f32ba696
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.common.js
@@ -0,0 +1,112 @@
+var path = require("path");
+var webpack = require("webpack");
+var HtmlWebpackPlugin = require("html-webpack-plugin");
+var ExtractTextPlugin = require("extract-text-webpack-plugin");
+var CopyWebpackPlugin = require("copy-webpack-plugin");
+var helpers = require("./helpers");
+
+module.exports = {
+ entry: {
+ "polyfills": "./src/polyfills.ts",
+ "vendor": "./src/vendor.ts",
+ "app": "./src/main.ts"
+ },
+
+ resolve: {
+ extensions: [".ts", ".js"]
+ },
+
+ externals: {
+ sqlite3: "commonjs sqlite3",
+ },
+
+ module: {
+ rules: [
+ {
+ test: /\.ts$/,
+ exclude: /\.spec\.ts$/,
+ use: ["awesome-typescript-loader", "angular2-template-loader"]
+ },
+ {
+ test: /\.html$/,
+ use: [
+ {
+ loader: "html-loader"
+ },
+ ]
+ },
+ {
+ test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
+ use: "file-loader?name=assets/images/[name].[ext]"
+ },
+ {
+ test: /\.scss$/,
+ use: [
+ {
+ loader: "style-loader"
+ },
+ {
+ loader: "css-loader"
+ },
+ {
+ loader: "postcss-loader", // Run post css actions
+ options: {
+ plugins: function () { // post css plugins, can be exported to postcss.config.js
+ return [
+ require("precss"),
+ require("autoprefixer")
+ ];
+ }
+ }
+ },
+ {
+ loader: "sass-loader",
+ options: {
+ includePaths: [
+ path.resolve(__dirname, "../src/assets/sass"),
+ path.resolve(__dirname, "../node_modules/bootstrap/scss"),
+ ]
+ }
+ }
+ ]
+ },
+ {
+ test: /\.css$/,
+ exclude: helpers.root("src", "app"),
+ use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" })
+ },
+ {
+ test: /\.css$/,
+ include: helpers.root("src", "app"),
+ use: "raw-loader"
+ }
+ ]
+ },
+
+ plugins: [
+ new webpack.ProvidePlugin({
+ $: "jquery",
+ jQuery: "jquery",
+ "window.jQuery": "jquery",
+ Popper: ["popper.js", "default"],
+ }),
+ new webpack.optimize.CommonsChunkPlugin({name: ["app", "vendor", "polyfills"]}),
+ new HtmlWebpackPlugin({template: "src/index.html"}),
+ new CopyWebpackPlugin([
+ {
+ from: "src/assets",
+ to: "assets",
+ toType: "dir"
+ },
+ ]),
+ new webpack.ContextReplacementPlugin(
+ /angular(\\|\/)core(\\|\/)(@angular|esm5)/,
+ path.resolve(__dirname, "../src")
+ ),
+ ],
+
+ target:"electron-renderer",
+ node: {
+ __dirname: true
+ },
+};
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.dev.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.dev.js
new file mode 100644
index 00000000..da7498c0
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.dev.js
@@ -0,0 +1,24 @@
+var webpackMerge = require("webpack-merge");
+var ExtractTextPlugin = require("extract-text-webpack-plugin");
+var commonConfig = require("./webpack.common.js");
+var helpers = require("./helpers");
+
+module.exports = webpackMerge(commonConfig, {
+ devtool: "cheap-module-source-map",
+
+ output: {
+ path: helpers.root("dist"),
+ publicPath: "./",
+ filename: "[name].js",
+ chunkFilename: "[id].chunk.js"
+ },
+
+ plugins: [
+ new ExtractTextPlugin("[name].css")
+ ],
+
+ devServer: {
+ historyApiFallback: true,
+ stats: "minimal"
+ }
+});
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.prod.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.prod.js
new file mode 100644
index 00000000..b59155af
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.prod.js
@@ -0,0 +1,39 @@
+var webpack = require("webpack");
+var webpackMerge = require("webpack-merge");
+var ExtractTextPlugin = require("extract-text-webpack-plugin");
+const Uglify = require("uglifyjs-webpack-plugin");
+var commonConfig = require("./webpack.common.js");
+var helpers = require("./helpers");
+
+const ENV = process.env.NODE_ENV = process.env.ENV = "production";
+
+module.exports = webpackMerge(commonConfig, {
+ devtool: "source-map",
+
+ output: {
+ path: helpers.root("dist"),
+ publicPath: "./",
+ filename: "[name].[hash].js",
+ chunkFilename: "[id].[hash].chunk.js"
+ },
+
+ plugins: [
+ new webpack.NoEmitOnErrorsPlugin(),
+ new Uglify({
+ uglifyOptions:{
+ keep_fnames: true
+ }
+ }),
+ new ExtractTextPlugin("[name].[hash].css"),
+ new webpack.DefinePlugin({
+ "process.env": {
+ "ENV": JSON.stringify(ENV)
+ }
+ }),
+ new webpack.LoaderOptionsPlugin({
+ htmlLoader: {
+ minimize: false // workaround for ng2
+ }
+ })
+ ]
+});
\ No newline at end of file
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.test.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.test.js
new file mode 100644
index 00000000..946c045e
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/config/webpack.test.js
@@ -0,0 +1,36 @@
+var helpers = require("./helpers");
+
+module.exports = {
+ devtool: "inline-source-map",
+
+ resolve: {
+ extensions: [".ts", ".js"]
+ },
+
+ externals: { sqlite3: "commonjs sqlite3" },
+
+ module: {
+ loaders: [
+ {
+ test: /\.ts$/,
+ loaders: ["awesome-typescript-loader", "angular2-template-loader"]
+ },
+ {
+ test: /\.html$/,
+ loader: "html-loader"
+
+ },
+ {
+ test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
+ loader: "null"
+ },
+ {
+ test: /\.css$/,
+ include: helpers.root("src", "app"),
+ loader: "raw-loader"
+ }
+ ]
+ },
+
+ target:"electron-renderer",
+};
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/index.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/index.js
new file mode 100644
index 00000000..6c596616
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/index.js
@@ -0,0 +1,58 @@
+"use strict";
+
+const {app, BrowserWindow, ipcMain } = require("electron");
+const path = require("path");
+
+// Keep a global reference of the window object, if you don"t, the window will
+// be closed automatically when the JavaScript object is garbage collected.
+let mainWindow;
+
+let createWindow = () => {
+ // Create the browser window.
+ mainWindow = new BrowserWindow({
+ width: 900,
+ height: 800,
+ // resizable:false,
+ icon:"./dist/assets/icon.ico",
+ show: false
+ });
+
+ mainWindow.once("ready-to-show", () => {
+ mainWindow.show();
+ });
+
+ // and load the index.html of the app.
+ mainWindow.loadURL("file://" + __dirname + "/dist/index.html");
+
+ mainWindow.setMenu(null);
+ //mainWindow.webContents.openDevTools();
+
+ // Emitted when the window is closed.
+ mainWindow.on("closed", () => {
+ // Dereference the window object, usually you would store windows
+ // in an array if your app supports multi windows, this is the time
+ // when you should delete the corresponding element.
+ mainWindow = null;
+ });
+};
+
+// This method will be called when Electron has finished
+// initialization and is ready to create browser windows.
+app.on("ready", createWindow);
+
+// Quit when all windows are closed.
+app.on("window-all-closed", () => {
+ // On OS X it is common for applications and their menu bar
+ // to stay active until the user quits explicitly with Cmd + Q
+ if (process.platform !== "darwin") {
+ app.quit();
+ }
+});
+
+app.on("activate", () => {
+ // On OS X it"s common to re-create a window in the app when the
+ // dock icon is clicked and there are no other windows open.
+ if (mainWindow === null) {
+ createWindow();
+ }
+});
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/package.json b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/package.json
new file mode 100644
index 00000000..93ab93a5
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/package.json
@@ -0,0 +1,102 @@
+{
+ "name": "zkweb",
+ "productName": "Zkweb",
+ "version": "1.0.0",
+ "description": "Zkweb Project Creator",
+ "author": "魂祭心",
+ "main": "index.js",
+ "scripts": {
+ "start": "electron .",
+ "prebuild": "node ./prebuild.js",
+ "dev": "webpack --config config/webpack.dev.js || electron .",
+ "test": "karma start ./config/karma.conf.js",
+ "build": "webpack --config config/webpack.prod.js",
+ "packagewin": "electron-packager ./ \"ProjectCreator.Gui\" --out=./build --platform=win32 --arch=x64 --icon=./src/assets/icon.ico --overwrite --ignore=\"(src|config/|.gitignore|build|DatabaseUtils/|.cs|.pdb|node_modules|prebuild.js|readme.md|tsconfig.json|tslint.json|package-lock.json)\"",
+ "packagelinux": "electron-packager ./ \"ProjectCreator.Gui\" --out=./build --platform=linux --arch=x64 --icon=./src/assets/icon.ico --overwrite --ignore=\"(src|config/|.gitignore|build|DatabaseUtils/|.cs|.pdb|node_modules|prebuild.js|readme.md|tsconfig.json|tslint.json|package-lock.json)\"",
+ "packagemac": "electron-packager ./ \"ProjectCreator.Gui\" --out=./build --platform=darwin --arch=x64 --icon=./src/assets/icon.ico --overwrite --ignore=\"(src|config/|.gitignore|build|DatabaseUtils/|.cs|.pdb|node_modules|prebuild.js|readme.md|tsconfig.json|tslint.json|package-lock.json)\""
+ },
+ "license": "MIT",
+ "build": {
+ "appId": "Zkweb",
+ "productName": "Zkweb",
+ "directories": {
+ "output": "build"
+ },
+ "nsis": {
+ "oneClick": false
+ },
+ "files": [
+ "!**/.vscode",
+ "!**/build",
+ "!**/config",
+ "!**/src"
+ ],
+ "extraResources": [
+ {
+ "from": "src/assets",
+ "to": "dist/assets",
+ "filter": "Database*"
+ }
+ ]
+ },
+ "dependencies": {
+ "@angular/animations": "^5.2.8",
+ "@angular/common": "^5.2.3",
+ "@angular/compiler": "^5.2.3",
+ "@angular/compiler-cli": "^5.2.6",
+ "@angular/core": "^5.2.3",
+ "@angular/forms": "^5.2.3",
+ "@angular/http": "^5.2.3",
+ "@angular/platform-browser": "^5.2.3",
+ "@angular/platform-browser-dynamic": "^5.2.3",
+ "@angular/platform-server": "^5.2.6",
+ "@ngx-translate/core": "^9.1.1",
+ "@ngx-translate/http-loader": "^2.0.1",
+ "bootstrap": "^4.0.0",
+ "core-js": "^2.5.3",
+ "electron": "^1.8.1",
+ "electron-packager": "^11.1.0",
+ "jquery": "^3.3.1",
+ "mongodb": "^3.0.3",
+ "mssql": "^4.1.0",
+ "mysql": "^2.15.0",
+ "pg-core": "^0.1.15",
+ "pg2": "0.0.1",
+ "popper.js": "^1.13.0",
+ "rxjs": "^5.5.6",
+ "zone.js": "^0.8.20"
+ },
+ "devDependencies": {
+ "@types/core-js": "^0.9.46",
+ "@types/jasmine": "^2.8.6",
+ "@types/node": "^9.4.0",
+ "angular2-template-loader": "^0.6.2",
+ "autoprefixer": "^7.2.5",
+ "awesome-typescript-loader": "^3.4.1",
+ "copy-webpack-plugin": "^4.3.1",
+ "css-loader": "^0.28.9",
+ "electron-reload": "^1.2.2",
+ "extract-text-webpack-plugin": "^3.0.2",
+ "file-loader": "^1.1.6",
+ "html-loader": "^0.5.5",
+ "html-webpack-plugin": "^2.30.1",
+ "jasmine-core": "^2.9.1",
+ "karma": "2.0.0",
+ "karma-electron": "^5.2.2",
+ "karma-jasmine": "^1.1.1",
+ "karma-sourcemap-loader": "^0.3.7",
+ "karma-spec-reporter": "^0.0.32",
+ "karma-webpack": "^2.0.9",
+ "node-sass": "^4.7.2",
+ "postcss-loader": "^2.1.0",
+ "precss": "^3.1.0",
+ "raw-loader": "^0.5.1",
+ "sass-loader": "^6.0.6",
+ "style-loader": "^0.20.1",
+ "ts-loader": "^3.4.0",
+ "typescript": "^2.7.1",
+ "uglifyjs-webpack-plugin": "^1.1.8",
+ "webpack": "^3.10.0",
+ "webpack-merge": "^4.1.1"
+ }
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/prebuild.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/prebuild.js
new file mode 100644
index 00000000..f9e9a170
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/prebuild.js
@@ -0,0 +1,26 @@
+const fs = require("fs-extra");
+const path = require("path");
+const childProcess = require("child_process");
+const util = require("util");
+const debuglog = util.debuglog("prebuild");
+
+var commnad = "dotnet publish -c Release " + path.join(".", "DatabaseUtils", "DatabaseUtils.csproj");
+var from = path.join(".", "DatabaseUtils", "bin", "Release", "netcoreapp2.0","publish");
+var to = path.join(".", "src", "assets","dbUtil");
+
+childProcess.exec(commnad,
+ (error, stdout) => {
+ if (!error) {
+ debuglog("build success");
+ fs.copy(from, to, function (err) {
+ if (err) {
+ return debuglog(err);
+ } else {
+ debuglog("complete!");
+ }
+ });
+ } else {
+ debuglog(error);
+ }
+ });
+
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/publish.js b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/publish.js
new file mode 100644
index 00000000..ed7873c0
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/publish.js
@@ -0,0 +1,44 @@
+/*import { request } from "http";
+
+"use strict";
+var packager = require("electron-packager");
+var path=require("path");
+
+var options = {
+ "dir": "./",
+ "app-copyright": "魂祭心",
+ "app-version": "1.0.0",
+ "asar": false,
+ "icon": "./src/assets/icon.ico",
+ "name": "Zkweb Project Creator",
+ "out": "./build",
+ "overwrite": true,
+ "prune": false,
+ "version": "1.0.0",
+ "ignore":function(str){
+ //--ignore=\"(src|config|.gitignore|build|.cs|.pdb|node_modules|prebuild.js|readme.md|tsconfig.json|tslint.json|package-lock.json
+ var p= path.parse('/home/user/dir/file.txt');
+ ignorePath(p,"src");
+ ignorePath(p,"src");
+ }
+};
+
+function keep(path){
+
+}
+
+function ignorePath(path,word){
+ return path.indexOf(key)!==-1;
+}
+
+function ignoreFile(path,){
+
+}
+
+function ignoreExtend(path,ext){
+
+}
+
+packager(options, function done_callback(err, appPaths) {
+
+});*/
\ No newline at end of file
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/readme.md b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/readme.md
new file mode 100644
index 00000000..0e8f66a9
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/readme.md
@@ -0,0 +1,25 @@
+# zkweb creator
+
+## build
+
+ cd ./ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui
+
+ npm install
+
+ npm run build
+
+## package
+
+ npm run packagewin
+
+ npm run packagelinux
+
+ npm run packagemac
+
+应用程序会生成在build目录下,需要移动到Tools目录里面。
+
+编译打包后生成的可执行文件,当前存在的两个问题:
+
+1. 与之前的gui工具相同,这个工具也需要放在Tools目录下面。
+
+2. 在ubuntu系统中,双击执行拿不到shell的PATH,因而需要shell启动程序中 ./zkweb
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/CreateProjectParameters.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/CreateProjectParameters.ts
new file mode 100644
index 00000000..195420f6
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/CreateProjectParameters.ts
@@ -0,0 +1,81 @@
+import { PluginCollection } from "./PluginCollection";
+
+export class CreateProjectParameters {
+
+ public TemplatesDirectory: string;
+ public ProjectType: string;
+ public ProjectName: string;
+ public ProjectDescription: string;
+ public ORM: string;
+ public Database: string;
+ public ConnectionString: string;
+ public UseDefaultPlugins: string;
+ public OutputDirectory: string;
+ public AvailableProductTypes: string[] = ["AspNetCore", "AspNet", "Owin"];
+ public AvailableORM: string[] = ["Dapper", "EFCore", "MongoDB", "NHibernate"];
+ public AvailableDatabases: any = {
+ Dapper: ["MSSQL", "SQLite", "MySQL", "PostgreSQL"],
+ EFCore: ["MSSQL", "SQLite", "MySQL", "PostgreSQL", "InMemory"],
+ MongoDB: ["MongoDB"],
+ NHibernate: ["PostgreSQL", "SQLite", "MySQL", "MSSQL"],
+ };
+
+ public Check(): any {
+ if (-1 === this.AvailableProductTypes.indexOf(this.ProjectType)) {
+ return {
+ isSuccess: false,
+ msgPrefix: "ProjectTypeMustBeOneOf",
+ args: this.AvailableProductTypes.join(","),
+ };
+ } else if (!this.ProjectName) {
+ return {
+ isSuccess: false,
+ msgPrefix: "ProjectNameCantBeEmpty",
+ };
+ } else if (-1 === this.AvailableORM.indexOf(this.ORM)) {
+ return {
+ isSuccess: false,
+ msgPrefix: "ORMMustBeOneOf",
+ args: this.AvailableORM.join(","),
+ };
+ } else if (-1 === this.AvailableDatabases[this.ORM].indexOf(this.Database)) {
+ return {
+ isSuccess: false,
+ msgPrefix: "DatabaseMustBeOneOf",
+ args: this.AvailableDatabases[this.ORM].join(","),
+ };
+ } else if (this.Database === "InMemory" && !this.ConnectionString) {
+ return {
+ isSuccess: false,
+ msgPrefix: "ConnectionStringCantBeEmpty",
+ };
+ } else if (!this.OutputDirectory) {
+ return {
+ isSuccess: false,
+ msgPrefix: "OutputDirectoryCantBeEmpty",
+ };
+ }
+ if (this.UseDefaultPlugins) {
+ const pluginCollection = PluginCollection.FromFile(this.UseDefaultPlugins);
+
+ let isOrmExit = false;
+
+ for (const orm of pluginCollection.SupportedORM) {
+ if (orm === this.ORM) {
+ isOrmExit = true;
+ }
+ }
+
+ if (!isOrmExit) {
+ return {
+ isSuccess: false,
+ msgPrefix: "ORMMustBeOneOf",
+ args: pluginCollection.SupportedORM.join(","),
+ };
+ }
+ }
+ return {
+ isSuccess: true,
+ };
+ }
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/PluginCollection.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/PluginCollection.ts
new file mode 100644
index 00000000..07b1e617
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/PluginCollection.ts
@@ -0,0 +1,18 @@
+const fs = require("fs");
+export class PluginCollection {
+
+ public PrependPlugins: string[];
+ public AppendPlugins: string[];
+ public SupportedORM: string[];
+
+ public static FromFile(path: string): PluginCollection {
+ const json = fs.readFileSync(path, "utf8");
+ return JSON.parse(json);
+ }
+
+ public PluginCollection() {
+ this.PrependPlugins = [];
+ this.AppendPlugins = [];
+ this.SupportedORM = [];
+ }
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.css b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.css
new file mode 100644
index 00000000..1aad6d16
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.css
@@ -0,0 +1,11 @@
+.btnCenter{
+ display: table;
+ width: auto;
+ margin-left: auto;
+ margin-right: auto;
+}
+.form-group{
+ margin-bottom: 0.3rem;
+}
+
+.row-margin-top { margin-top: 10px; }
\ No newline at end of file
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.html b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.html
new file mode 100644
index 00000000..d4b339c3
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.html
@@ -0,0 +1,183 @@
+
\ No newline at end of file
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.ts
new file mode 100644
index 00000000..7e30f3f6
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.component.ts
@@ -0,0 +1,190 @@
+import { Component, Input } from "@angular/core";
+import { TranslateService } from "@ngx-translate/core";
+const childProcess = require("child_process");
+const EventEmitter = require("events");
+const path = require("path");
+const app = require("electron").remote.app;
+const util = require("util");
+const debuglog = util.debuglog("app");
+import { remote } from "electron";
+import "../assets/sass/style.scss";
+import { CreateProjectParameters } from "./CreateProjectParameters";
+
+class MessageEmitter extends EventEmitter { }
+
+@Component({
+ selector: "app",
+ templateUrl: "app.component.html",
+ styleUrls: ["app.component.css"] ,
+})
+export class AppComponent {
+
+ @Input()
+ public parameters: CreateProjectParameters;
+ @Input()
+ public enableDatabase: any;
+ private language: string;
+ private eventEmitter: MessageEmitter;
+ private rootPath: string;
+ private isDataBaseChecking: boolean;
+
+ constructor(public translateService: TranslateService) {
+ this.language = app.getLocale();
+ this.rootPath = app.getAppPath();
+ this.parameters = new CreateProjectParameters();
+ this.parameters.ProjectType = "AspNetCore";
+ this.parameters.ORM = "NHibernate";
+ this.parameters.Database = "MSSQL";
+ this.isDataBaseChecking = false;
+ this.eventEmitter = new MessageEmitter();
+ this.enableDatabase = {
+ MSSQL: true,
+ MySQL: true,
+ SQLite: true,
+ PostgreSQL: true,
+ InMemory: true,
+ MongoDB: true,
+ };
+ }
+
+ ngOnInit() {
+ this.translateService.addLangs(["zh-CN", "en-US"]);
+ this.translateService.setDefaultLang("zh-CN");
+ this.translateService.use(this.language);
+
+ this.eventEmitter.on("error", (msg: string) => {
+ remote.dialog.showErrorBox("error", msg);
+ });
+ this.eventEmitter.on("info", (msg: string) => {
+ remote.dialog.showMessageBox({
+ type: "info",
+ title: "info",
+ message: msg ,
+ });
+ });
+ }
+
+ public createProject(): void {
+ const toolPath = this.findTools();
+ if (!toolPath) {
+ this.translateService.get("ToolsFoderFail", {}).subscribe((res: string) => {
+ this.eventEmitter.emit("error", res);
+ });
+ return;
+ }
+ const result = this.parameters.Check();
+ if (!result.isSuccess) {
+ this.translateService.get(result.msgPrefix, {}).subscribe((res: string) => {
+ debuglog(res);
+ this.eventEmitter.emit("error", res + (result.args ? result.args : ""));
+ });
+ return;
+ }
+
+ const commnad = this.createCommand(toolPath);
+ debuglog(commnad);
+
+ childProcess.exec(commnad,
+ (error: any, stdout: any) => {
+ if (error) {
+ this.eventEmitter.emit("error", "fail");
+ } else {
+ this.eventEmitter.emit("info", stdout);
+ }
+ });
+
+ }
+
+ public testConnection(): void {
+ if (!this.isDataBaseChecking) {
+ this.isDataBaseChecking = true;
+ try {
+ const utilPath = path.join(this.rootPath, "dist", "assets", "dbUtil", "DatabaseUtils.dll");
+ const commnad = "dotnet " + utilPath + " " + this.parameters.Database + " \"" + this.parameters.ConnectionString + "\"";
+ childProcess.exec(commnad,
+ (error: any, stdout: any, stderr: any) => {
+ if (error) {
+ debuglog(error);
+ debuglog(stderr);
+ // this.eventEmitter.emit("info", commnad);
+ this.translateService.get("dataBaseTestFail", {}).subscribe((res: string) => {
+ this.eventEmitter.emit("error", res);
+ });
+ } else {
+ debuglog(stdout);
+ this.eventEmitter.emit("info", "success");
+ }
+ this.isDataBaseChecking = false;
+ });
+ } catch {
+ this.isDataBaseChecking = false;
+ }
+ }
+ }
+
+ public changeOrm(orm: string): void {
+ const invalidDatabases = this.parameters.AvailableDatabases[orm];
+ if (-1 === invalidDatabases.indexOf(this.parameters.Database)) {
+ this.parameters.Database = "";
+ }
+ const keys: string[] = [];
+ for (const m in this.enableDatabase) {
+ if (this.enableDatabase.hasOwnProperty(m)) {
+ keys.push(m);
+ }
+ }
+
+ keys.forEach((item) => {
+ this.enableDatabase[item] = false;
+ });
+
+ invalidDatabases.forEach((item: any) => {
+ this.enableDatabase[item] = true;
+ });
+ }
+
+ public pluginSelect(): void {
+ const selectFile = remote.dialog.showOpenDialog({ properties: ["openFile"] });
+ if (selectFile && selectFile.length > 0) {
+ this.parameters.UseDefaultPlugins = selectFile[0];
+ }
+ }
+
+ public outPutSelect(): void {
+ const selectFile = remote.dialog.showOpenDialog({ properties: ["openDirectory"] });
+ if (selectFile && selectFile.length > 0) {
+ this.parameters.OutputDirectory = selectFile[0];
+ }
+ }
+
+ private createCommand(toolPath: string): string {
+ let parametersStr = [
+ "--t=" + this.parameters.ProjectType,
+ "--n=" + this.parameters.ProjectName,
+ "--m=" + this.parameters.ORM,
+ "--b=" + this.parameters.Database,
+ "--c=" + "\"this.parameters.ConnectionString" + "\"",
+ "--o=" + this.parameters.OutputDirectory,
+ ].join(" ");
+ if (this.parameters.ProjectDescription) {
+ parametersStr += " " + "--d=" + this.parameters.ProjectDescription;
+ }
+ if (this.parameters.ProjectDescription) {
+ parametersStr += " " + "--u=" + this.parameters.UseDefaultPlugins;
+ }
+
+ toolPath = path.join(toolPath, "ProjectCreator.Cmd.NetCore", "ZKWeb.Toolkits.ProjectCreator.Cmd.dll");
+ return "dotnet " + toolPath + " " + parametersStr;
+
+ }
+
+ private findTools(): string {
+ const folders = this.rootPath.split(path.sep);
+ const index = folders.indexOf("Tools");
+ if (index !== -1) {
+ return folders.slice(0, index + 1).join(path.sep);
+ }
+ return "";
+ }
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.module.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.module.ts
new file mode 100644
index 00000000..ef59559e
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/app.module.ts
@@ -0,0 +1,37 @@
+import { HttpClient, HttpClientModule } from "@angular/common/http";
+import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { HttpModule} from "@angular/http";
+import { BrowserModule } from "@angular/platform-browser";
+import { TranslateLoader, TranslateModule} from "@ngx-translate/core";
+import { TranslateHttpLoader } from "@ngx-translate/http-loader";
+import { AppComponent } from "./app.component";
+
+export function createTranslateHttpLoader(http: HttpClient) {
+ return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
+}
+@NgModule({
+ imports: [
+ BrowserModule,
+ HttpModule,
+ HttpClientModule,
+ FormsModule,
+ TranslateModule.forRoot({
+ loader: {
+ provide: TranslateLoader,
+ useFactory: (createTranslateHttpLoader),
+ deps: [HttpClient],
+ },
+ }) ,
+ ],
+ declarations: [
+ AppComponent,
+ ],
+ providers: [
+ ],
+ bootstrap: [AppComponent],
+})
+
+export class AppModule {
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/baseConnection.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/baseConnection.ts
new file mode 100644
index 00000000..0e47ab20
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/baseConnection.ts
@@ -0,0 +1,13 @@
+
+export interface IBaseConnection {
+
+ ip: string;
+ port: number;
+ user: string;
+ password: string;
+ connectionString: string;
+
+ parser(): void;
+ testConnect(messageEvent: any): void;
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/mongoConnection.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/mongoConnection.ts
new file mode 100644
index 00000000..94bc4c2e
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/mongoConnection.ts
@@ -0,0 +1,30 @@
+import { TranslateService } from "@ngx-translate/core";
+import { IBaseConnection } from "./baseConnection";
+const MongoClient = require("mongodb").MongoClient;
+
+export class MongoConnection implements IBaseConnection {
+
+ public ip: string;
+ public port: number;
+ public user: string;
+ public password: string;
+ public connectionString: string;
+
+ constructor(public translateService: TranslateService, connectonString: string) {
+ this.connectionString = connectonString;
+ }
+ parser(): void {
+ }
+ testConnect(messageEvent: any): void {
+ MongoClient.connect(this.connectionString, (err: any) => {
+ if (err) {
+ this.translateService.get("dataBaseTestFail", {}).subscribe((res: string) => {
+ messageEvent.emit("error", res);
+ });
+ } else {
+ messageEvent.emit("info", "success");
+ }
+ });
+ }
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/msSqlConnection.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/msSqlConnection.ts
new file mode 100644
index 00000000..fa57fb7f
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/msSqlConnection.ts
@@ -0,0 +1,60 @@
+import { TranslateService } from "@ngx-translate/core";
+import { IBaseConnection } from "./baseConnection";
+const sql = require("mssql");
+
+export class MsSqlConnection implements IBaseConnection {
+
+ public ip: string;
+ public port: number;
+ public user: string;
+ public password: string;
+ public connectionString: string;
+
+ constructor(public translateService: TranslateService, connectonString: string) {
+ this.connectionString = connectonString;
+ }
+ /**
+ *
+ * @param connectonString Data Source=server;Initial Catalog=db;User ID=test;Password=test;
+ */
+ parser(): void {
+ const phrases = this.connectionString.toLowerCase().split(";");
+ const config = {};
+ for (const phrase of phrases) {
+ if (phrase) {
+ const kv = phrase.split("=");
+ config[kv[0].trim()] = kv[1].trim();
+ }
+ }
+ this.ip = config["data source"];
+ this.port = config["port"] ? parseInt(config["port"], 10) : 1433;
+ this.user = config["user id"];
+ this.password = config["password"];
+ }
+
+ testConnect(messageEvent: any): void {
+ try {
+ sql.connect({
+ user: this.user,
+ password: this.password,
+ server: this.ip,
+ port: this.port.toString(),
+ }, (err: any) => {
+ if (err) {
+ this.translateService.get("dataBaseTestFail", {}).subscribe((res: string) => {
+ messageEvent.emit("error", res);
+ });
+ } else {
+ messageEvent.emit("info", "success");
+ }
+ sql.close();
+ });
+ } catch {
+ this.translateService.get("dataBaseTestFail", {}).subscribe((res: string) => {
+ messageEvent.emit("error", res);
+ });
+ sql.close();
+ }
+ }
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/mysqlConnection.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/mysqlConnection.ts
new file mode 100644
index 00000000..757f2b17
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/mysqlConnection.ts
@@ -0,0 +1,60 @@
+import { TranslateService } from "@ngx-translate/core";
+import { IBaseConnection } from "./baseConnection";
+const mysql = require("mysql");
+
+export class MySqlConnection implements IBaseConnection {
+
+ public ip: string;
+ public port: number;
+ public user: string;
+ public password: string;
+ public connectionString: string;
+
+ constructor(public translateService: TranslateService, connectonString: string) {
+ this.connectionString = connectonString;
+ }
+
+ parser(): void {
+ const phrases = this.connectionString.toLowerCase().split(";");
+ const config = {};
+ for (const phrase of phrases) {
+ if (phrase) {
+ const kv = phrase.split("=");
+ config[kv[0].trim()] = kv[1].trim();
+ }
+ }
+ this.ip = config["server"];
+ this.port = config["port"] ? parseInt(config["port"], 10) : 3306;
+ this.user = config["user"];
+ this.password = config["password"];
+ }
+
+ testConnect(messageEvent: any): void {
+ let connection: any = null;
+ try {
+ connection = mysql.createConnection({
+ host: this.ip,
+ port: this.port.toString(),
+ user: this.user,
+ password: this.password,
+ });
+
+ connection.connect({}, (err: any) => {
+ if (err) {
+ this.translateService.get("dataBaseTestFail", {}).subscribe((res: string) => {
+ messageEvent.emit("error", res);
+ });
+ } else {
+ messageEvent.emit("info", "success");
+ }
+ connection.destroy();
+ });
+ } catch {
+ this.translateService.get("dataBaseTestFail", {}).subscribe((res: string) => {
+ messageEvent.emit("error", res);
+ });
+ connection.destroy();
+ }
+ }
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/postgreSQLConnection.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/postgreSQLConnection.ts
new file mode 100644
index 00000000..08891edb
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/postgreSQLConnection.ts
@@ -0,0 +1,41 @@
+import { TranslateService } from "@ngx-translate/core";
+import { IBaseConnection } from "./baseConnection";
+const util = require("util");
+const debuglog = util.debuglog("postgreSQL");
+export class PostgreSQLConnection implements IBaseConnection {
+
+ public user: string;
+ public password: string;
+ public connectionString: string;
+ public ip: string;
+ public port: number;
+ public db: string;
+
+ constructor(public translateService: TranslateService, connectonString: string) {
+ this.connectionString = connectonString;
+ }
+ /**
+ *
+ * @param connectonString PORT=5432;DATABASE=Demo;HOST=localhost;PASSWORD=root;USER ID=postgres
+ */
+ parser(): void {
+ const phrases = this.connectionString.toLowerCase().split(";");
+ const config = {};
+ for (const phrase of phrases) {
+ if (phrase) {
+ const kv = phrase.split("=");
+ config[kv[0].trim()] = kv[1].trim();
+ }
+ }
+ this.ip = config["host"];
+ this.port = config["port"] ? parseInt (config["port"], 10) : 5432;
+ this.user = config["user id"];
+ this.password = config["password"];
+ this.db = config["database"];
+ }
+
+ testConnect(messageEvent: any): void {
+ debuglog(messageEvent);
+ }
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/sqlLiteConnection.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/sqlLiteConnection.ts
new file mode 100644
index 00000000..c28e0803
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/app/dataBaseConnection/sqlLiteConnection.ts
@@ -0,0 +1,42 @@
+import { TranslateService } from "@ngx-translate/core";
+import { IBaseConnection } from "./baseConnection";
+const fs = require("fs");
+
+export class SqlLiteConnection implements IBaseConnection {
+
+ public ip: string;
+ public port: number;
+ public user: string;
+ public password: string;
+ public connectionString: string;
+
+ constructor(public translateService: TranslateService, connectonString: string) {
+ this.connectionString = connectonString;
+ }
+ /**
+ *
+ * @param connectonString Data Source=server;Initial Catalog=db;User ID=test;Password=test;
+ */
+ parser(): void {
+ const phrases = this.connectionString.toLowerCase().split(";");
+ const config = {};
+ for (const phrase of phrases) {
+ if (phrase) {
+ const kv = phrase.split("=");
+ config[kv[0].trim()] = kv[1].trim();
+ }
+ }
+ this.ip = config["data source"];
+ }
+
+ testConnect(messageEvent: any): void {
+ if (fs.existsSync(this.ip)) {
+ this.translateService.get("dataBaseTestFail", {}).subscribe((res: string) => {
+ messageEvent.emit("error", res);
+ });
+ } else {
+ messageEvent.emit("info", "success");
+ }
+ }
+
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/i18n/en-US.json b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/i18n/en-US.json
new file mode 100644
index 00000000..9194a5da
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/i18n/en-US.json
@@ -0,0 +1,31 @@
+{
+ "projectType": "Project Type(Require):",
+ "projectTypeTip": "Asp.Net Core is recommended for new projects ",
+ "projectName": "Project Name(Required):",
+ "projectNameTip": "Also be the namespace, please don't use special characters",
+ "projectDescription": "Description:",
+ "orm": "ORM(Required):",
+ "ormTip": "NHibernate is most powerful but you may want EFCore for better .net core support",
+ "dataBase": "Database(Required):",
+ "dataBaseTip": "Just choose one you preferred",
+ "connectionString": "Connection String(Required):",
+ "connectionStringTip": "You can click 'Test' to verify the connection string is valid",
+ "testConnection": "Test",
+ "browser": "Browse",
+ "useDefaultPlugin": "Use Default Plugins:",
+ "useDefaultPluginTip": "Default plugins contains many features, but for now only NHibernate can use all of them",
+ "outPutFolder": "Output Directory(Required):",
+ "outPutFolderTip": "Project will be created here",
+ "create": "Create Project",
+ "ConnectionStringCantBeEmpty": "Connection string can't be empty",
+ "DatabaseMustBeOneOf": "Database must be one of ",
+ "DetectTemplatesDirectoryFailed": "Detect templates directory failed",
+ "ORMMustBeOneOf": "ORM must be one of",
+ "OutputDirectoryCantBeEmpty": "Output directory can't be empty",
+ "ProjectNameCantBeEmpty": "Project name can't be empty",
+ "ProjectTypeMustBeOneOf": "Project type must be one of ",
+ "ThisPluginCollectionOnlySupportTheseORM": "This plugin collection only support these ORM:",
+ "dataBaseTestFail":"fail to connect dataBase",
+ "ToolsFoderFail":"unable to find Tools foder",
+ "notValidConnectionString":"Invalid ConnectionString"
+}
\ No newline at end of file
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/i18n/zh-CN.json b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/i18n/zh-CN.json
new file mode 100644
index 00000000..6e094737
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/i18n/zh-CN.json
@@ -0,0 +1,31 @@
+{
+ "projectType":"项目类型(必填):",
+ "projectTypeTip": "推荐新项目使用Asp.Net Core",
+ "projectName":" 项目名称(必填):",
+ "projectNameTip":"同时会作为命名空间, 请勿使用特殊字符",
+ "projectDescription":" 项目描述:",
+ "orm":"Orm(必填)",
+ "ormTip":"NHibernate功能最强大, 但您可能需要选EFCore以更好的支持.Net Core",
+ "dataBase":"数据库(必填)",
+ "dataBaseTip":"选一个你觉得最好的",
+ "connectionString":"连接字符串(必填)",
+ "connectionStringTip":"你可以点击'测试'检查连接字符串是否正确",
+ "testConnection":"测试",
+ "browser":"浏览",
+ "useDefaultPlugin":"使用默认插件",
+ "useDefaultPluginTip":"默认插件包含了很多功能, 但目前只有NHibernate可以使用全部",
+ "outPutFolder":"输出文件夹(必填)",
+ "outPutFolderTip":"项目会在这个文件夹下创建",
+ "create":"创建",
+ "ConnectionStringCantBeEmpty": "连接字符串不能为空",
+ "DatabaseMustBeOneOf": "数据库必须是这些的其中之一: ",
+ "DetectTemplatesDirectoryFailed": "检测项目模板目录失败",
+ "ORMMustBeOneOf": "ORM必须是这些的其中之一:",
+ "OutputDirectoryCantBeEmpty": "输出目录不能为空",
+ "ProjectNameCantBeEmpty": "项目名称不能为空",
+ "ProjectTypeMustBeOneOf": "项目类型必须是这些的其中之一:",
+ "ThisPluginCollectionOnlySupportTheseORM": "这个插件集只支持这些ORM:" ,
+ "dataBaseTestFail":"数据库连接失败",
+ "ToolsFoderFail":"无法探测到Tools文件夹",
+ "notValidConnectionString":"连接字符串错误"
+}
\ No newline at end of file
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/icon.icns b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/icon.icns
new file mode 100644
index 00000000..caca1c8b
Binary files /dev/null and b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/icon.icns differ
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/icon.ico b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/icon.ico
new file mode 100644
index 00000000..0445d069
Binary files /dev/null and b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/icon.ico differ
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/images/.gitkeep b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/images/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/_bootstrap-custom.scss b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/_bootstrap-custom.scss
new file mode 100644
index 00000000..26d0818e
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/_bootstrap-custom.scss
@@ -0,0 +1 @@
+$grid-gutter-width-base: 10px !default;
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/_bootstrap.scss b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/_bootstrap.scss
new file mode 100644
index 00000000..c09d20e0
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/_bootstrap.scss
@@ -0,0 +1,42 @@
+/*!
+ * Bootstrap v4.0.0-beta (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+ // Comment out the files you don't need
+@import "functions";
+@import "variables";
+@import "mixins";
+@import "print";
+@import "reboot";
+@import "type";
+@import "images";
+@import "code";
+@import "grid";
+@import "tables";
+@import "forms";
+@import "buttons";
+@import "transitions";
+@import "dropdown";
+@import "button-group";
+@import "input-group";
+@import "custom-forms";
+@import "nav";
+@import "navbar";
+@import "card";
+@import "breadcrumb";
+@import "pagination";
+@import "badge";
+@import "jumbotron";
+@import "alert";
+@import "progress";
+@import "media";
+@import "list-group";
+@import "close";
+@import "modal";
+@import "tooltip";
+@import "popover";
+@import "carousel";
+@import "utilities";
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/style.scss b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/style.scss
new file mode 100644
index 00000000..7a849dab
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/assets/sass/style.scss
@@ -0,0 +1,7 @@
+@import 'bootstrap-custom';
+@import 'bootstrap';
+
+html, body {
+ height: 100%;
+ margin: 0;
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/index.html b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/index.html
new file mode 100644
index 00000000..3d40679a
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ Loading...
+
+
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/main.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/main.ts
new file mode 100644
index 00000000..cd69f5bc
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/main.ts
@@ -0,0 +1,10 @@
+import { enableProdMode } from "@angular/core";
+import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
+
+import { AppModule } from "./app/app.module";
+
+if (process.env.ENV === "production") {
+ enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/polyfills.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/polyfills.ts
new file mode 100644
index 00000000..9e6070be
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/polyfills.ts
@@ -0,0 +1,11 @@
+import "core-js/es7/reflect";
+import "zone.js/dist/zone";
+import "zone.js/dist/zone-patch-electron";
+
+if (process.env.ENV === "production") {
+ // Production
+} else {
+ // Development
+ Error["stackTraceLimit"] = Infinity;
+ require("zone.js/dist/long-stack-trace-zone");
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/vendor.ts b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/vendor.ts
new file mode 100644
index 00000000..6e2d1df8
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/src/vendor.ts
@@ -0,0 +1,14 @@
+// Angular
+import "@angular/common";
+import "@angular/core";
+import "@angular/http";
+import "@angular/platform-browser";
+import "@angular/platform-browser-dynamic";
+
+// RxJS
+import "rxjs";
+
+// Other vendors for example jQuery, Lodash or Bootstrap
+// You can import js, ts, css, sass, ...
+
+import "bootstrap";
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/tsconfig.json b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/tsconfig.json
new file mode 100644
index 00000000..b17d3f6e
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/tsconfig.json
@@ -0,0 +1,33 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "sourceMap": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "suppressImplicitAnyIndexErrors": true,
+
+ "removeComments": false,
+ "preserveConstEnums": true,
+ "noImplicitAny": true,
+ "noImplicitReturns": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true,
+ "noImplicitThis": true,
+ "noUnusedParameters": true,
+ "importHelpers": true,
+ "noEmitHelpers": true,
+ "pretty": true,
+ "skipLibCheck": true
+ },
+ "include": [
+ "src/app/**/*.ts"
+ ],
+ "exclude": [
+ "**/node_modules/*",
+ "dist",
+ "build",
+ "src/app/**/*.spec.ts"
+ ]
+}
diff --git a/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/tslint.json b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/tslint.json
new file mode 100644
index 00000000..f1c6e435
--- /dev/null
+++ b/ZKWeb.Toolkits/ZKWeb.Toolkits.ProjectCreator.Crossplatform.Gui/tslint.json
@@ -0,0 +1,186 @@
+{
+ /*
+ * Possible values:
+ * - the name of a built-in config
+ * - the name of an NPM module which has a "main" file that exports a config object
+ * - a relative path to a JSON file
+ */
+ "extends": [
+ "tslint:latest"
+ ],
+ "rules": {
+ "class-name": true,
+ "comment-format": [
+ true,
+ "check-space"
+ ],
+ "curly": true,
+ "eofline": true,
+ "forin": true,
+ "indent": [
+ true,
+ "spaces"
+ ],
+ "label-position": true,
+ "max-line-length": [
+ true,
+ 140
+ ],
+ "member-access": false,
+ "member-ordering": [
+ true,
+ {
+ "order": "fields-first"
+ }
+ ],
+ "no-arg": true,
+ "no-bitwise": true,
+ "no-console": [
+ false, // should be true
+ "debug",
+ "info",
+ "time",
+ "timeEnd",
+ "trace"
+ ],
+ "no-construct": true,
+ "no-debugger": true,
+ "no-duplicate-variable": true,
+ "no-empty": false,
+ "no-eval": true,
+ "no-inferrable-types": true,
+ "no-shadowed-variable": true,
+ "no-string-literal": false,
+ "no-switch-case-fall-through": true,
+ "no-trailing-whitespace": false, // White space is automatically removed by vscode on save
+ "no-this-assignment": [
+ true,
+ {
+ "allowed-names": [
+ "^self$"
+ ],
+ "allow-destructuring": true
+ }
+ ],
+ "no-unused-expression": true,
+ "no-unused-variable": false, // Is already been handled by Typescript
+ "no-use-before-declare": true,
+ "no-var-keyword": true,
+ "no-var-requires": false,
+ "object-literal-sort-keys": false,
+ "one-line": [
+ true,
+ "check-open-brace",
+ "check-catch",
+ "check-else",
+ "check-whitespace"
+ ],
+ "space-before-function-paren": [
+ true,
+ {
+ "anonymous": "always",
+ "named": "never",
+ "asyncArrow": "always"
+ }
+ ],
+ "quotemark": [
+ true,
+ "double"
+ ],
+ "radix": true,
+ "semicolon": [
+ true,
+ "always"
+ ],
+ "triple-equals": [
+ true,
+ "allow-undefined-check",
+ "allow-null-check"
+ ],
+ "typedef-whitespace": [
+ true,
+ {
+ "call-signature": "nospace",
+ "index-signature": "nospace",
+ "parameter": "nospace",
+ "property-declaration": "nospace",
+ "variable-declaration": "nospace"
+ }
+ ],
+ "variable-name": false,
+ "whitespace": [
+ true,
+ "check-branch",
+ "check-decl",
+ "check-operator",
+ "check-separator",
+ "check-type"
+ ],
+ /*
+ * Any rules specified here will override those from the base config we are extending
+ */
+ "max-classes-per-file": [
+ false
+ ],
+ "prefer-conditional-expression": false,
+ "import-spacing": false,
+
+ /*
+ * Rules for Codelyzer
+ */
+ // The rule have the following arguments:
+ // [ENABLED, "attribute" | "element", "selectorPrefix" | ["listOfPrefixes"], "camelCase" | "kebab-case"]
+ "directive-selector": [
+ false,
+ "attribute",
+ [
+ "fin",
+ "dir-prefix2"
+ ],
+ "camelCase"
+ ],
+ "component-selector": [
+ false,
+ "element",
+ [
+ "fin",
+ "cmp-prefix2"
+ ],
+ "kebab-case"
+ ],
+ "use-input-property-decorator": true,
+ "use-output-property-decorator": true,
+ "use-host-property-decorator": true,
+ "no-attribute-parameter-decorator": true,
+ "no-input-rename": true,
+ "no-output-rename": true,
+ "no-output-on-prefix-name": true,
+ "no-forward-ref": true,
+ "no-submodule-imports": false,
+
+ "use-life-cycle-interface": true,
+ "use-pipe-transform-interface": true,
+ // [ENABLED, "SUFFIX"]
+ // Where "SUFFIX" is your custom suffix, for instance "Page" for Ionic 2 components.
+ "component-class-suffix": [
+ true,
+ "Component"
+ ],
+ "directive-class-suffix": [
+ true,
+ "Directive"
+ ],
+ "templates-use-public": true,
+ "invoke-injectable": true
+ },
+ "rulesDirectory": [
+ /*
+ * A list of relative or absolute paths to directories that contain custom rules.
+ * See the Custom Rules documentation below for more details.
+ */
+
+ ],
+ "exclude": [
+ "**/*.js"
+ ]
+}
\ No newline at end of file