diff --git a/Samples/Zero.Desktop/ClientSetting.cs b/Samples/Zero.Desktop/ClientSetting.cs new file mode 100644 index 000000000..7959ffb16 --- /dev/null +++ b/Samples/Zero.Desktop/ClientSetting.cs @@ -0,0 +1,37 @@ +using System.ComponentModel; +using NewLife; +using NewLife.Configuration; +using NewLife.Remoting.Clients; + +namespace Zero.Desktop; + +[Config("ClientSetting")] +public class ClientSetting : Config, IClientSetting +{ + #region 属性 + /// 语音提示。默认true + [Description("语音提示。默认true")] + public Boolean SpeechTip { get; set; } = true; + + /// 证书 + [Description("证书")] + public String Code { get; set; } + + /// 密钥 + [Description("密钥")] + public String Secret { get; set; } + + /// 服务地址端口。默认为空,子网内自动发现 + [Description("服务地址端口。默认为空,子网内自动发现")] + public String Server { get; set; } = ""; + #endregion + + #region 加载/保存 + protected override void OnLoaded() + { + if (Server.IsNullOrEmpty()) Server = "http://s.newlifex.com:6600"; + + base.OnLoaded(); + } + #endregion +} \ No newline at end of file diff --git a/Samples/Zero.Desktop/FrmMain.Designer.cs b/Samples/Zero.Desktop/FrmMain.Designer.cs new file mode 100644 index 000000000..cfda26e82 --- /dev/null +++ b/Samples/Zero.Desktop/FrmMain.Designer.cs @@ -0,0 +1,238 @@ +namespace Zero.Desktop +{ + partial class FrmMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + groupBox1 = new GroupBox(); + btnOpenAsync = new Button(); + txtServer = new TextBox(); + btnOpen = new Button(); + label1 = new Label(); + groupBox2 = new GroupBox(); + textBox2 = new TextBox(); + label3 = new Label(); + btnCall = new Button(); + cbApi = new ComboBox(); + label2 = new Label(); + groupBox3 = new GroupBox(); + richTextBox1 = new RichTextBox(); + btnCallAsync = new Button(); + groupBox1.SuspendLayout(); + groupBox2.SuspendLayout(); + groupBox3.SuspendLayout(); + SuspendLayout(); + // + // groupBox1 + // + groupBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + groupBox1.Controls.Add(btnOpenAsync); + groupBox1.Controls.Add(txtServer); + groupBox1.Controls.Add(btnOpen); + groupBox1.Controls.Add(label1); + groupBox1.Location = new Point(11, 10); + groupBox1.Margin = new Padding(3, 2, 3, 2); + groupBox1.Name = "groupBox1"; + groupBox1.Padding = new Padding(3, 2, 3, 2); + groupBox1.Size = new Size(1134, 75); + groupBox1.TabIndex = 0; + groupBox1.TabStop = false; + groupBox1.Text = "数据库连接"; + // + // btnOpenAsync + // + btnOpenAsync.Location = new Point(630, 19); + btnOpenAsync.Margin = new Padding(3, 2, 3, 2); + btnOpenAsync.Name = "btnOpenAsync"; + btnOpenAsync.Size = new Size(106, 45); + btnOpenAsync.TabIndex = 4; + btnOpenAsync.Text = "异步打开"; + btnOpenAsync.UseVisualStyleBackColor = true; + btnOpenAsync.Click += btnAsyncOpen_Click; + // + // txtServer + // + txtServer.Location = new Point(96, 28); + txtServer.Name = "txtServer"; + txtServer.Size = new Size(346, 26); + txtServer.TabIndex = 3; + txtServer.Text = "tcp://127.0.0.1:5500"; + // + // btnOpen + // + btnOpen.Location = new Point(489, 19); + btnOpen.Margin = new Padding(3, 2, 3, 2); + btnOpen.Name = "btnOpen"; + btnOpen.Size = new Size(106, 45); + btnOpen.TabIndex = 2; + btnOpen.Text = "打开"; + btnOpen.UseVisualStyleBackColor = true; + btnOpen.Click += btnOpen_Click; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(19, 31); + label1.Name = "label1"; + label1.Size = new Size(60, 20); + label1.TabIndex = 1; + label1.Text = "连接:"; + // + // groupBox2 + // + groupBox2.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + groupBox2.Controls.Add(btnCallAsync); + groupBox2.Controls.Add(textBox2); + groupBox2.Controls.Add(label3); + groupBox2.Controls.Add(btnCall); + groupBox2.Controls.Add(cbApi); + groupBox2.Controls.Add(label2); + groupBox2.Enabled = false; + groupBox2.Location = new Point(11, 90); + groupBox2.Margin = new Padding(3, 2, 3, 2); + groupBox2.Name = "groupBox2"; + groupBox2.Padding = new Padding(3, 2, 3, 2); + groupBox2.Size = new Size(1134, 202); + groupBox2.TabIndex = 1; + groupBox2.TabStop = false; + groupBox2.Text = "内容区"; + // + // textBox2 + // + textBox2.Location = new Point(96, 79); + textBox2.Name = "textBox2"; + textBox2.Size = new Size(346, 26); + textBox2.TabIndex = 4; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new Point(19, 82); + label3.Name = "label3"; + label3.Size = new Size(69, 20); + label3.TabIndex = 3; + label3.Text = "参数1:"; + // + // btnCall + // + btnCall.Location = new Point(489, 67); + btnCall.Name = "btnCall"; + btnCall.Size = new Size(106, 45); + btnCall.TabIndex = 2; + btnCall.Text = "调用"; + btnCall.UseVisualStyleBackColor = true; + btnCall.Click += btnCall_Click; + // + // cbApi + // + cbApi.FormattingEnabled = true; + cbApi.Location = new Point(96, 35); + cbApi.Name = "cbApi"; + cbApi.Size = new Size(346, 28); + cbApi.TabIndex = 1; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(19, 38); + label2.Name = "label2"; + label2.Size = new Size(60, 20); + label2.TabIndex = 0; + label2.Text = "接口:"; + // + // groupBox3 + // + groupBox3.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + groupBox3.Controls.Add(richTextBox1); + groupBox3.Location = new Point(14, 296); + groupBox3.Margin = new Padding(3, 2, 3, 2); + groupBox3.Name = "groupBox3"; + groupBox3.Padding = new Padding(3, 2, 3, 2); + groupBox3.Size = new Size(1128, 400); + groupBox3.TabIndex = 2; + groupBox3.TabStop = false; + groupBox3.Text = "日志"; + // + // richTextBox1 + // + richTextBox1.Dock = DockStyle.Fill; + richTextBox1.Location = new Point(3, 21); + richTextBox1.Margin = new Padding(3, 2, 3, 2); + richTextBox1.Name = "richTextBox1"; + richTextBox1.Size = new Size(1122, 377); + richTextBox1.TabIndex = 0; + richTextBox1.Text = ""; + // + // btnCallAsync + // + btnCallAsync.Location = new Point(630, 67); + btnCallAsync.Name = "btnCallAsync"; + btnCallAsync.Size = new Size(106, 45); + btnCallAsync.TabIndex = 5; + btnCallAsync.Text = "异步调用"; + btnCallAsync.UseVisualStyleBackColor = true; + btnCallAsync.Click += btnCallAsync_Click; + // + // FrmMain + // + AutoScaleDimensions = new SizeF(10F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1155, 707); + Controls.Add(groupBox3); + Controls.Add(groupBox2); + Controls.Add(groupBox1); + Margin = new Padding(3, 2, 3, 2); + Name = "FrmMain"; + StartPosition = FormStartPosition.CenterScreen; + Text = "零代客户端"; + Load += FrmMain_Load; + groupBox1.ResumeLayout(false); + groupBox1.PerformLayout(); + groupBox2.ResumeLayout(false); + groupBox2.PerformLayout(); + groupBox3.ResumeLayout(false); + ResumeLayout(false); + } + + #endregion + + private GroupBox groupBox1; + private GroupBox groupBox2; + private Label label1; + private Button btnOpen; + private GroupBox groupBox3; + private RichTextBox richTextBox1; + private TextBox txtServer; + private Button btnCall; + private ComboBox cbApi; + private Label label2; + private TextBox textBox2; + private Label label3; + private Button btnOpenAsync; + private Button btnCallAsync; + } +} \ No newline at end of file diff --git a/Samples/Zero.Desktop/FrmMain.cs b/Samples/Zero.Desktop/FrmMain.cs new file mode 100644 index 000000000..de453b771 --- /dev/null +++ b/Samples/Zero.Desktop/FrmMain.cs @@ -0,0 +1,139 @@ +using System.Reflection; +using NewLife; +using NewLife.Log; +using NewLife.Reflection; +using NewLife.Remoting; +using NewLife.Threading; + +namespace Zero.Desktop; + +public partial class FrmMain : Form +{ + public FrmMain() + { + InitializeComponent(); + } + + private void FrmMain_Load(Object sender, EventArgs e) + { + var asm = AssemblyX.Create(Assembly.GetExecutingAssembly()); + Text = String.Format("{2} v{0} {1:HH:mm:ss}", asm.FileVersion, asm.Compile, Text); + + richTextBox1.UseWinFormControl(); + + _timer = new TimerX(OnBindConn, null, 1_000, 3_000); + } + + private TimerX _timer; + private ApiClient _client; + private String _lastConns; + private void OnBindConn(Object state) + { + //var keys = DAL.ConnStrs.Keys; + //var ks = keys.Join(","); + //if (ks == _lastConns) return; + //_lastConns = ks; + + //cbConns.DataSource = keys; + } + + private void btnOpen_Click(Object sender, EventArgs e) + { + var server = txtServer.Text; + if (server.IsNullOrEmpty()) return; + + var btn = sender as Button; + var btn2 = btnOpenAsync; + if (btn.Text == "打开") + { + var client = new ApiClient(server) + { + Log = XTrace.Log, + EncoderLog = XTrace.Log, + SocketLog = XTrace.Log + }; + client.Open(); + + var rs = client.Invoke("api/all", null); + cbApi.DataSource = rs; + + txtServer.Enabled = false; + groupBox2.Enabled = true; + btn.Text = "关闭"; + btn2.Text = "异步关闭"; + + _client = client; + } + else + { + _client.Close(btn.Text); + + txtServer.Enabled = true; + groupBox2.Enabled = false; + btn.Text = "打开"; + btn2.Text = "异步打开"; + } + } + + private async void btnAsyncOpen_Click(object sender, EventArgs e) + { + var server = txtServer.Text; + if (server.IsNullOrEmpty()) return; + + var btn = btnOpen; + var btn2 = sender as Button; + if (btn2.Text == "异步打开") + { + var client = new ApiClient(server) + { + Log = XTrace.Log, + EncoderLog = XTrace.Log, + SocketLog = XTrace.Log + }; + client.Open(); + + var rs = await client.InvokeAsync("api/all", null); + cbApi.DataSource = rs; + + txtServer.Enabled = false; + groupBox2.Enabled = true; + btn.Text = "关闭"; + btn2.Text = "异步关闭"; + + _client = client; + } + else + { + _client.Close(btn.Text); + + txtServer.Enabled = true; + groupBox2.Enabled = false; + btn.Text = "打开"; + btn2.Text = "异步打开"; + } + } + + private void listBox1_SelectedIndexChanged(Object sender, EventArgs e) + { + //var table = listBox1.SelectedItem as IDataTable; + //if (table == null) return; + + //var sql = $"select * from {table.TableName}"; + //var ds = _dal.Select(new SelectBuilder(sql), 0, 1000); + + //dataGridView1.DataSource = ds.Tables[0]; + //dataGridView1.Refresh(); + } + + private void btnCall_Click(object sender, EventArgs e) + { + var act = cbApi.Text.Substring(" ", "("); + var rs = _client.Invoke(act, null); + } + + private async void btnCallAsync_Click(object sender, EventArgs e) + { + var act = cbApi.Text.Substring(" ", "("); + var rs = await _client.InvokeAsync(act, null); + } +} \ No newline at end of file diff --git a/Samples/Zero.Desktop/FrmMain.resx b/Samples/Zero.Desktop/FrmMain.resx new file mode 100644 index 000000000..8b2ff64a1 --- /dev/null +++ b/Samples/Zero.Desktop/FrmMain.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/Zero.Desktop/Program.cs b/Samples/Zero.Desktop/Program.cs new file mode 100644 index 000000000..14dd759e5 --- /dev/null +++ b/Samples/Zero.Desktop/Program.cs @@ -0,0 +1,73 @@ +using System.Text; +using NewLife; +using NewLife.Log; +using NewLife.Model; +using Stardust; + +namespace Zero.Desktop; + +internal static class Program +{ + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // 支持GB2312编码 + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + + XTrace.UseWinForm(); + MachineInfo.RegisterAsync(); + + StartClient(); + + var set = ClientSetting.Current; + + // 启用语音提示 + StringHelper.EnableSpeechTip = set.SpeechTip; + + if (set.IsNew) "学无先后达者为师,欢迎使用新生命零代客户端!".SpeechTip(); + + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + //Application.EnableVisualStyles(); + //Application.SetCompatibleTextRenderingDefault(false); + //Application.SetHighDpiMode(HighDpiMode.SystemAware); + Application.Run(new FrmMain()); + } + + static StarFactory _factory; + static StarClient _Client; + private static void StartClient() + { + var set = ClientSetting.Current; + var server = set.Server; + if (server.IsNullOrEmpty()) return; + + XTrace.WriteLine("初始化服务端地址:{0}", server); + + _factory = new StarFactory(server, null, null) + { + Log = XTrace.Log, + }; + + var client = new StarClient(server) + { + Code = set.Code, + Secret = set.Secret, + ProductCode = _factory.AppId, + Setting = set, + + Tracer = _factory.Tracer, + Log = XTrace.Log, + }; + + client.Open(); + + Host.RegisterExit(() => client.Logout("ApplicationExit")); + + _Client = client; + } +} \ No newline at end of file diff --git a/Samples/Zero.Desktop/Zero.Desktop.csproj b/Samples/Zero.Desktop/Zero.Desktop.csproj new file mode 100644 index 000000000..f66f3e239 --- /dev/null +++ b/Samples/Zero.Desktop/Zero.Desktop.csproj @@ -0,0 +1,38 @@ + + + + WinExe + net9.0-windows + 客户端桌面应用 + CS架构的客户端桌面应用,给用户提供便捷操作,可对接硬件 + 新生命开发团队 + ©2002-2024 NewLife + 1.0 + $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) + $(VersionPrefix).$(VersionSuffix) + $(Version) + $(VersionPrefix).* + false + ..\..\Bin\Desktop + false + enable + latest + true + + true + false + SystemAware + Microsoft Sans Serif, 8.25pt + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Zero.Desktop/app.manifest b/Samples/Zero.Desktop/app.manifest new file mode 100644 index 000000000..2255841c4 --- /dev/null +++ b/Samples/Zero.Desktop/app.manifest @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/Zero.Desktop/appsettings.json b/Samples/Zero.Desktop/appsettings.json new file mode 100644 index 000000000..368e81f59 --- /dev/null +++ b/Samples/Zero.Desktop/appsettings.json @@ -0,0 +1,24 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + //"StarServer": "http://s.newlifex.com:6600", + //"RedisCache": "server=127.0.0.1:6379;password=;db=3", + //"RedisQueue": "server=127.0.0.1:6379;password=;db=5", + "ConnectionStrings": { + "Membership": "Data Source=..\\Data\\Membership.db;Provider=SQLite", + "Log": "Data Source=..\\Data\\Log.db;Provider=SQLite", + "Zero": "Data Source=..\\Data\\Zero.db;Provider=SQLite" + + // 各种数据库连接字符串模版,连接名Zero对应Zero.Data/Projects/Model.xml中的ConnName + //"Zero": "Server=.;Port=3306;Database=zero;Uid=root;Pwd=root;Provider=MySql", + //"Zero": "Data Source=.;Initial Catalog=zero;user=sa;password=sa;Provider=SqlServer", + //"Zero": "Server=.;Database=zero;Uid=root;Pwd=root;Provider=PostgreSql", + //"Zero": "Data Source=Tcp://127.0.0.1/ORCL;User Id=scott;Password=tiger;Provider=Oracle" + } +} diff --git a/X组件.sln b/X组件.sln index d38e0130f..df727b50e 100644 --- a/X组件.sln +++ b/X组件.sln @@ -33,6 +33,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zero.HttpServer", "Samples\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zero.EchoServer", "Samples\Zero.EchoServer\Zero.EchoServer.csproj", "{71469BB2-4B27-4524-8488-7DCDF67DBDA3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zero.Desktop", "Samples\Zero.Desktop\Zero.Desktop.csproj", "{1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -135,6 +137,18 @@ Global {71469BB2-4B27-4524-8488-7DCDF67DBDA3}.Release|iPhone.Build.0 = Release|Any CPU {71469BB2-4B27-4524-8488-7DCDF67DBDA3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {71469BB2-4B27-4524-8488-7DCDF67DBDA3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Debug|iPhone.Build.0 = Debug|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Release|Any CPU.Build.0 = Release|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Release|iPhone.ActiveCfg = Release|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Release|iPhone.Build.0 = Release|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47}.Release|iPhoneSimulator.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -144,6 +158,7 @@ Global {CA03BB57-CBB4-41DF-B2F4-462A8C91E3C4} = {ED6D680E-7AE3-4C2C-9464-907B0538D176} {E9707BD6-9EF9-41A7-AE11-2B35CC9E6878} = {ED6D680E-7AE3-4C2C-9464-907B0538D176} {71469BB2-4B27-4524-8488-7DCDF67DBDA3} = {ED6D680E-7AE3-4C2C-9464-907B0538D176} + {1A6F2E63-1881-4D74-AD0A-7EAB1164AD47} = {ED6D680E-7AE3-4C2C-9464-907B0538D176} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6AEA440B-0D90-4F6E-BA9A-D42B27A78D7B}