适配跨平台,winform乱码

This commit is contained in:
snltty
2023-11-29 17:17:58 +08:00
parent 5b1d063dc6
commit 1f0bfa6dc6
124 changed files with 3885 additions and 1628 deletions

View File

@@ -69,308 +69,196 @@
//
// serverIP
//
serverIP.Location = new Point(106, 76);
resources.ApplyResources(serverIP, "serverIP");
serverIP.Name = "serverIP";
serverIP.Size = new Size(100, 23);
serverIP.TabIndex = 0;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(32, 80);
resources.ApplyResources(label1, "label1");
label1.Name = "label1";
label1.Size = new Size(55, 17);
label1.TabIndex = 1;
label1.Text = "服务端IP";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(223, 80);
resources.ApplyResources(label2, "label2");
label2.Name = "label2";
label2.Size = new Size(68, 17);
label2.TabIndex = 3;
label2.Text = "服务端端口";
//
// serverPort
//
serverPort.Location = new Point(294, 76);
resources.ApplyResources(serverPort, "serverPort");
serverPort.Name = "serverPort";
serverPort.Size = new Size(100, 23);
serverPort.TabIndex = 2;
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(232, 106);
resources.ApplyResources(label3, "label3");
label3.Name = "label3";
label3.Size = new Size(56, 17);
label3.TabIndex = 7;
label3.Text = "web端口";
//
// webPort
//
webPort.Location = new Point(294, 102);
resources.ApplyResources(webPort, "webPort");
webPort.Name = "webPort";
webPort.Size = new Size(100, 23);
webPort.TabIndex = 6;
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(23, 106);
resources.ApplyResources(label4, "label4");
label4.Name = "label4";
label4.Size = new Size(80, 17);
label4.TabIndex = 5;
label4.Text = "管理接口端口";
//
// apiPort
//
apiPort.Location = new Point(106, 102);
resources.ApplyResources(apiPort, "apiPort");
apiPort.Name = "apiPort";
apiPort.Size = new Size(100, 23);
apiPort.TabIndex = 4;
//
// modeClient
//
modeClient.AutoSize = true;
modeClient.Location = new Point(156, 21);
resources.ApplyResources(modeClient, "modeClient");
modeClient.Name = "modeClient";
modeClient.Size = new Size(63, 21);
modeClient.TabIndex = 8;
modeClient.Text = "客户端";
modeClient.UseVisualStyleBackColor = true;
//
// modeServer
//
modeServer.AutoSize = true;
modeServer.Location = new Point(219, 22);
resources.ApplyResources(modeServer, "modeServer");
modeServer.Name = "modeServer";
modeServer.Size = new Size(63, 21);
modeServer.TabIndex = 9;
modeServer.Text = "服务端";
modeServer.UseVisualStyleBackColor = true;
//
// label5
//
label5.AutoSize = true;
label5.Location = new Point(41, 253);
resources.ApplyResources(label5, "label5");
label5.Name = "label5";
label5.Size = new Size(56, 17);
label5.TabIndex = 14;
label5.Text = "数据数量";
//
// shareLen
//
shareLen.Location = new Point(106, 249);
resources.ApplyResources(shareLen, "shareLen");
shareLen.Name = "shareLen";
shareLen.Size = new Size(100, 23);
shareLen.TabIndex = 13;
//
// label6
//
label6.AutoSize = true;
label6.Location = new Point(27, 226);
resources.ApplyResources(label6, "label6");
label6.Name = "label6";
label6.Size = new Size(68, 17);
label6.TabIndex = 12;
label6.Text = "共享数据键";
//
// shareKey
//
shareKey.Location = new Point(106, 222);
resources.ApplyResources(shareKey, "shareKey");
shareKey.Name = "shareKey";
shareKey.Size = new Size(100, 23);
shareKey.TabIndex = 11;
//
// label7
//
label7.AutoSize = true;
label7.Location = new Point(225, 280);
resources.ApplyResources(label7, "label7");
label7.Name = "label7";
label7.Size = new Size(68, 17);
label7.TabIndex = 18;
label7.Text = "壁纸键下标";
//
// wallpaperIndex
//
wallpaperIndex.Location = new Point(294, 276);
resources.ApplyResources(wallpaperIndex, "wallpaperIndex");
wallpaperIndex.Name = "wallpaperIndex";
wallpaperIndex.Size = new Size(100, 23);
wallpaperIndex.TabIndex = 17;
//
// label8
//
label8.AutoSize = true;
label8.Location = new Point(27, 280);
resources.ApplyResources(label8, "label8");
label8.Name = "label8";
label8.Size = new Size(68, 17);
label8.TabIndex = 16;
label8.Text = "键盘键下标";
//
// keyboardIndex
//
keyboardIndex.Location = new Point(106, 276);
resources.ApplyResources(keyboardIndex, "keyboardIndex");
keyboardIndex.Name = "keyboardIndex";
keyboardIndex.Size = new Size(100, 23);
keyboardIndex.TabIndex = 15;
//
// label9
//
label9.AutoSize = true;
label9.Location = new Point(27, 307);
resources.ApplyResources(label9, "label9");
label9.Name = "label9";
label9.Size = new Size(68, 17);
label9.TabIndex = 20;
label9.Text = "锁屏键下标";
//
// llockIndex
//
llockIndex.Location = new Point(106, 303);
resources.ApplyResources(llockIndex, "llockIndex");
llockIndex.Name = "llockIndex";
llockIndex.Size = new Size(100, 23);
llockIndex.TabIndex = 19;
//
// label10
//
label10.AutoSize = true;
label10.Location = new Point(227, 306);
resources.ApplyResources(label10, "label10");
label10.Name = "label10";
label10.Size = new Size(66, 17);
label10.TabIndex = 22;
label10.Text = "SAS键下标";
//
// sasIndex
//
sasIndex.Location = new Point(294, 302);
resources.ApplyResources(sasIndex, "sasIndex");
sasIndex.Name = "sasIndex";
sasIndex.Size = new Size(100, 23);
sasIndex.TabIndex = 21;
//
// label11
//
label11.AutoSize = true;
label11.Location = new Point(36, 53);
resources.ApplyResources(label11, "label11");
label11.Name = "label11";
label11.Size = new Size(44, 17);
label11.TabIndex = 24;
label11.Text = "机器名";
//
// machineName
//
machineName.Location = new Point(106, 49);
resources.ApplyResources(machineName, "machineName");
machineName.Name = "machineName";
machineName.Size = new Size(100, 23);
machineName.TabIndex = 23;
//
// label12
//
label12.AutoSize = true;
label12.Location = new Point(220, 154);
resources.ApplyResources(label12, "label12");
label12.Name = "label12";
label12.Size = new Size(73, 17);
label12.TabIndex = 28;
label12.Text = "截屏间隔ms";
//
// screenDelay
//
screenDelay.Location = new Point(294, 150);
resources.ApplyResources(screenDelay, "screenDelay");
screenDelay.Name = "screenDelay";
screenDelay.Size = new Size(100, 23);
screenDelay.TabIndex = 27;
//
// label13
//
label13.AutoSize = true;
label13.Location = new Point(27, 154);
resources.ApplyResources(label13, "label13");
label13.Name = "label13";
label13.Size = new Size(73, 17);
label13.TabIndex = 26;
label13.Text = "报告间隔ms";
//
// reportDelay
//
reportDelay.Location = new Point(106, 150);
resources.ApplyResources(reportDelay, "reportDelay");
reportDelay.Name = "reportDelay";
reportDelay.Size = new Size(100, 23);
reportDelay.TabIndex = 25;
//
// label14
//
label14.AutoSize = true;
label14.Location = new Point(20, 181);
resources.ApplyResources(label14, "label14");
label14.Name = "label14";
label14.Size = new Size(80, 17);
label14.TabIndex = 30;
label14.Text = "截屏缩放比例";
//
// screenScale
//
screenScale.Location = new Point(106, 177);
resources.ApplyResources(screenScale, "screenScale");
screenScale.Name = "screenScale";
screenScale.Size = new Size(100, 23);
screenScale.TabIndex = 29;
//
// installBtn
//
installBtn.Location = new Point(201, 372);
resources.ApplyResources(installBtn, "installBtn");
installBtn.Name = "installBtn";
installBtn.Size = new Size(81, 35);
installBtn.TabIndex = 31;
installBtn.Text = "安装自启动";
installBtn.UseVisualStyleBackColor = true;
installBtn.Click += OnInstallClick;
//
// label15
//
label15.Location = new Point(22, 337);
resources.ApplyResources(label15, "label15");
label15.Name = "label15";
label15.Size = new Size(372, 23);
label15.TabIndex = 32;
label15.Text = "每项255长度0项保留不可用";
label15.TextAlign = ContentAlignment.MiddleCenter;
//
// runBtn
//
runBtn.Location = new Point(114, 372);
resources.ApplyResources(runBtn, "runBtn");
runBtn.Name = "runBtn";
runBtn.Size = new Size(81, 35);
runBtn.TabIndex = 33;
runBtn.Text = "停止运行";
runBtn.UseVisualStyleBackColor = true;
runBtn.Click += RunClick;
//
// checkStateBtn
//
checkStateBtn.Location = new Point(331, 378);
resources.ApplyResources(checkStateBtn, "checkStateBtn");
checkStateBtn.Name = "checkStateBtn";
checkStateBtn.Size = new Size(75, 23);
checkStateBtn.TabIndex = 34;
checkStateBtn.Text = "检查状态";
checkStateBtn.UseVisualStyleBackColor = true;
checkStateBtn.Click += checkStateBtn_Click;
//
// label16
//
label16.AutoSize = true;
label16.Location = new Point(211, 253);
resources.ApplyResources(label16, "label16");
label16.Name = "label16";
label16.Size = new Size(80, 17);
label16.TabIndex = 36;
label16.Text = "每项数据长度";
//
// shareItemLen
//
shareItemLen.Location = new Point(294, 249);
resources.ApplyResources(shareItemLen, "shareItemLen");
shareItemLen.Name = "shareItemLen";
shareItemLen.Size = new Size(100, 23);
shareItemLen.TabIndex = 35;
//
// MainForm
//
AutoScaleDimensions = new SizeF(7F, 17F);
resources.ApplyResources(this, "$this");
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(418, 420);
Controls.Add(label16);
Controls.Add(shareItemLen);
Controls.Add(checkStateBtn);
@@ -407,9 +295,7 @@
Controls.Add(serverPort);
Controls.Add(label1);
Controls.Add(serverIP);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "MainForm";
Text = "cmonitor安装工具";
Load += OnLoad;
ResumeLayout(false);
PerformLayout();

View File

@@ -2,6 +2,7 @@ using common.libs;
using Microsoft.Win32;
using System.Diagnostics;
using System.Net;
using System.Text;
namespace cmonitor.install.win
{
@@ -132,12 +133,13 @@ namespace cmonitor.install.win
string shareKeyStr = shareKey.Text;
string shareLenStr = shareLen.Text;
string shareItemLenStr = shareItemLen.Text;
Task.Run(() =>
{
if (installed == false)
{
string taskStr = $"sc create \"{serviceName}\" binpath=\"{sasPath} {shareKeyStr} {shareLenStr} 255 {sasIndexStr} \\\"{paramStr}\\\"\" start=AUTO";
string taskStr = $"sc create \"{serviceName}\" binpath=\"{sasPath} {shareKeyStr} {shareLenStr} {shareItemLenStr} {sasIndexStr} \\\"{paramStr}\\\"\" start=AUTO";
CommandHelper.Windows(string.Empty, new string[] {
taskStr,
$"net start {serviceName}",
@@ -168,7 +170,7 @@ namespace cmonitor.install.win
{
if (modeClient.Checked == false && modeServer.Checked == false)
{
MessageBox.Show("<EFBFBD>ͻ<EFBFBD><EFBFBD>˺ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˱<EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("客户端和服务端必须选择一样!");
return false;
}
List<string> modeStr = new List<string>();
@@ -188,22 +190,22 @@ namespace cmonitor.install.win
{
if (string.IsNullOrWhiteSpace(serverIP.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ip<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("服务器ip必填");
return false;
}
if (string.IsNullOrWhiteSpace(serverPort.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿ڱ<EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("服务器端口必填");
return false;
}
if (string.IsNullOrWhiteSpace(apiPort.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿ڱ<EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("管理端口必填");
return false;
}
if (string.IsNullOrWhiteSpace(webPort.Text))
{
MessageBox.Show("web<EFBFBD>˿ڱ<EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("web端口必填");
return false;
}
installParams.Add($"--server {serverIP.Text}");
@@ -217,17 +219,17 @@ namespace cmonitor.install.win
{
if (string.IsNullOrWhiteSpace(reportDelay.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("报告间隔时间必填");
return false;
}
if (string.IsNullOrWhiteSpace(screenDelay.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("截屏间隔时间必填");
return false;
}
if (string.IsNullOrWhiteSpace(screenScale.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("截屏缩放比例必填");
return false;
}
installParams.Add($"--report-delay {reportDelay.Text}");
@@ -240,37 +242,37 @@ namespace cmonitor.install.win
{
if (string.IsNullOrWhiteSpace(shareKey.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("共享数据键必填");
return false;
}
if (string.IsNullOrWhiteSpace(shareLen.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("共享数量必填");
return false;
}
if (string.IsNullOrWhiteSpace(shareItemLen.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("共享每项数据长度必填");
return false;
}
if (string.IsNullOrWhiteSpace(keyboardIndex.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><EFBFBD>±<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("键盘键下标必填");
return false;
}
if (string.IsNullOrWhiteSpace(wallpaperIndex.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("壁纸键下标必填");
return false;
}
if (string.IsNullOrWhiteSpace(llockIndex.Text))
{
MessageBox.Show("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("锁屏键下标必填");
return false;
}
if (string.IsNullOrWhiteSpace(sasIndex.Text))
{
MessageBox.Show("sas<EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
MessageBox.Show("sas键下标必填");
return false;
}
installParams.Add($"--share-key {shareKey.Text}");
@@ -287,35 +289,35 @@ namespace cmonitor.install.win
{
if (loading)
{
installBtn.Text = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..";
runBtn.Text = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..";
checkStateBtn.Text = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..";
installBtn.Text = "操作中..";
runBtn.Text = "操作中..";
checkStateBtn.Text = "操作中..";
}
else
{
checkStateBtn.Text = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬";
checkStateBtn.Text = "检查状态";
if (installed)
{
installBtn.ForeColor = Color.Red;
installBtn.Text = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
installBtn.Text = "解除自启动";
runBtn.Enabled = true;
}
else
{
installBtn.ForeColor = Color.Black;
installBtn.Text = "<EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
installBtn.Text = "安装自启动";
runBtn.Enabled = false;
}
if (running)
{
runBtn.ForeColor = Color.Red;
runBtn.Text = "ֹͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
runBtn.Text = "停止运行";
}
else
{
runBtn.ForeColor = Color.Black;
runBtn.Text = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
runBtn.Text = "启动";
}
}
}));

View File

@@ -118,6 +118,892 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="serverIP.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 76</value>
</data>
<data name="serverIP.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="serverIP.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;serverIP.Name" xml:space="preserve">
<value>serverIP</value>
</data>
<data name="&gt;&gt;serverIP.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;serverIP.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;serverIP.ZOrder" xml:space="preserve">
<value>35</value>
</data>
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
<value>32, 80</value>
</data>
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
<value>55, 17</value>
</data>
<data name="label1.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>服务端IP</value>
</data>
<data name="&gt;&gt;label1.Name" xml:space="preserve">
<value>label1</value>
</data>
<data name="&gt;&gt;label1.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
<value>34</value>
</data>
<data name="label2.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
<value>223, 80</value>
</data>
<data name="label2.Size" type="System.Drawing.Size, System.Drawing">
<value>68, 17</value>
</data>
<data name="label2.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>服务端端口</value>
</data>
<data name="&gt;&gt;label2.Name" xml:space="preserve">
<value>label2</value>
</data>
<data name="&gt;&gt;label2.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label2.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label2.ZOrder" xml:space="preserve">
<value>32</value>
</data>
<data name="serverPort.Location" type="System.Drawing.Point, System.Drawing">
<value>294, 76</value>
</data>
<data name="serverPort.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="serverPort.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;serverPort.Name" xml:space="preserve">
<value>serverPort</value>
</data>
<data name="&gt;&gt;serverPort.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;serverPort.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;serverPort.ZOrder" xml:space="preserve">
<value>33</value>
</data>
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
<value>232, 106</value>
</data>
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
<value>56, 17</value>
</data>
<data name="label3.TabIndex" type="System.Int32, mscorlib">
<value>7</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>web端口</value>
</data>
<data name="&gt;&gt;label3.Name" xml:space="preserve">
<value>label3</value>
</data>
<data name="&gt;&gt;label3.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label3.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label3.ZOrder" xml:space="preserve">
<value>28</value>
</data>
<data name="webPort.Location" type="System.Drawing.Point, System.Drawing">
<value>294, 102</value>
</data>
<data name="webPort.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="webPort.TabIndex" type="System.Int32, mscorlib">
<value>6</value>
</data>
<data name="&gt;&gt;webPort.Name" xml:space="preserve">
<value>webPort</value>
</data>
<data name="&gt;&gt;webPort.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;webPort.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;webPort.ZOrder" xml:space="preserve">
<value>29</value>
</data>
<data name="label4.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
<value>23, 106</value>
</data>
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
<value>80, 17</value>
</data>
<data name="label4.TabIndex" type="System.Int32, mscorlib">
<value>5</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>管理接口端口</value>
</data>
<data name="&gt;&gt;label4.Name" xml:space="preserve">
<value>label4</value>
</data>
<data name="&gt;&gt;label4.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label4.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label4.ZOrder" xml:space="preserve">
<value>30</value>
</data>
<data name="apiPort.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 102</value>
</data>
<data name="apiPort.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="apiPort.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="&gt;&gt;apiPort.Name" xml:space="preserve">
<value>apiPort</value>
</data>
<data name="&gt;&gt;apiPort.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;apiPort.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;apiPort.ZOrder" xml:space="preserve">
<value>31</value>
</data>
<data name="modeClient.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="modeClient.Location" type="System.Drawing.Point, System.Drawing">
<value>156, 21</value>
</data>
<data name="modeClient.Size" type="System.Drawing.Size, System.Drawing">
<value>63, 21</value>
</data>
<data name="modeClient.TabIndex" type="System.Int32, mscorlib">
<value>8</value>
</data>
<data name="modeClient.Text" xml:space="preserve">
<value>客户端</value>
</data>
<data name="&gt;&gt;modeClient.Name" xml:space="preserve">
<value>modeClient</value>
</data>
<data name="&gt;&gt;modeClient.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;modeClient.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;modeClient.ZOrder" xml:space="preserve">
<value>27</value>
</data>
<data name="modeServer.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="modeServer.Location" type="System.Drawing.Point, System.Drawing">
<value>219, 22</value>
</data>
<data name="modeServer.Size" type="System.Drawing.Size, System.Drawing">
<value>63, 21</value>
</data>
<data name="modeServer.TabIndex" type="System.Int32, mscorlib">
<value>9</value>
</data>
<data name="modeServer.Text" xml:space="preserve">
<value>服务端</value>
</data>
<data name="&gt;&gt;modeServer.Name" xml:space="preserve">
<value>modeServer</value>
</data>
<data name="&gt;&gt;modeServer.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;modeServer.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;modeServer.ZOrder" xml:space="preserve">
<value>26</value>
</data>
<data name="label5.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label5.Location" type="System.Drawing.Point, System.Drawing">
<value>41, 253</value>
</data>
<data name="label5.Size" type="System.Drawing.Size, System.Drawing">
<value>56, 17</value>
</data>
<data name="label5.TabIndex" type="System.Int32, mscorlib">
<value>14</value>
</data>
<data name="label5.Text" xml:space="preserve">
<value>数据数量</value>
</data>
<data name="&gt;&gt;label5.Name" xml:space="preserve">
<value>label5</value>
</data>
<data name="&gt;&gt;label5.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label5.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label5.ZOrder" xml:space="preserve">
<value>22</value>
</data>
<data name="shareLen.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 249</value>
</data>
<data name="shareLen.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="shareLen.TabIndex" type="System.Int32, mscorlib">
<value>13</value>
</data>
<data name="&gt;&gt;shareLen.Name" xml:space="preserve">
<value>shareLen</value>
</data>
<data name="&gt;&gt;shareLen.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;shareLen.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;shareLen.ZOrder" xml:space="preserve">
<value>23</value>
</data>
<data name="label6.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label6.Location" type="System.Drawing.Point, System.Drawing">
<value>27, 226</value>
</data>
<data name="label6.Size" type="System.Drawing.Size, System.Drawing">
<value>68, 17</value>
</data>
<data name="label6.TabIndex" type="System.Int32, mscorlib">
<value>12</value>
</data>
<data name="label6.Text" xml:space="preserve">
<value>共享数据键</value>
</data>
<data name="&gt;&gt;label6.Name" xml:space="preserve">
<value>label6</value>
</data>
<data name="&gt;&gt;label6.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label6.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label6.ZOrder" xml:space="preserve">
<value>24</value>
</data>
<data name="shareKey.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 222</value>
</data>
<data name="shareKey.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="shareKey.TabIndex" type="System.Int32, mscorlib">
<value>11</value>
</data>
<data name="&gt;&gt;shareKey.Name" xml:space="preserve">
<value>shareKey</value>
</data>
<data name="&gt;&gt;shareKey.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;shareKey.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;shareKey.ZOrder" xml:space="preserve">
<value>25</value>
</data>
<data name="label7.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label7.Location" type="System.Drawing.Point, System.Drawing">
<value>225, 280</value>
</data>
<data name="label7.Size" type="System.Drawing.Size, System.Drawing">
<value>68, 17</value>
</data>
<data name="label7.TabIndex" type="System.Int32, mscorlib">
<value>18</value>
</data>
<data name="label7.Text" xml:space="preserve">
<value>壁纸键下标</value>
</data>
<data name="&gt;&gt;label7.Name" xml:space="preserve">
<value>label7</value>
</data>
<data name="&gt;&gt;label7.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label7.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label7.ZOrder" xml:space="preserve">
<value>18</value>
</data>
<data name="wallpaperIndex.Location" type="System.Drawing.Point, System.Drawing">
<value>294, 276</value>
</data>
<data name="wallpaperIndex.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="wallpaperIndex.TabIndex" type="System.Int32, mscorlib">
<value>17</value>
</data>
<data name="&gt;&gt;wallpaperIndex.Name" xml:space="preserve">
<value>wallpaperIndex</value>
</data>
<data name="&gt;&gt;wallpaperIndex.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;wallpaperIndex.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;wallpaperIndex.ZOrder" xml:space="preserve">
<value>19</value>
</data>
<data name="label8.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label8.Location" type="System.Drawing.Point, System.Drawing">
<value>27, 280</value>
</data>
<data name="label8.Size" type="System.Drawing.Size, System.Drawing">
<value>68, 17</value>
</data>
<data name="label8.TabIndex" type="System.Int32, mscorlib">
<value>16</value>
</data>
<data name="label8.Text" xml:space="preserve">
<value>键盘键下标</value>
</data>
<data name="&gt;&gt;label8.Name" xml:space="preserve">
<value>label8</value>
</data>
<data name="&gt;&gt;label8.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label8.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label8.ZOrder" xml:space="preserve">
<value>20</value>
</data>
<data name="keyboardIndex.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 276</value>
</data>
<data name="keyboardIndex.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="keyboardIndex.TabIndex" type="System.Int32, mscorlib">
<value>15</value>
</data>
<data name="&gt;&gt;keyboardIndex.Name" xml:space="preserve">
<value>keyboardIndex</value>
</data>
<data name="&gt;&gt;keyboardIndex.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;keyboardIndex.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;keyboardIndex.ZOrder" xml:space="preserve">
<value>21</value>
</data>
<data name="label9.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label9.Location" type="System.Drawing.Point, System.Drawing">
<value>27, 307</value>
</data>
<data name="label9.Size" type="System.Drawing.Size, System.Drawing">
<value>68, 17</value>
</data>
<data name="label9.TabIndex" type="System.Int32, mscorlib">
<value>20</value>
</data>
<data name="label9.Text" xml:space="preserve">
<value>锁屏键下标</value>
</data>
<data name="&gt;&gt;label9.Name" xml:space="preserve">
<value>label9</value>
</data>
<data name="&gt;&gt;label9.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label9.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label9.ZOrder" xml:space="preserve">
<value>16</value>
</data>
<data name="llockIndex.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 303</value>
</data>
<data name="llockIndex.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="llockIndex.TabIndex" type="System.Int32, mscorlib">
<value>19</value>
</data>
<data name="&gt;&gt;llockIndex.Name" xml:space="preserve">
<value>llockIndex</value>
</data>
<data name="&gt;&gt;llockIndex.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;llockIndex.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;llockIndex.ZOrder" xml:space="preserve">
<value>17</value>
</data>
<data name="label10.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label10.Location" type="System.Drawing.Point, System.Drawing">
<value>227, 306</value>
</data>
<data name="label10.Size" type="System.Drawing.Size, System.Drawing">
<value>66, 17</value>
</data>
<data name="label10.TabIndex" type="System.Int32, mscorlib">
<value>22</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>SAS键下标</value>
</data>
<data name="&gt;&gt;label10.Name" xml:space="preserve">
<value>label10</value>
</data>
<data name="&gt;&gt;label10.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label10.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label10.ZOrder" xml:space="preserve">
<value>14</value>
</data>
<data name="sasIndex.Location" type="System.Drawing.Point, System.Drawing">
<value>294, 302</value>
</data>
<data name="sasIndex.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="sasIndex.TabIndex" type="System.Int32, mscorlib">
<value>21</value>
</data>
<data name="&gt;&gt;sasIndex.Name" xml:space="preserve">
<value>sasIndex</value>
</data>
<data name="&gt;&gt;sasIndex.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;sasIndex.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;sasIndex.ZOrder" xml:space="preserve">
<value>15</value>
</data>
<data name="label11.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label11.Location" type="System.Drawing.Point, System.Drawing">
<value>36, 53</value>
</data>
<data name="label11.Size" type="System.Drawing.Size, System.Drawing">
<value>44, 17</value>
</data>
<data name="label11.TabIndex" type="System.Int32, mscorlib">
<value>24</value>
</data>
<data name="label11.Text" xml:space="preserve">
<value>机器名</value>
</data>
<data name="&gt;&gt;label11.Name" xml:space="preserve">
<value>label11</value>
</data>
<data name="&gt;&gt;label11.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label11.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label11.ZOrder" xml:space="preserve">
<value>12</value>
</data>
<data name="machineName.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 49</value>
</data>
<data name="machineName.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="machineName.TabIndex" type="System.Int32, mscorlib">
<value>23</value>
</data>
<data name="&gt;&gt;machineName.Name" xml:space="preserve">
<value>machineName</value>
</data>
<data name="&gt;&gt;machineName.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;machineName.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;machineName.ZOrder" xml:space="preserve">
<value>13</value>
</data>
<data name="label12.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label12.Location" type="System.Drawing.Point, System.Drawing">
<value>220, 154</value>
</data>
<data name="label12.Size" type="System.Drawing.Size, System.Drawing">
<value>73, 17</value>
</data>
<data name="label12.TabIndex" type="System.Int32, mscorlib">
<value>28</value>
</data>
<data name="label12.Text" xml:space="preserve">
<value>截屏间隔ms</value>
</data>
<data name="&gt;&gt;label12.Name" xml:space="preserve">
<value>label12</value>
</data>
<data name="&gt;&gt;label12.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label12.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label12.ZOrder" xml:space="preserve">
<value>8</value>
</data>
<data name="screenDelay.Location" type="System.Drawing.Point, System.Drawing">
<value>294, 150</value>
</data>
<data name="screenDelay.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="screenDelay.TabIndex" type="System.Int32, mscorlib">
<value>27</value>
</data>
<data name="&gt;&gt;screenDelay.Name" xml:space="preserve">
<value>screenDelay</value>
</data>
<data name="&gt;&gt;screenDelay.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;screenDelay.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;screenDelay.ZOrder" xml:space="preserve">
<value>9</value>
</data>
<data name="label13.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label13.Location" type="System.Drawing.Point, System.Drawing">
<value>27, 154</value>
</data>
<data name="label13.Size" type="System.Drawing.Size, System.Drawing">
<value>73, 17</value>
</data>
<data name="label13.TabIndex" type="System.Int32, mscorlib">
<value>26</value>
</data>
<data name="label13.Text" xml:space="preserve">
<value>报告间隔ms</value>
</data>
<data name="&gt;&gt;label13.Name" xml:space="preserve">
<value>label13</value>
</data>
<data name="&gt;&gt;label13.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label13.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label13.ZOrder" xml:space="preserve">
<value>10</value>
</data>
<data name="reportDelay.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 150</value>
</data>
<data name="reportDelay.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="reportDelay.TabIndex" type="System.Int32, mscorlib">
<value>25</value>
</data>
<data name="&gt;&gt;reportDelay.Name" xml:space="preserve">
<value>reportDelay</value>
</data>
<data name="&gt;&gt;reportDelay.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;reportDelay.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;reportDelay.ZOrder" xml:space="preserve">
<value>11</value>
</data>
<data name="label14.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label14.Location" type="System.Drawing.Point, System.Drawing">
<value>20, 181</value>
</data>
<data name="label14.Size" type="System.Drawing.Size, System.Drawing">
<value>80, 17</value>
</data>
<data name="label14.TabIndex" type="System.Int32, mscorlib">
<value>30</value>
</data>
<data name="label14.Text" xml:space="preserve">
<value>截屏缩放比例</value>
</data>
<data name="&gt;&gt;label14.Name" xml:space="preserve">
<value>label14</value>
</data>
<data name="&gt;&gt;label14.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label14.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label14.ZOrder" xml:space="preserve">
<value>6</value>
</data>
<data name="screenScale.Location" type="System.Drawing.Point, System.Drawing">
<value>106, 177</value>
</data>
<data name="screenScale.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="screenScale.TabIndex" type="System.Int32, mscorlib">
<value>29</value>
</data>
<data name="&gt;&gt;screenScale.Name" xml:space="preserve">
<value>screenScale</value>
</data>
<data name="&gt;&gt;screenScale.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;screenScale.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;screenScale.ZOrder" xml:space="preserve">
<value>7</value>
</data>
<data name="installBtn.Location" type="System.Drawing.Point, System.Drawing">
<value>201, 372</value>
</data>
<data name="installBtn.Size" type="System.Drawing.Size, System.Drawing">
<value>81, 35</value>
</data>
<data name="installBtn.TabIndex" type="System.Int32, mscorlib">
<value>31</value>
</data>
<data name="installBtn.Text" xml:space="preserve">
<value>安装自启动</value>
</data>
<data name="&gt;&gt;installBtn.Name" xml:space="preserve">
<value>installBtn</value>
</data>
<data name="&gt;&gt;installBtn.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;installBtn.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;installBtn.ZOrder" xml:space="preserve">
<value>5</value>
</data>
<data name="label15.Location" type="System.Drawing.Point, System.Drawing">
<value>22, 337</value>
</data>
<data name="label15.Size" type="System.Drawing.Size, System.Drawing">
<value>372, 23</value>
</data>
<data name="label15.TabIndex" type="System.Int32, mscorlib">
<value>32</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>每项255长度0项保留不可用</value>
</data>
<data name="label15.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleCenter</value>
</data>
<data name="&gt;&gt;label15.Name" xml:space="preserve">
<value>label15</value>
</data>
<data name="&gt;&gt;label15.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label15.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label15.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="runBtn.Location" type="System.Drawing.Point, System.Drawing">
<value>114, 372</value>
</data>
<data name="runBtn.Size" type="System.Drawing.Size, System.Drawing">
<value>81, 35</value>
</data>
<data name="runBtn.TabIndex" type="System.Int32, mscorlib">
<value>33</value>
</data>
<data name="runBtn.Text" xml:space="preserve">
<value>停止运行</value>
</data>
<data name="&gt;&gt;runBtn.Name" xml:space="preserve">
<value>runBtn</value>
</data>
<data name="&gt;&gt;runBtn.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;runBtn.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;runBtn.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="checkStateBtn.Location" type="System.Drawing.Point, System.Drawing">
<value>331, 378</value>
</data>
<data name="checkStateBtn.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
</data>
<data name="checkStateBtn.TabIndex" type="System.Int32, mscorlib">
<value>34</value>
</data>
<data name="checkStateBtn.Text" xml:space="preserve">
<value>检查状态</value>
</data>
<data name="&gt;&gt;checkStateBtn.Name" xml:space="preserve">
<value>checkStateBtn</value>
</data>
<data name="&gt;&gt;checkStateBtn.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;checkStateBtn.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;checkStateBtn.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="label16.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label16.Location" type="System.Drawing.Point, System.Drawing">
<value>211, 253</value>
</data>
<data name="label16.Size" type="System.Drawing.Size, System.Drawing">
<value>80, 17</value>
</data>
<data name="label16.TabIndex" type="System.Int32, mscorlib">
<value>36</value>
</data>
<data name="label16.Text" xml:space="preserve">
<value>每项数据长度</value>
</data>
<data name="&gt;&gt;label16.Name" xml:space="preserve">
<value>label16</value>
</data>
<data name="&gt;&gt;label16.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label16.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label16.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="shareItemLen.Location" type="System.Drawing.Point, System.Drawing">
<value>294, 249</value>
</data>
<data name="shareItemLen.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="shareItemLen.TabIndex" type="System.Int32, mscorlib">
<value>35</value>
</data>
<data name="&gt;&gt;shareItemLen.Name" xml:space="preserve">
<value>shareItemLen</value>
</data>
<data name="&gt;&gt;shareItemLen.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;shareItemLen.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;shareItemLen.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<metadata name="$this.Language" type="System.Globalization.CultureInfo, System.Private.CoreLib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
<value>zh-Hans</value>
</metadata>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>7, 17</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>418, 420</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAAAAAAAEAIABdQAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAEAAAABAAgGAAAAXHKoZgAAQCRJ
@@ -397,4 +1283,13 @@
lbj4VzZ7T6Ce2eKyfeTF92Tj/y+1yov7XH58jUaj0Wg0Gk2v5P8D5M/bzdE8cNIAAAAASUVORK5CYII=
</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>cmonitor安装工具</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>MainForm</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,15 @@
namespace cmonitor.libs
{
internal interface IShareMemory
{
public bool Init();
public byte ReadByte(int position);
public void WriteByte(int position, byte value);
public int ReadInt(int position);
public void WriteInt(int position, int value);
public void ReadArray(int position, byte[] bytes, int offset, int length);
public void WriteArray(int position, byte[] data, int offset, int length);
}
}

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -20,10 +19,8 @@ namespace cmonitor.libs
private int itemSize;
private byte[] bytes;
private object lockObj = new object();
MemoryMappedFile mmfLocal = null;
MemoryMappedViewAccessor accessorLocal = null;
MemoryMappedFile mmfGlobal = null;
MemoryMappedViewAccessor accessorGlobal = null;
IShareMemory accessorLocal = null;
IShareMemory accessorGlobal = null;
Action<int, ShareMemoryState> stateAction;
@@ -41,10 +38,13 @@ namespace cmonitor.libs
{
try
{
if (OperatingSystem.IsWindows() && accessorLocal == null)
if (accessorLocal == null)
{
mmfLocal = MemoryMappedFile.CreateOrOpen($"{key}", bytes.Length);
accessorLocal = mmfLocal.CreateViewAccessor();
accessorLocal = ShareMemoryFactory.Create(key, length, itemSize);
if (accessorLocal.Init() == false)
{
accessorLocal = null;
}
}
}
catch (Exception)
@@ -57,8 +57,11 @@ namespace cmonitor.libs
{
if (OperatingSystem.IsWindows() && accessorGlobal == null)
{
mmfGlobal = MemoryMappedFile.CreateOrOpen($"Global\\{key}", bytes.Length);
accessorGlobal = mmfGlobal.CreateViewAccessor();
accessorGlobal = ShareMemoryFactory.Create(key, length, itemSize);
if (accessorGlobal.Init() == false)
{
accessorGlobal = null;
}
}
}
catch (Exception)
@@ -210,16 +213,16 @@ namespace cmonitor.libs
}
public string GetItemValue(int index)
{
MemoryMappedViewAccessor accessor = accessorLocal ?? accessorGlobal;
IShareMemory accessor = accessorLocal ?? accessorGlobal;
if (accessor == null) return string.Empty;
index = index * itemSize + shareMemoryStateSize;
accessor.Read(index, out int keylen);
int keylen = accessor.ReadInt(index);
index += 4 + keylen;
if (keylen == 0) return string.Empty;
accessor.Read(index, out int vallen);
int vallen = accessor.ReadInt(index);
index += 4;
if (vallen == 0 || keylen + 8 + shareMemoryStateSize + vallen > itemSize) return string.Empty;
@@ -258,12 +261,12 @@ namespace cmonitor.libs
{
if (accessorLocal != null)
{
accessorLocal.Write(valIndex, ref keylen);
accessorLocal.WriteInt(valIndex, keylen);
accessorLocal.WriteArray(valIndex + 4, key, 0, key.Length);
}
if (accessorGlobal != null)
{
accessorGlobal.Write(valIndex, ref keylen);
accessorGlobal.WriteInt(valIndex, keylen);
accessorGlobal.WriteArray(valIndex + 4, key, 0, key.Length);
}
valIndex += 4 + key.Length;
@@ -273,23 +276,23 @@ namespace cmonitor.libs
int keyLen = 0;
if (accessorLocal != null)
{
accessorLocal.Read(valIndex, out keyLen);
keyLen = accessorLocal.ReadInt(valIndex);
}
if (keyLen == 0 && accessorGlobal != null)
{
accessorGlobal.Read(valIndex, out keyLen);
keyLen = accessorGlobal.ReadInt(valIndex);
}
valIndex += 4 + keyLen;
}
if (accessorLocal != null)
{
accessorLocal.Write(valIndex, vallen);
accessorLocal.WriteInt(valIndex, vallen);
accessorLocal.WriteArray(valIndex + 4, value, 0, value.Length);
}
if (accessorGlobal != null)
{
accessorGlobal.Write(valIndex, vallen);
accessorGlobal.WriteInt(valIndex, vallen);
accessorGlobal.WriteArray(valIndex + 4, value, 0, value.Length);
}
}
@@ -302,7 +305,7 @@ namespace cmonitor.libs
return false;
}
private bool ReadState(MemoryMappedViewAccessor accessor, int index, ShareMemoryState state)
private bool ReadState(IShareMemory accessor, int index, ShareMemoryState state)
{
if (accessor == null) return false;
@@ -334,7 +337,7 @@ namespace cmonitor.libs
return false;
}
private void WriteState(MemoryMappedViewAccessor accessor, int index, ShareMemoryState state, bool value)
private void WriteState(IShareMemory accessor, int index, ShareMemoryState state, bool value)
{
if (accessor == null) return;
byte stateValue = accessor.ReadByte(index * itemSize);
@@ -347,7 +350,7 @@ namespace cmonitor.libs
{
stateValue &= (byte)(~stateByte);
}
accessor.Write(index * itemSize, stateValue);
accessor.WriteByte(index * itemSize, stateValue);
}
public void WriteUpdated(int index, bool updated = true)
{
@@ -366,14 +369,6 @@ namespace cmonitor.libs
WriteState(accessorGlobal, index, ShareMemoryState.Running, running);
WriteUpdated(index, true);
}
public void Disponse()
{
accessorLocal?.Dispose();
mmfLocal?.Dispose();
accessorGlobal?.Dispose();
mmfGlobal?.Dispose();
}
}
public struct ShareMemoryStruct

View File

@@ -0,0 +1,25 @@
using System;
namespace cmonitor.libs
{
internal static class ShareMemoryFactory
{
public static IShareMemory Create(string key, int length, int itemSize)
{
if (OperatingSystem.IsWindows())
{
return new ShareMemoryWindows(key, length, itemSize);
}
else if (OperatingSystem.IsLinux())
{
return new ShareMemoryLinux(key, length, itemSize);
}
else if (OperatingSystem.IsMacOS())
{
return new ShareMemoryMacOS(key, length, itemSize);
}
return new ShareMemoryWindows(key, length, itemSize);
}
}
}

View File

@@ -0,0 +1,118 @@
using System;
using System.Runtime.InteropServices;
namespace cmonitor.libs
{
internal sealed class ShareMemoryLinux : IShareMemory
{
private string key;
private int length;
private int itemSize;
long shmSize;
IntPtr shmPtr;
public ShareMemoryLinux(string key, int length, int itemSize)
{
this.key = key;
this.length = length;
this.itemSize = itemSize;
}
public bool Init()
{
try
{
int shmFd = ShmOpen(key, 0, 0666);
if (shmFd == -1)
{
return false;
}
shmSize = length * itemSize;
int result = FTruncate(shmFd, shmSize);
if (result == -1)
{
return false;
}
shmPtr = MMap(IntPtr.Zero, (IntPtr)shmSize, 0x03, 0x1 /* MAP_SHARED */, shmFd, 0);
return shmPtr != IntPtr.Zero;
}
catch (Exception)
{
}
return false;
}
public void ReadArray(int position, byte[] bytes, int offset, int length)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.Copy(shmPtr + position, bytes, offset, length);
}
}
public void WriteArray(int position, byte[] bytes, int offset, int length)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.Copy(bytes, offset, shmPtr + position, length);
}
}
public byte ReadByte(int position)
{
if (shmPtr != IntPtr.Zero)
{
return Marshal.ReadByte(shmPtr + position);
}
return 0;
}
public void WriteByte(int position, byte value)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.WriteByte(shmPtr + position, value);
}
}
public int ReadInt(int position)
{
if (shmPtr != IntPtr.Zero)
{
return Marshal.ReadInt32(shmPtr + position);
}
return 0;
}
public void WriteInt(int position, int value)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.WriteInt32(shmPtr + position, value);
}
}
// 导入Linux的动态链接库
private const string LIBC_LIBRARY = "libc";
// 定义POSIX共享内存相关的API函数
[DllImport(LIBC_LIBRARY, EntryPoint = "shm_open", SetLastError = true)]
public static extern int ShmOpen(string name, int flags, int mode);
[DllImport(LIBC_LIBRARY, EntryPoint = "ftruncate", SetLastError = true)]
public static extern int FTruncate(int fd, long length);
[DllImport(LIBC_LIBRARY, EntryPoint = "mmap", SetLastError = true)]
public static extern IntPtr MMap(IntPtr addr, IntPtr length, int prot, int flags, int fd, long offset);
[DllImport(LIBC_LIBRARY, EntryPoint = "munmap", SetLastError = true)]
public static extern int MUnmap(IntPtr addr, IntPtr length);
[DllImport(LIBC_LIBRARY, EntryPoint = "shm_unlink", SetLastError = true)]
public static extern int ShmUnlink(string name);
}
}

View File

@@ -0,0 +1,118 @@
using System;
using System.Runtime.InteropServices;
namespace cmonitor.libs
{
internal sealed class ShareMemoryMacOS : IShareMemory
{
private string key;
private int length;
private int itemSize;
long shmSize;
IntPtr shmPtr;
public ShareMemoryMacOS(string key, int length, int itemSize)
{
this.key = key;
this.length = length;
this.itemSize = itemSize;
}
public bool Init()
{
try
{
int shmFd = ShmOpen(key, 0x1, 0x1B6);
if (shmFd == -1)
{
return false;
}
shmSize = length * itemSize;
int result = FTruncate(shmFd, shmSize);
if (result == -1)
{
return false;
}
shmPtr = MMap(IntPtr.Zero, (UIntPtr)shmSize, 0x3, 0x1 /* MAP_SHARED */, shmFd, 0);
return shmPtr != IntPtr.Zero;
}
catch (Exception)
{
}
return false;
}
public void ReadArray(int position, byte[] bytes, int offset, int length)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.Copy(shmPtr + position, bytes, offset, length);
}
}
public void WriteArray(int position, byte[] bytes, int offset, int length)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.Copy(bytes, offset, shmPtr + position, length);
}
}
public byte ReadByte(int position)
{
if (shmPtr != IntPtr.Zero)
{
return Marshal.ReadByte(shmPtr + position);
}
return 0;
}
public void WriteByte(int position, byte value)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.WriteByte(shmPtr + position, value);
}
}
public int ReadInt(int position)
{
if (shmPtr != IntPtr.Zero)
{
return Marshal.ReadInt32(shmPtr + position);
}
return 0;
}
public void WriteInt(int position, int value)
{
if (shmPtr != IntPtr.Zero)
{
Marshal.WriteInt32(shmPtr + position, value);
}
}
// 导入 macOS 的动态链接库
private const string LIB_SYSTEM_LIBRARY = "/usr/lib/libSystem.dylib";
// 定义 POSIX 共享内存相关的 API 函数
[DllImport(LIB_SYSTEM_LIBRARY, EntryPoint = "shm_open", SetLastError = true)]
public static extern int ShmOpen(string name, int oflag, int mode);
[DllImport(LIB_SYSTEM_LIBRARY, EntryPoint = "ftruncate", SetLastError = true)]
public static extern int FTruncate(int fd, long length);
[DllImport(LIB_SYSTEM_LIBRARY, EntryPoint = "mmap", SetLastError = true)]
public static extern IntPtr MMap(IntPtr addr, UIntPtr length, int prot, int flags, int fd, long offset);
[DllImport(LIB_SYSTEM_LIBRARY, EntryPoint = "munmap", SetLastError = true)]
public static extern int MUnmap(IntPtr addr, UIntPtr length);
[DllImport(LIB_SYSTEM_LIBRARY, EntryPoint = "shm_unlink", SetLastError = true)]
public static extern int ShmUnlink(string name);
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.IO.MemoryMappedFiles;
namespace cmonitor.libs
{
internal sealed class ShareMemoryWindows : IShareMemory
{
private string key;
private int length;
private int itemSize;
MemoryMappedFile mmfLocal = null;
MemoryMappedViewAccessor accessorLocal = null;
public ShareMemoryWindows(string key, int length, int itemSize)
{
this.key = key;
this.length = length;
this.itemSize = itemSize;
}
public bool Init()
{
try
{
if (accessorLocal == null)
{
mmfLocal = MemoryMappedFile.CreateOrOpen($"{key}", length * itemSize);
accessorLocal = mmfLocal.CreateViewAccessor();
return true;
}
}
catch (Exception)
{
}
return false;
}
public void ReadArray(int position, byte[] bytes, int offset, int length)
{
if (accessorLocal != null)
{
accessorLocal.ReadArray(position, bytes, offset, bytes.Length);
}
}
public void WriteArray(int position, byte[] data, int offset, int length)
{
if (accessorLocal != null)
{
accessorLocal.WriteArray(position, data, offset, length);
}
}
public byte ReadByte(int position)
{
if (accessorLocal != null)
{
return accessorLocal.ReadByte(position);
}
return 0;
}
public void WriteByte(int position, byte value)
{
if (accessorLocal != null)
{
accessorLocal.Write(position, value);
}
}
public int ReadInt(int position)
{
if (accessorLocal != null)
{
return accessorLocal.ReadInt32(position);
}
return 0;
}
public void WriteInt(int position, int value)
{
if (accessorLocal != null)
{
accessorLocal.Write(position, value);
}
}
}
}

View File

@@ -6,7 +6,6 @@
<PublishAot>false</PublishAot>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;ReleaseLinux</Configurations>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
@@ -41,7 +40,4 @@
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<Content Include="favicon.ico" />
</ItemGroup>
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

View File

@@ -9,6 +9,10 @@ a {
color: #6f9ccd;
}
:root {
--foot-menu-dropdown-color: #f5f5f5;
}
.flex {
display: flex;
display: -webkit-flex;

View File

@@ -1,6 +1,6 @@
<template>
<div>
<el-dialog title="选择角色" destroy-on-close v-model="showSelectUsername" center :show-close="false" :close-on-click-modal="false" align-center width="70%">
<el-dialog class="options-center" title="选择角色" destroy-on-close v-model="showSelectUsername" center :show-close="false" :close-on-click-modal="false" align-center width="70%">
<div class="username-wrap t-c">
<el-select filterable allow-create default-first-option v-model="state.username" @change="handleChange" placeholder="选择角色" size="large">
<el-option v-for="item in state.usernames" :key="item" :label="item" :value="item" />
@@ -10,7 +10,7 @@
<el-button type="success" @click="handleUsername" plain> </el-button>
</template>
</el-dialog>
<el-dialog title="管理接口" destroy-on-close v-model="showPort" center :show-close="false" :close-on-click-modal="false" align-center width="70%">
<el-dialog class="options-center" title="管理接口" destroy-on-close v-model="showPort" center :show-close="false" :close-on-click-modal="false" align-center width="70%">
<div class="port-wrap t-c">
<el-input v-model="state.api" style="width:auto"></el-input>
</div>
@@ -61,8 +61,8 @@ export default {
}).catch(() => { });
}
const handleConnect = () => {
initWebsocket(`ws://192.168.1.18:1801`);
//initWebsocket(`ws://${state.api}`);
//initWebsocket(`ws://192.168.1.18:1801`);
initWebsocket(`ws://${state.api}`);
localStorage.setItem('api', state.api);
}
const handleUsername = () => {

View File

@@ -36,9 +36,7 @@ export default {
<style lang="stylus" scoped>
@media (min-width: 768px) {
.main-wrap {
border: 2px solid #d0d7de;
height: 90% !important;
width: 394px !important;
background-image: url('../assets/bg.jpg') !important;
}
}

View File

@@ -1,9 +1,27 @@
<template>
<div class="device-list-wrap absolute flex flex-column" id="device-list-wrap">
<div class="items flex-1 relative scrollbar-1">
<Items></Items>
<div class="device-list-wrap absolute flex flex-column flex-nowarp" id="device-list-wrap">
<div class="content flex-1 flex">
<div class="items flex-1 relative scrollbar-1">
<Items></Items>
</div>
<div class="active-device flex flex-column" v-if="globalData.pc">
<div class="head">
<Head></Head>
</div>
<div class="flex-1 prev">
<div class="prev-inner">
<h3>{{globalData.currentDevice.MachineName}}</h3>
<div class="inner">
<canvas id="prev-canvas" width="1920" height="1080"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="foot">
<div class="foot" v-if="!globalData.pc">
<div class="foot-options">
<FootOptions></FootOptions>
</div>
@@ -20,11 +38,15 @@
import FootMenu from './wraps/FootMenu.vue'
import FootOptions from './wraps/FootOptions.vue'
import Items from './wraps/Items.vue'
import Head from './wraps/Head.vue'
import { providePluginState } from './provide'
import { injectGlobalData } from '../provide'
export default {
components: { Items, FootMenu, FootOptions },
components: { Items, FootMenu, FootOptions, Head },
setup() {
const globalData = injectGlobalData();
const files = require.context('./plugins/', true, /index\.js/);
const pluginSettings = files.keys().map(c => files(c).default);
const pluginState = pluginSettings.reduce((data, item, index) => {
@@ -39,28 +61,98 @@ export default {
const indexModules = indexFiles.keys().map(c => indexFiles(c).default);
return {
indexModules
indexModules, globalData
}
}
}
</script>
<style lang="stylus" scoped>
.device-list-wrap {
.head {
padding: 1rem 1rem 1rem 1rem;
border-bottom: 1px solid #ddd;
background-color: #f0f0f0;
z-index: 999;
position: relative;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.075);
@media (min-width: 768px) {
.active-device {
width: calc(100% - 41rem) !important;
}
.items {
padding: 0.6rem;
transform-style: preserve-3d;
perspective: 600px;
padding-bottom: 11.6rem;
height: 100%;
padding: 1rem 0 !important;
box-sizing: border-box;
border-right: 1px solid #999;
background-color: rgba(255, 255, 255, 0.3);
}
.foot {
display: none;
}
}
.device-list-wrap {
.content {
position: relative;
overflow: hidden;
.items {
padding: 0.6rem;
transform-style: preserve-3d;
perspective: 600px;
padding-bottom: 11.6rem;
height: 100%;
box-sizing: border-box;
}
}
.head {
width: 100%;
z-index: 999;
position: relative;
// display: none;
}
.prev {
overflow: hidden;
padding: 0.4rem 1rem 1rem 1rem;
.prev-inner {
position: relative;
box-sizing: border-box;
font-size: 1.6rem;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.05);
width: 100%;
margin: 0 auto 0 auto;
position: relative;
transition: 0.3s;
background-color: rgba(255, 255, 255, 1);
border-radius: 4px;
h3 {
padding: 0.6rem 0 0.6rem 1rem;
color: #666;
font-size: 1.4rem;
}
.inner {
position: relative;
overflow: hidden;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 0 0 4px 4px;
// border: 1px solid rgba(255, 255, 255, 0.2);
box-sizing: border-box;
&:before {
content: '';
display: inline-block;
padding-bottom: 56.25%;
width: 0.1px;
vertical-align: middle;
}
canvas {
width: 100%;
height: 100%;
position: absolute;
}
}
}
}
.foot {

View File

@@ -48,7 +48,7 @@ export default {
}
.el-dropdown {
color: #f5f5f5;
color: var(--foot-menu-dropdown-color);
font-size: 1.6rem;
.el-dropdown-link {

View File

@@ -1,5 +1,5 @@
<template>
<el-dialog title="调节亮度" destroy-on-close v-model="state.show" center align-center width="94%">
<el-dialog class="options-center" title="调节亮度" destroy-on-close v-model="state.show" center align-center width="94%">
<div class="slider-wrap flex flex-column">
<div class="silder flex flex-1">
<div class="flex-1">

View File

@@ -11,6 +11,8 @@ export default {
fullImg: null, //全图
fullUpdated: false, //第一次进来先获取一次全图
width: 0, height: 0, //系统宽高
prevCanvas: null,
prevCtx: null,
draw(canvas, ctx) {
this.drawFps(canvas, ctx);
@@ -315,7 +317,12 @@ export default {
}
}
}
if (!this.prevCanvas || !this.prevCtx) {
this.prevCanvas = document.getElementById(`prev-canvas`);
if (this.prevCanvas) {
this.prevCtx = this.prevCanvas.getContext('2d')
}
}
},
drawRegionImgs(item) {
const regions = item.Screen.regionImgs;
@@ -338,6 +345,7 @@ export default {
},
draw() {
const devices = this.globalData.value.devices.filter(c => this.globalData.value.reportNames.indexOf(c.MachineName) >= 0);
const current = this.globalData.value.currentDevice;
for (let i = 0; i < devices.length; i++) {
const item = devices[i];
@@ -355,6 +363,11 @@ export default {
const img = item.Screen.fullImg;
if (img) {
item.ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, item.canvas.width, item.canvas.height);
if (this.prevCtx) {
if (current && current.MachineName == item.MachineName) {
this.prevCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, this.prevCanvas.width, this.prevCanvas.height);
}
}
}
item.infoCtx.clearRect(0, 0, item.infoCanvas.width, item.infoCanvas.height);
this.drawInfo(item);

View File

@@ -1,5 +1,5 @@
<template>
<el-dialog title="设置" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
<el-dialog class="options" title="设置" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
<div class="setting-wrap">
<el-form ref="ruleFormRef" :model="state.form" :rules="state.rules" label-width="100px">
<el-form-item label="报告延迟(ms)" prop="ReportDelay">
@@ -11,7 +11,7 @@
<el-form-item label="截屏缩放" prop="ScreenScale">
<el-input-number size="large" v-model="state.form.ScreenScale" :min="0.1" :max="1" :step="0.1" controls-position="right" />
</el-form-item>
<el-form-item label="保存配置" prop="SaveSetting">
<!-- <el-form-item label="保存配置" prop="SaveSetting">
<el-checkbox v-model="state.form.SaveSetting">保存限制配置</el-checkbox>
</el-form-item>
<el-form-item label="黑屏唤醒" prop="WakeUp">
@@ -19,7 +19,7 @@
</el-form-item>
<el-form-item label="声音峰值" prop="VolumeMasterPeak">
<el-checkbox v-model="state.form.VolumeMasterPeak">报告声音峰值</el-checkbox>
</el-form-item>
</el-form-item> -->
</el-form>
</div>
<template #footer>

View File

@@ -67,11 +67,11 @@ export default {
}
const handleUSB = () => {
handleChange('USBSTOR', usb.value ? '确定启用USB吗' : '确定禁用USB吗', !usb.value);
handleChange('USBSTOR', usb.value ? '确定启用USB吗' : '确定禁用USB吗', !usb.value).then(() => { }).catch(() => { });
}
const handleSetting = () => {
handleChange('NoControlPanel', setting.value ? '确定启用设置吗?' : '确定禁用设置吗?', !setting.value);
handleChange('NoControlPanel', setting.value ? '确定启用设置吗?' : '确定禁用设置吗?', !setting.value).then(() => { }).catch(() => { });
}
const handleShutdown = () => {
const newValue = !shutdown.value;
@@ -80,7 +80,7 @@ export default {
updateRegistryOptions([props.data.MachineName], 'DisableLockWorkstation', newValue);
updateRegistryOptions([props.data.MachineName], 'HideFastUserSwitching', newValue);
updateRegistryOptions([props.data.MachineName], 'DisableChangePassword', newValue);
});
}).catch(() => { });
}
return {

View File

@@ -1,5 +1,5 @@
<template>
<el-dialog class="volume-dialog" title="调节音量" destroy-on-close v-model="state.show" center align-center width="94%">
<el-dialog class="volume-dialog options-center" title="调节音量" destroy-on-close v-model="state.show" center align-center width="94%">
<div class="slider-wrap flex flex-column">
<div class="silder flex flex-1">
<div class="flex-1">

View File

@@ -24,6 +24,11 @@ export default {
<style lang="stylus">
.el-dialog.is-align-center.options {
margin-top: 1vh;
max-width: 40rem;
}
.el-dialog.is-align-center.options-center {
max-width: 40rem;
}
</style>

View File

@@ -0,0 +1,131 @@
<template>
<div class="head-wrap">
<div class="inner flex">
<a href="/" class="logo">
<img src="@/assets/logo.png" alt="">
</a>
<ul class="menu flex">
<template v-for="(item,index) in footMenuModules" :key="index">
<li>
<component :is="item"></component>
</li>
</template>
</ul>
<div class="options">
<template v-for="(item,index) in footOptionTopModules" :key="index">
<component :is="item"></component>
</template>
<template v-for="(item,index) in footOptionBottomModules" :key="index">
<component :is="item"></component>
</template>
</div>
<div class="flex-1"></div>
<a class="username" href="javascript:;" @click="handleUpdate">{{username}}</a>
</div>
</div>
</template>
<script>
import { injectGlobalData } from '@/views/provide';
import { ElMessageBox } from 'element-plus';
import { computed } from 'vue';
export default {
setup() {
const footMenuFiles = require.context('../plugins/', true, /FootMenu\.vue/);
const footMenuModules = footMenuFiles.keys().map(c => footMenuFiles(c).default).sort((a, b) => a.sort - b.sort);
const footOptionTopFiles = require.context('../plugins/', true, /FootOptionTop\.vue/);
const footOptionTopModules = footOptionTopFiles.keys().map(c => footOptionTopFiles(c).default);
const footOptionBottomFiles = require.context('../plugins/', true, /FootOptionBottom\.vue/);
const footOptionBottomModules = footOptionBottomFiles.keys().map(c => footOptionBottomFiles(c).default);
const globalData = injectGlobalData();
const username = computed(() => globalData.value.username);
const handleUpdate = () => {
ElMessageBox.confirm('是否确定重选角色?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
globalData.value.username = '';
localStorage.setItem('username', '');
}).catch(() => { });
}
return { footMenuModules, footOptionTopModules, footOptionBottomModules, username, handleUpdate }
}
}
</script>
<style lang="stylus">
.head-wrap {
.el-icon {
margin-top: -2px !important;
}
}
</style>
<style lang="stylus" scoped>
.head-wrap {
--foot-menu-dropdown-color: #333;
}
.head-wrap {
position: relative;
z-index: 9;
padding: 1rem 1rem 0 1rem;
.inner {
border-radius: 4px;
background-color: rgba(255, 255, 255, 1);
height: 4rem;
line-height: 4rem;
overflow: hidden;
.logo {
padding-top: 0.4rem;
padding-left: 0.6rem;
height: 4rem;
box-sizing: border-box;
img {
height: 3.2rem;
}
}
.username {
padding: 0 0.6rem;
font-size: 1.4rem;
color: #333;
text-decoration: underline;
}
ul.menu {
padding-left: 2rem;
li {
text-align: center;
a {
padding: 1.2rem 1rem;
font-size: 1.6rem;
display: block;
color: #333;
line-height: 1;
&:hover {
background-color: rgba(0, 0, 0, 0.05);
}
}
}
}
.options {
padding-left: 2rem;
}
}
}
</style>

View File

@@ -115,6 +115,13 @@ export default {
</script>
<style lang="stylus" scoped>
@media (min-width: 768px) {
.device-item {
width: 39rem !important;
background-color: rgba(255, 255, 255, 1) !important;
}
}
.device-item {
// border: 1px solid #ddd;
font-size: 1.6rem;

View File

@@ -92,15 +92,26 @@ export default {
if (items.length == 0) return;
const wrapHeight = itemsWrap.offsetHeight;
const doms = [...items].map((item, index) => {
let totalHeight = 0;
let doms = [...items].map((item, index) => {
const topLine = item.offsetTop - scrollTop;
const middleLine = topLine + item.offsetHeight / 2;
const offset = Math.abs(middleLine - wrapHeight / 2);
return { dom: item, index: index, offset: offset };
totalHeight += item.offsetHeight + 6;
return { dom: item, index: index, top: item.offsetTop, offset: offset, height: item.offsetHeight };
});
//哪个是在最中间的
const middleItem = doms.sort((a, b) => a.offset - b.offset)[0];
const sorted = doms.sort((a, b) => a.offset - b.offset);
const middleItem = sorted[0];
if (scrollTop < doms[0].height / 2) {
globalData.value.currentDevice = globalData.value.devices[0];
} else if (scrollTop + wrapHeight >= totalHeight) {
globalData.value.currentDevice = globalData.value.devices[globalData.value.devices.length - 1];
} else {
globalData.value.currentDevice = globalData.value.devices[middleItem.index];
}
for (let i = 0; i < items.length; i++) {
let style = 'z-index:9;background-color:rgba(255,255,255,1);';
const dist = Math.abs((middleItem.index - i));

View File

@@ -18,8 +18,14 @@ export const provideGlobalData = () => {
}
return [];
}),
reportNames: []
currentDevice: { MachineName: '' },
reportNames: [],
pc: window.innerWidth > 768
});
window.addEventListener('resize', () => {
globalData.value.pc = window.innerWidth > 768;
});
provide(globalDataSymbol, globalData);
return globalData;
}

View File

@@ -2,5 +2,6 @@ const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
productionSourceMap: process.env.NODE_ENV === 'production' ? false : true,
outputDir: '../public/extends/web',
transpileDependencies: true
transpileDependencies: true,
publicPath: './'
})

View File

@@ -28,7 +28,6 @@ using cmonitor.server.service.messengers.share;
using cmonitor.server.service.messengers.notify;
using cmonitor.server.service.messengers.setting;
using cmonitor.server.web;
using cmonitor.hijack;
using common.libs;
using common.libs.database;
using common.libs.extends;
@@ -36,6 +35,9 @@ using Microsoft.Extensions.DependencyInjection;
using System.Net;
using System.Reflection;
using System.Text.Json.Serialization;
using cmonitor.server.client.reports.keyboard;
using cmonitor.server.client.reports.wallpaper;
using common.libs.winapis;
namespace cmonitor
@@ -138,29 +140,66 @@ namespace cmonitor
{
serviceCollection.AddTransient(typeof(IConfigDataProvider<>), typeof(ConfigDataFileProvider<>));
//劫持
serviceCollection.AddSingleton<HijackConfig>();
serviceCollection.AddSingleton<HijackController>();
serviceCollection.AddSingleton<HijackEventHandler>();
//客户端
serviceCollection.AddSingleton<ClientSignInState>();
serviceCollection.AddSingleton<ClientTransfer>();
serviceCollection.AddSingleton<ClientConfig>();
serviceCollection.AddSingleton<ReportTransfer>();
serviceCollection.AddSingleton<ActiveWindowReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IActiveWindow, ActiveWindowWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IActiveWindow, ActiveWindowLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IActiveWindow, ActiveWindowMacOS>();
serviceCollection.AddSingleton<HijackConfig>();
serviceCollection.AddSingleton<HijackReport>();
serviceCollection.AddSingleton<LLockReport>();
serviceCollection.AddSingleton<ScreenReport>();
serviceCollection.AddSingleton<VolumeReport>();
serviceCollection.AddSingleton<WallpaperReport>();
serviceCollection.AddSingleton<LightReport>();
serviceCollection.AddSingleton<ShareReport>();
serviceCollection.AddSingleton<SystemReport>();
serviceCollection.AddSingleton<NotifyReport>();
serviceCollection.AddSingleton<CommandReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IHijack, HijackWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IHijack, HijackLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IHijack, HijackMacOS>();
serviceCollection.AddSingleton<KeyboardReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IKeyboard, KeyboardWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IKeyboard, KeyboardLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IKeyboard, KeyboardMacOS>();
serviceCollection.AddSingleton<LightReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<ILight, LightWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<ILight, LightLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<ILight, LightMacOS>();
serviceCollection.AddSingleton<LLockReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<ILLock, LLockWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<ILLock, LLockLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<ILLock, LLockMacOS>();
serviceCollection.AddSingleton<NotifyReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<INotify, NotifyWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<INotify, NotifyLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<INotify, NotifyMacOS>();
serviceCollection.AddSingleton<ScreenReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IScreen, ScreenWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IScreen, ScreenLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IScreen, ScreenMacOS>();
serviceCollection.AddSingleton<VolumeReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IVolume, VolumeWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IVolume, VolumeLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IVolume, VolumeMacOS>();
serviceCollection.AddSingleton<WallpaperReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IWallpaper, WallpaperWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IWallpaper, WallpaperLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IWallpaper, WallpaperMacOS>();
serviceCollection.AddSingleton<SystemReport>();
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<ISystem, SystemWindows>();
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<ISystem, SystemLinux>();
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<ISystem, SystemMacOS>();
serviceCollection.AddSingleton<ShareReport>();
serviceCollection.AddSingleton<CommandReport>();
//服务
@@ -208,6 +247,7 @@ namespace cmonitor
//web
serviceCollection.AddSingleton<IWebServer, WebServer>();
}
private static void InitConfig(Config config, Dictionary<string, string> dic)
{
try
@@ -372,7 +412,7 @@ namespace cmonitor
&& ValidateReport(dic, out error)
&& ValidateElevated(dic, out error);
}
static bool ValidateMode(Dictionary<string, string> dic)
{
//模式
@@ -382,7 +422,7 @@ namespace cmonitor
}
return true;
}
static bool ValidateServer(Dictionary<string, string> dic, out string error)
{
error = string.Empty;
@@ -393,7 +433,7 @@ namespace cmonitor
}
return true;
}
static bool ValidateName(Dictionary<string, string> dic, out string error)
{
error = string.Empty;
@@ -461,7 +501,7 @@ namespace cmonitor
}
return true;
}
static bool ValidateReport(Dictionary<string, string> dic, out string error)
{
error = string.Empty;

View File

@@ -1,4 +1,5 @@
using cmonitor.server.client.reports.command;
using cmonitor.server.client.reports.keyboard;
using cmonitor.server.service;
using cmonitor.server.service.messengers.keyboard;
using cmonitor.server.service.messengers.sign;

View File

@@ -61,7 +61,7 @@ namespace cmonitor.server.api.services
public sealed class RegistryInfo
{
public string[] Names { get; set; }
public RegistryUpdateInfo Registry { get; set; }
public SystemOptionUpdateInfo Registry { get; set; }
}
public sealed class PasswordInfo

View File

@@ -1,7 +1,6 @@
using cmonitor.hijack;
using cmonitor.server.client.reports.hijack;
using cmonitor.server.client.reports.screen;
using common.libs.database;
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace cmonitor.server.client

View File

@@ -0,0 +1,26 @@
namespace cmonitor.server.client.reports.active
{
public sealed class ActiveWindowLinux : IActiveWindow
{
public void DisallowRun(string[] names)
{
}
public ActiveWindowInfo GetActiveWindow()
{
return new ActiveWindowInfo();
}
public int GetWindowCount()
{
return 0;
}
public Dictionary<uint, string> GetWindows()
{
return new Dictionary<uint, string>();
}
}
}

View File

@@ -0,0 +1,26 @@
namespace cmonitor.server.client.reports.active
{
public sealed class ActiveWindowMacOS : IActiveWindow
{
public void DisallowRun(string[] names)
{
}
public ActiveWindowInfo GetActiveWindow()
{
return new ActiveWindowInfo();
}
public int GetWindowCount()
{
return 0;
}
public Dictionary<uint, string> GetWindows()
{
return new Dictionary<uint, string>();
}
}
}

View File

@@ -1,13 +1,6 @@
using cmonitor.server.client.reports.system;
using common.libs;
using common.libs;
using MemoryPack;
#if DEBUG || RELEASE
using Microsoft.Win32;
#endif
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace cmonitor.server.client.reports.active
{
@@ -16,27 +9,25 @@ namespace cmonitor.server.client.reports.active
public string Name => "ActiveWindow";
private readonly ClientConfig clientConfig;
private readonly IActiveWindow activeWindow;
private readonly ActiveWindowTimeManager activeWindowTimeManager = new ActiveWindowTimeManager();
private ActiveReportInfo report = new ActiveReportInfo();
private uint lastPid = 0;
private string lastTitle = string.Empty;
private int count = 0;
public ActiveWindowReport(Config config, ClientConfig clientConfig)
public ActiveWindowReport(Config config, ClientConfig clientConfig, IActiveWindow activeWindow)
{
this.clientConfig = clientConfig;
this.activeWindow = activeWindow;
if (config.IsCLient)
{
Timers();
DisallowInit();
DisallowRun(clientConfig.WindowNames);
Loop();
AppDomain.CurrentDomain.ProcessExit += (s, e) => DisallowRun(Array.Empty<string>());
Console.CancelKeyPress += (s, e) => DisallowRun(Array.Empty<string>());
}
}
long ticks = DateTime.UtcNow.Ticks;
@@ -52,6 +43,14 @@ namespace cmonitor.server.client.reports.active
}
return null;
}
public void DisallowRun(string[] names)
{
clientConfig.WindowNames = names;
report.DisallowCount = names.Length;
activeWindow.DisallowRun(names);
}
public ActiveWindowTimeReportInfo GetActiveWindowTimes()
{
return activeWindowTimeManager.GetActiveWindowTimes();
@@ -60,25 +59,28 @@ namespace cmonitor.server.client.reports.active
{
activeWindowTimeManager.Clear();
}
public Dictionary<uint, string> GetWindows()
{
return activeWindow.GetWindows();
}
private void Timers()
private void Loop()
{
Task.Factory.StartNew(async () =>
{
while (true)
{
if ((DateTime.UtcNow.Ticks - ticks) / TimeSpan.TicksPerMillisecond < 1000 || disallowNames.Length > 0)
if ((DateTime.UtcNow.Ticks - ticks) / TimeSpan.TicksPerMillisecond < 1000 || report.DisallowCount > 0)
{
try
{
GetActiveWindow();
report.WindowCount = GetWindowCount();
if (Disallow() == false)
{
//activeWindowTimeManager.Update(report);
}
ActiveWindowInfo info = activeWindow.GetActiveWindow();
report.Title = info.Title;
report.FileName = info.FileName;
report.Desc = info.Desc;
report.Pid = info.Pid;
report.WindowCount = activeWindow.GetWindowCount();
}
catch (Exception ex)
{
@@ -91,260 +93,6 @@ namespace cmonitor.server.client.reports.active
}
}, TaskCreationOptions.LongRunning);
}
const int nChars = 256;
private StringBuilder buff = new StringBuilder(nChars);
private void GetActiveWindow()
{
IntPtr handle = GetForegroundWindow();
GetWindowThreadProcessId(handle, out uint id);
if (GetWindowText(handle, buff, nChars) > 0)
{
Process p = Process.GetProcessById((int)id);
string desc = string.Empty;
string filename = string.Empty;
try
{
ProcessModule main = p.MainModule;
if (main != null)
{
filename = main.FileName;
desc = main.FileVersionInfo.FileDescription;
}
}
catch (Exception)
{
}
report.Title = buff.ToString();
report.FileName = filename;
report.Desc = desc;
report.Pid = id;
return;
}
report.Title = string.Empty;
report.FileName = string.Empty;
report.Desc = string.Empty;
report.Pid = 0;
}
private string[] disallowNames = Array.Empty<string>();
public void DisallowRun(string[] names)
{
clientConfig.WindowNames = names;
DisallowRun(false);
DisallowRunClear();
report.DisallowCount = names.Length;
disallowNames = names;
Task.Run(() =>
{
if (names.Length > 0)
{
DisallowRun(true);
DisallowRunFileNames(names);
}
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
});
}
private bool Disallow()
{
if (disallowNames.Length > 0)
{
try
{
ReadOnlySpan<char> filenameSpan = report.FileName.AsSpan();
uint pid = report.Pid;
foreach (string item in disallowNames)
{
ReadOnlySpan<char> nameSpan = item.AsSpan();
bool result = item == report.Title
|| (filenameSpan.Length >= nameSpan.Length && filenameSpan.Slice(filenameSpan.Length - nameSpan.Length, nameSpan.Length).SequenceEqual(nameSpan));
if (result)
{
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { $"taskkill /f /pid {pid}" });
});
}
}
}
catch (Exception)
{
}
return true;
}
return false;
}
private void DisallowInit()
{
CreateKey();
DisallowRunClear();
DisallowRun(false);
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
});
}
private void DisallowRunClear()
{
#if DEBUG || RELEASE
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\DisallowRun", true);
if (key != null)
{
string[] names = key.GetValueNames();
if (names != null)
{
foreach (string name in names)
{
key.DeleteValue(name, false);
}
}
}
}
}
catch (Exception ex)
{
Logger.Instance.Error($"application disallow clear {ex}");
}
#endif
}
private void DisallowRunFileNames(string[] filenames)
{
#if DEBUG || RELEASE
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\DisallowRun", true);
if (key != null)
{
foreach (string filename in filenames)
{
key.SetValue(filename, filename, RegistryValueKind.String);
}
}
}
}
catch (Exception ex)
{
Logger.Instance.Error($"application disallow {string.Join(",", filenames)} {ex}");
}
#endif
}
private void DisallowRun(bool value)
{
#if DEBUG || RELEASE
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", true);
if (key != null)
{
key.SetValue("DisallowRun", value ? 1 : 0, RegistryValueKind.DWord);
}
}
}
catch (Exception)
{
}
#endif
}
private void CreateKey()
{
#if DEBUG || RELEASE
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", true);
RegistryKey disallowRun = key.OpenSubKey("DisallowRun");
if (disallowRun == null)
{
key.CreateSubKey("DisallowRun");
}
}
}
catch (Exception)
{
}
#endif
}
private int GetWindowCount()
{
int length = 0;
EnumWindows((IntPtr hWnd, IntPtr lParam) =>
{
try
{
if (IsWindowVisible(hWnd) && GetWindowTextLength(hWnd) > 0)
{
length++;
}
}
catch (Exception)
{
}
return true;
}, IntPtr.Zero);
return length;
}
public Dictionary<uint, string> GetWIndows()
{
Dictionary<uint, string> dic = new Dictionary<uint, string>();
StringBuilder lpString = new StringBuilder(256);
EnumWindows((IntPtr hWnd, IntPtr lParam) =>
{
try
{
if (IsWindowVisible(hWnd) && GetWindowTextLength(hWnd) > 0)
{
GetWindowText(hWnd, lpString, 256);
GetWindowThreadProcessId(hWnd, out uint id);
dic[id] = lpString.ToString();
}
}
catch (Exception)
{
}
return true;
}, IntPtr.Zero);
return dic;
}
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool IsWindowVisible(IntPtr hWnd);
}
public sealed class ActiveReportInfo
@@ -357,14 +105,6 @@ namespace cmonitor.server.client.reports.active
public int WindowCount { get; set; }
}
public sealed class ActiveWindow
{
public string Title { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
public string Desc { get; set; } = string.Empty;
public uint Pid = 0;
}
public sealed class ActiveWindowTimeManager
{
private ConcurrentDictionary<string, ActiveWindowTimeInfo> dic = new ConcurrentDictionary<string, ActiveWindowTimeInfo>();
@@ -432,7 +172,6 @@ namespace cmonitor.server.client.reports.active
}
}
[MemoryPackable]
public sealed partial class ActiveWindowTimeReportInfo
{

View File

@@ -0,0 +1,248 @@
using common.libs;
using common.libs.winapis;
using Microsoft.Win32;
using System.Diagnostics;
using System.Text;
namespace cmonitor.server.client.reports.active
{
public sealed class ActiveWindowWindows : IActiveWindow
{
public ActiveWindowWindows(Config config)
{
if (config.IsCLient)
{
CreateKey();
DisallowRunClear();
DisallowRun(false);
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
});
}
}
private void CreateKey()
{
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", true);
RegistryKey disallowRun = key.OpenSubKey("DisallowRun");
if (disallowRun == null)
{
key.CreateSubKey("DisallowRun");
}
}
}
catch (Exception)
{
}
}
private string[] disallowNames = Array.Empty<string>();
public void DisallowRun(string[] names)
{
DisallowRun(false);
DisallowRunClear();
disallowNames = names;
Task.Run(() =>
{
if (names.Length > 0)
{
DisallowRun(true);
DisallowRunFileNames(names);
}
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
});
}
private void DisallowRunClear()
{
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\DisallowRun", true);
if (key != null)
{
string[] names = key.GetValueNames();
if (names != null)
{
foreach (string name in names)
{
key.DeleteValue(name, false);
}
}
}
}
}
catch (Exception ex)
{
Logger.Instance.Error($"application disallow clear {ex}");
}
}
private void DisallowRun(bool value)
{
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", true);
if (key != null)
{
key.SetValue("DisallowRun", value ? 1 : 0, RegistryValueKind.DWord);
}
}
}
catch (Exception)
{
}
}
private void DisallowRunFileNames(string[] filenames)
{
try
{
if (OperatingSystem.IsWindows())
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\DisallowRun", true);
if (key != null)
{
foreach (string filename in filenames)
{
key.SetValue(filename, filename, RegistryValueKind.String);
}
}
}
}
catch (Exception ex)
{
Logger.Instance.Error($"application disallow {string.Join(",", filenames)} {ex}");
}
}
private bool Disallow(ActiveWindowInfo window)
{
if (disallowNames.Length > 0)
{
try
{
ReadOnlySpan<char> filenameSpan = window.FileName.AsSpan();
uint pid = window.Pid;
foreach (string item in disallowNames)
{
ReadOnlySpan<char> nameSpan = item.AsSpan();
bool result = item == window.Title
|| (filenameSpan.Length >= nameSpan.Length && filenameSpan.Slice(filenameSpan.Length - nameSpan.Length, nameSpan.Length).SequenceEqual(nameSpan));
if (result)
{
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { $"taskkill /f /pid {pid}" });
});
}
}
}
catch (Exception)
{
}
return true;
}
return false;
}
const int nChars = 256;
private StringBuilder buff = new StringBuilder(nChars);
public ActiveWindowInfo GetActiveWindow()
{
ActiveWindowInfo activeWindowInfo = new ActiveWindowInfo();
IntPtr handle = User32.GetForegroundWindow();
User32.GetWindowThreadProcessId(handle, out uint id);
if (User32.GetWindowText(handle, buff, nChars) > 0)
{
Process p = Process.GetProcessById((int)id);
string desc = string.Empty;
string filename = string.Empty;
try
{
ProcessModule main = p.MainModule;
if (main != null)
{
filename = main.FileName;
desc = main.FileVersionInfo.FileDescription;
}
}
catch (Exception)
{
}
activeWindowInfo.Title = buff.ToString();
activeWindowInfo.FileName = filename;
activeWindowInfo.Desc = desc;
activeWindowInfo.Pid = id;
Disallow(activeWindowInfo);
}
else
{
activeWindowInfo.Title = string.Empty;
activeWindowInfo.FileName = string.Empty;
activeWindowInfo.Desc = string.Empty;
activeWindowInfo.Pid = 0;
}
return activeWindowInfo;
}
public int GetWindowCount()
{
int length = 0;
User32.EnumWindows((IntPtr hWnd, IntPtr lParam) =>
{
try
{
if (User32.IsWindowVisible(hWnd) && User32.GetWindowTextLength(hWnd) > 0)
{
length++;
}
}
catch (Exception)
{
}
return true;
}, IntPtr.Zero);
return length;
}
public Dictionary<uint, string> GetWindows()
{
Dictionary<uint, string> dic = new Dictionary<uint, string>();
StringBuilder lpString = new StringBuilder(256);
User32.EnumWindows((IntPtr hWnd, IntPtr lParam) =>
{
try
{
if (User32.IsWindowVisible(hWnd) && User32.GetWindowTextLength(hWnd) > 0)
{
User32.GetWindowText(hWnd, lpString, 256);
User32.GetWindowThreadProcessId(hWnd, out uint id);
dic[id] = lpString.ToString();
}
}
catch (Exception)
{
}
return true;
}, IntPtr.Zero);
return dic;
}
}
}

View File

@@ -0,0 +1,20 @@
namespace cmonitor.server.client.reports.active
{
public interface IActiveWindow
{
public void DisallowRun(string[] names);
public ActiveWindowInfo GetActiveWindow();
public int GetWindowCount();
public Dictionary<uint, string> GetWindows();
}
public sealed class ActiveWindowInfo
{
public string Title { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
public string Desc { get; set; } = string.Empty;
public uint Pid { get; set; }
}
}

View File

@@ -4,7 +4,6 @@
{
public string Name => "Command";
private readonly CommandReportInfo commandReportInfo = new CommandReportInfo();
public CommandReport()
{
}
@@ -15,10 +14,4 @@
}
}
public sealed class CommandReportInfo
{
//public string[] RegeditUsers { get; set; } = Array.Empty<string>();
}
}

View File

@@ -1,4 +1,4 @@
namespace cmonitor.hijack
namespace cmonitor.server.client.reports.hijack
{
public sealed class HijackConfig
{

View File

@@ -0,0 +1,25 @@
namespace cmonitor.server.client.reports.hijack
{
public sealed class HijackLinux : IHijack
{
public ulong UdpSend => 0;
public ulong UdpReceive => 0;
public ulong TcpSend => 0;
public ulong TcpReceive => 0;
public void SetRules()
{
}
public void Start()
{
}
public void Stop()
{
}
}
}

View File

@@ -0,0 +1,25 @@
namespace cmonitor.server.client.reports.hijack
{
public sealed class HijackMacOS : IHijack
{
public ulong UdpSend => 0;
public ulong UdpReceive => 0;
public ulong TcpSend => 0;
public ulong TcpReceive => 0;
public void SetRules()
{
}
public void Start()
{
}
public void Stop()
{
}
}
}

View File

@@ -1,5 +1,4 @@
using cmonitor.hijack;
using common.libs;
using common.libs;
using MemoryPack;
namespace cmonitor.server.client.reports.hijack
@@ -8,22 +7,20 @@ namespace cmonitor.server.client.reports.hijack
{
public string Name => "Hijack";
private readonly HijackEventHandler hijackEventHandler;
private readonly HijackConfig hijackConfig;
private readonly ClientConfig clientConfig;
private readonly HijackController hijackController;
private readonly IHijack hijack;
private ulong[] array = new ulong[3];
private ulong[] lastArray = new ulong[3];
private long ticks = DateTime.UtcNow.Ticks;
public HijackReport(HijackEventHandler hijackEventHandler, HijackController hijackController, HijackConfig hijackConfig, ClientConfig clientConfig, Config config)
public HijackReport(IHijack hijack, HijackConfig hijackConfig, ClientConfig clientConfig, Config config)
{
this.hijackEventHandler = hijackEventHandler;
this.hijackController = hijackController;
this.hijack = hijack;
this.hijackConfig = hijackConfig;
this.clientConfig = clientConfig;
if (OperatingSystem.IsWindows() && config.IsCLient)
if (config.IsCLient)
{
try
{
@@ -34,7 +31,7 @@ namespace cmonitor.server.client.reports.hijack
hijackConfig.DeniedIPs = clientConfig.HijackConfig.DeniedIPs;
hijackConfig.AllowIPs = clientConfig.HijackConfig.AllowIPs;
hijackController.Start();
hijack.Start();
}
catch (Exception ex)
{
@@ -54,13 +51,13 @@ namespace cmonitor.server.client.reports.hijack
clientConfig.HijackConfig = hijackConfig;
hijackController.SetRules();
hijack.SetRules();
}
public object GetReports(ReportType reportType)
{
array[0] = hijackEventHandler.UdpSend + hijackEventHandler.TcpSend;
array[1] = hijackEventHandler.TcpReceive + hijackEventHandler.UdpReceive;
array[0] = hijack.UdpSend + hijack.TcpSend;
array[1] = hijack.TcpReceive + hijack.UdpReceive;
ulong count = (ulong)(hijackConfig.AllowIPs.Length + hijackConfig.DeniedIPs.Length + hijackConfig.AllowDomains.Length + hijackConfig.DeniedDomains.Length + hijackConfig.AllowProcesss.Length + hijackConfig.DeniedProcesss.Length);
array[2] = count;

View File

@@ -0,0 +1,36 @@
using cmonitor.server.client.reports.hijack.hijack;
namespace cmonitor.server.client.reports.hijack
{
public sealed class HijackWindows : IHijack
{
private readonly HijackEventHandler hijackEventHandler;
private readonly HijackController hijackController;
public HijackWindows(HijackConfig hijackConfig)
{
hijackEventHandler = new HijackEventHandler(hijackConfig);
hijackController = new HijackController(hijackConfig, hijackEventHandler);
}
public ulong UdpSend => hijackEventHandler.UdpSend;
public ulong UdpReceive => hijackEventHandler.UdpReceive;
public ulong TcpSend => hijackEventHandler.TcpSend;
public ulong TcpReceive => hijackEventHandler.TcpReceive;
public void SetRules()
{
hijackController.SetRules();
}
public void Start()
{
hijackController.Start();
}
public void Stop()
{
hijackController.Stop();
}
}
}

View File

@@ -0,0 +1,14 @@
namespace cmonitor.server.client.reports.hijack
{
public interface IHijack
{
public ulong UdpSend { get; }
public ulong UdpReceive { get; }
public ulong TcpSend { get; }
public ulong TcpReceive { get;}
public void Start();
public void Stop();
public void SetRules();
}
}

View File

@@ -1,11 +1,12 @@
using common.libs;
using cmonitor.server.client.reports.hijack;
using common.libs;
using System.Buffers.Binary;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace cmonitor.hijack;
namespace cmonitor.server.client.reports.hijack.hijack;
public sealed class HijackController
{

View File

@@ -3,8 +3,9 @@ using System.Collections.Concurrent;
using System.Text;
using common.libs.extends;
using System.IO;
using cmonitor.server.client.reports.hijack;
namespace cmonitor.hijack
namespace cmonitor.server.client.reports.hijack.hijack
{
public sealed class HijackEventHandler : NF_EventHandler
{
@@ -45,7 +46,7 @@ namespace cmonitor.hijack
tcpConnections.TryAdd(id, true);
return;
}
public void tcpSend(ulong id, IntPtr buf, int len)
public void tcpSend(ulong id, nint buf, int len)
{
if (tcpConnections.ContainsKey(id))
{
@@ -53,7 +54,7 @@ namespace cmonitor.hijack
NFAPI.nf_tcpPostSend(id, buf, len);
}
}
public void tcpReceive(ulong id, IntPtr buf, int len)
public void tcpReceive(ulong id, nint buf, int len)
{
TcpReceive += (ulong)len;
NFAPI.nf_tcpPostReceive(id, buf, len);
@@ -151,7 +152,7 @@ namespace cmonitor.hijack
sb.Append(".");
span = span.Slice(1 + span[0]);
}
string domain = (sb.ToString(0, sb.Length - 1));
string domain = sb.ToString(0, sb.Length - 1);
if (checkDomain(domain))
{
return true;

View File

@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
namespace cmonitor.hijack
namespace cmonitor.server.client.reports.hijack.hijack
{
public enum NF_STATUS
{

View File

@@ -0,0 +1,40 @@
using MemoryPack;
namespace cmonitor.server.client.reports.keyboard
{
public interface IKeyboard
{
public void KeyBoard(KeyBoardInputInfo inputInfo);
public void MouseSet(MouseSetInfo setInfo);
public void MouseClick(MouseClickInfo clickInfo);
public void CtrlAltDelete();
public void WinL();
}
[MemoryPackable]
public partial struct KeyBoardInputInfo
{
/// <summary>
/// System.Windows.Forms.Keys
/// </summary>
public byte Key { get; set; }
/// <summary>
/// 0 down,2 up
/// </summary>
public int Type { get; set; }
}
[MemoryPackable]
public partial struct MouseSetInfo
{
public int X { get; set; }
public int Y { get; set; }
}
[MemoryPackable]
public partial struct MouseClickInfo
{
public uint Flag { get; set; }
public int Data { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
namespace cmonitor.server.client.reports.keyboard
{
public sealed class KeyboardLinux : IKeyboard
{
public void CtrlAltDelete()
{
}
public void KeyBoard(KeyBoardInputInfo inputInfo)
{
}
public void MouseClick(MouseClickInfo clickInfo)
{
}
public void MouseSet(MouseSetInfo setInfo)
{
}
public void WinL()
{
}
}
}

View File

@@ -0,0 +1,26 @@
namespace cmonitor.server.client.reports.keyboard
{
public sealed class KeyboardMacOS : IKeyboard
{
public void CtrlAltDelete()
{
}
public void KeyBoard(KeyBoardInputInfo inputInfo)
{
}
public void MouseClick(MouseClickInfo clickInfo)
{
}
public void MouseSet(MouseSetInfo setInfo)
{
}
public void WinL()
{
}
}
}

View File

@@ -1,29 +1,14 @@
using cmonitor.server.client.reports.screen;
using cmonitor.server.client.reports.screen.helpers;
using cmonitor.server.client.reports.screen.winapis;
using cmonitor.server.client.reports.screen.winapiss;
using cmonitor.server.client.reports.share;
using common.libs;
using MemoryPack;
using System.Collections.Concurrent;
namespace cmonitor.server.client.reports.command
namespace cmonitor.server.client.reports.keyboard
{
public sealed class KeyboardReport : IReport
{
public string Name => "Keyboard";
private readonly Config config;
private readonly ShareReport shareReport;
public KeyboardReport(Config config, ShareReport shareReport)
{
this.config = config;
this.shareReport = shareReport;
if (OperatingSystem.IsWindows() && config.IsCLient)
{
CheckQueue();
}
private readonly IKeyboard keyboard;
public KeyboardReport(IKeyboard keyboard)
{
this.keyboard = keyboard;
}
public object GetReports(ReportType reportType)
{
@@ -35,126 +20,22 @@ namespace cmonitor.server.client.reports.command
public void KeyBoard(KeyBoardInputInfo inputInfo)
{
KeyBoardInputInfo _inputInfo = inputInfo;
TryOnInputDesktop(() =>
{
User32.keybd_event(_inputInfo.Key, (byte)User32.MapVirtualKey(_inputInfo.Key, 0), _inputInfo.Type, 0);
});
keyboard.KeyBoard(inputInfo);
}
public void MouseSet(MouseSetInfo setInfo)
{
MouseSetInfo _setInfo = setInfo;
TryOnInputDesktop(() =>
{
User32.SetCursorPos(_setInfo.X, _setInfo.Y);
MouseHelper.MouseSet(_setInfo.X, _setInfo.Y);
});
keyboard.MouseSet(setInfo);
}
public void MouseClick(MouseClickInfo clickInfo)
{
MouseClickInfo _clickInfo = clickInfo;
TryOnInputDesktop(() =>
{
MouseHelper.MouseClick(_clickInfo.Flag, _clickInfo.Data);
});
keyboard.MouseClick(clickInfo);
}
public const int KEYEVENTF_EXTENDEDKEY = 0x0000;
public const int KEYEVENTF_KEYUP = 0x0002;
public void CtrlAltDelete()
{
try
{
shareReport.UpdateShare(new ShareItemInfo
{
Index = Config.ShareMemorySASIndex,
Key = "cmonitor.sas.service",
Value = "ctrl+alt+delete"
});
}
catch (Exception ex)
{
Logger.Instance.Error(ex);
}
keyboard.CtrlAltDelete();
}
private readonly ConcurrentQueue<Action> inputActions = new();
private void CheckQueue()
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
Task.Factory.StartNew((a) =>
{
CancellationTokenSource tks = a as CancellationTokenSource;
while (tks.IsCancellationRequested == false)
{
if (inputActions.IsEmpty == false)
{
try
{
if (inputActions.TryDequeue(out var action))
{
if (config.Elevated == true && !Win32Interop.SwitchToInputDesktop())
{
uint code = Kernel32.GetLastError();
tks.Cancel();
CheckQueue();
}
action();
}
}
finally
{
}
}
else
{
Thread.Sleep(10);
}
}
}, cancellationTokenSource, TaskCreationOptions.LongRunning);
}
private void TryOnInputDesktop(Action inputAction)
{
inputActions.Enqueue(() =>
{
try
{
inputAction();
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
});
}
}
[MemoryPackable]
public partial struct KeyBoardInputInfo
{
/// <summary>
/// System.Windows.Forms.Keys
/// </summary>
public byte Key { get; set; }
/// <summary>
/// 0 down,2 up
/// </summary>
public int Type { get; set; }
}
[MemoryPackable]
public partial struct MouseSetInfo
{
public int X { get; set; }
public int Y { get; set; }
}
[MemoryPackable]
public partial struct MouseClickInfo
{
public uint Flag { get; set; }
public int Data { get; set; }
}
}

View File

@@ -0,0 +1,124 @@
using cmonitor.server.client.reports.share;
using common.libs;
using common.libs.helpers;
using common.libs.winapis;
using System.Collections.Concurrent;
namespace cmonitor.server.client.reports.keyboard
{
public sealed class KeyboardWindows : IKeyboard
{
private readonly Config config;
private readonly ShareReport shareReport;
public KeyboardWindows(Config config, ShareReport shareReport)
{
this.config = config;
this.shareReport = shareReport;
if (config.IsCLient)
{
CheckQueue();
}
}
public void KeyBoard(KeyBoardInputInfo inputInfo)
{
KeyBoardInputInfo _inputInfo = inputInfo;
TryOnInputDesktop(() =>
{
User32.keybd_event(_inputInfo.Key, (byte)User32.MapVirtualKey(_inputInfo.Key, 0), _inputInfo.Type, 0);
});
}
public void MouseSet(MouseSetInfo setInfo)
{
MouseSetInfo _setInfo = setInfo;
TryOnInputDesktop(() =>
{
User32.SetCursorPos(_setInfo.X, _setInfo.Y);
MouseHelper.MouseSet(_setInfo.X, _setInfo.Y);
});
}
public void MouseClick(MouseClickInfo clickInfo)
{
MouseClickInfo _clickInfo = clickInfo;
TryOnInputDesktop(() =>
{
MouseHelper.MouseClick(_clickInfo.Flag, _clickInfo.Data);
});
}
public void CtrlAltDelete()
{
try
{
shareReport.UpdateShare(new ShareItemInfo
{
Index = Config.ShareMemorySASIndex,
Key = "cmonitor.sas.service",
Value = "ctrl+alt+delete"
});
}
catch (Exception ex)
{
Logger.Instance.Error(ex);
}
}
public void WinL()
{
User32.LockWorkStation();
}
private readonly ConcurrentQueue<Action> inputActions = new();
private void CheckQueue()
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
Task.Factory.StartNew((a) =>
{
CancellationTokenSource tks = a as CancellationTokenSource;
while (tks.IsCancellationRequested == false)
{
if (inputActions.IsEmpty == false)
{
try
{
if (inputActions.TryDequeue(out var action))
{
if (config.Elevated == true && !Win32Interop.SwitchToInputDesktop())
{
uint code = Kernel32.GetLastError();
tks.Cancel();
CheckQueue();
}
action();
}
}
finally
{
}
}
else
{
Thread.Sleep(10);
}
}
}, cancellationTokenSource, TaskCreationOptions.LongRunning);
}
private void TryOnInputDesktop(Action inputAction)
{
inputActions.Enqueue(() =>
{
try
{
inputAction();
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
});
}
}
}

View File

@@ -0,0 +1,8 @@
namespace cmonitor.server.client.reports.light
{
public interface ILight
{
public int Get();
public void Set(int value);
}
}

View File

@@ -0,0 +1,15 @@
namespace cmonitor.server.client.reports.light
{
public sealed class LightLinux : ILight
{
public int Get()
{
return 0;
}
public void Set(int value)
{
}
}
}

View File

@@ -0,0 +1,15 @@
namespace cmonitor.server.client.reports.light
{
public sealed class LightMacOS : ILight
{
public int Get()
{
return 0;
}
public void Set(int value)
{
}
}
}

View File

@@ -3,26 +3,19 @@
public sealed class LightReport : IReport
{
public string Name => "Light";
LightReportInfo report = new LightReportInfo();
int lastValue = 0;
private readonly LightWatcher lightWatcher;
public LightReport()
private readonly ILight light;
public LightReport(ILight light)
{
if (OperatingSystem.IsWindows())
{
lightWatcher = new LightWatcher();
lightWatcher.BrightnessChanged += (e, value) =>
{
report.Value = (int)value.newBrightness;
};
report.Value = LightWmiHelper.GetBrightnessLevel();
}
this.light = light;
}
public object GetReports(ReportType reportType)
{
report.Value = light.Get();
if (reportType == ReportType.Full || report.Value != lastValue)
{
lastValue = report.Value;
@@ -33,7 +26,7 @@
public void SetLight(int value)
{
LightWmiHelper.SetBrightnessLevel(value);
light.Set(value);
}
}

View File

@@ -0,0 +1,30 @@
namespace cmonitor.server.client.reports.light
{
public sealed class LightWindows : ILight
{
private readonly LightWindowsWatcher lightWatcher;
private int value = 0;
public LightWindows(Config config)
{
if (config.IsCLient)
{
lightWatcher = new LightWindowsWatcher();
lightWatcher.BrightnessChanged += (e, value) =>
{
this.value = (int)value.newBrightness;
};
value = LightWindowsWmiHelper.GetBrightnessLevel();
}
}
public int Get()
{
return value;
}
public void Set(int value)
{
LightWindowsWmiHelper.SetBrightnessLevel(value);
}
}
}

View File

@@ -3,7 +3,7 @@ using System.Management;
#endif
namespace cmonitor.server.client.reports.light
{
public class LightWatcher : IDisposable
public class LightWindowsWatcher : IDisposable
{
public event EventHandler<BrightnessChangedEventArgs> BrightnessChanged;
@@ -32,7 +32,7 @@ namespace cmonitor.server.client.reports.light
private readonly ManagementEventWatcher _watcher;
#endif
public LightWatcher()
public LightWindowsWatcher()
{
#if DEBUG || RELEASE
if (OperatingSystem.IsWindows())

View File

@@ -5,7 +5,7 @@ using common.libs;
namespace cmonitor.server.client.reports.light
{
public static class LightWmiHelper
public static class LightWindowsWmiHelper
{
public static int GetBrightnessLevel()
{

View File

@@ -0,0 +1,8 @@
namespace cmonitor.server.client.reports.llock
{
public interface ILLock
{
public void Set(bool value);
public void LockSystem();
}
}

View File

@@ -0,0 +1,13 @@
namespace cmonitor.server.client.reports.llock
{
public sealed class LLockLinux : ILLock
{
public void LockSystem()
{
}
public void Set(bool value)
{
}
}
}

View File

@@ -0,0 +1,13 @@
namespace cmonitor.server.client.reports.llock
{
public sealed class LLockMacOS : ILLock
{
public void LockSystem()
{
}
public void Set(bool value)
{
}
}
}

View File

@@ -1,6 +1,4 @@
using cmonitor.server.client.reports.screen.winapiss;
using cmonitor.server.client.reports.share;
using common.libs;
using cmonitor.server.client.reports.share;
namespace cmonitor.server.client.reports.llock
{
@@ -10,18 +8,18 @@ namespace cmonitor.server.client.reports.llock
private LLockReportInfo report = new LLockReportInfo();
bool lastValue = false;
bool update = false;
private readonly Config config;
private readonly ShareReport shareReport;
private readonly ClientConfig clientConfig;
private readonly ILLock lLock;
public LLockReport(Config config, ShareReport shareReport, ClientConfig clientConfig)
public LLockReport(Config config, ShareReport shareReport, ClientConfig clientConfig, ILLock lLock)
{
this.config = config;
this.shareReport = shareReport;
this.clientConfig = clientConfig;
if (OperatingSystem.IsWindows() && config.IsCLient)
this.lLock = lLock;
if (config.IsCLient)
{
LockScreen(clientConfig.LLock);
}
@@ -30,13 +28,12 @@ namespace cmonitor.server.client.reports.llock
DateTime startTime = new DateTime(1970, 1, 1);
public object GetReports(ReportType reportType)
{
clientConfig.LLock = report.LockScreen = shareReport.GetShare(Name, out cmonitor.libs.ShareItemInfo share)
clientConfig.LLock = report.LockScreen = shareReport.GetShare(Name, out libs.ShareItemInfo share)
&& string.IsNullOrWhiteSpace(share.Value) == false
&& long.TryParse(share.Value, out long time) && (long)(DateTime.UtcNow.Subtract(startTime)).TotalMilliseconds - time < 1000;
if (reportType == ReportType.Full || update || report.LockScreen != lastValue)
if (reportType == ReportType.Full || report.LockScreen != lastValue)
{
update = false;
lastValue = report.LockScreen;
return report;
}
@@ -50,28 +47,17 @@ namespace cmonitor.server.client.reports.llock
{
shareReport.WriteClose(Config.ShareMemoryLLockIndex);
await Task.Delay(100);
if (open)
{
CommandHelper.Windows(string.Empty, new string[] {
$"start llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryLLockIndex}"
});
}
lLock.Set(open);
});
}
public void LockSystem()
{
User32.LockWorkStation();
lLock.LockSystem();
}
}
public enum EnableLock : byte
{
Disabled = 0,
Enables = 1
}
public sealed class LLockReportInfo
{
public bool LockScreen { get; set; }

View File

@@ -0,0 +1,29 @@
using common.libs;
using common.libs.winapis;
namespace cmonitor.server.client.reports.llock
{
public sealed class LLockWindows : ILLock
{
private readonly Config config;
public LLockWindows(Config config)
{
this.config = config;
}
public void Set(bool value)
{
if (value)
{
CommandHelper.Windows(string.Empty, new string[] {
$"start llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryLLockIndex}"
});
}
}
public void LockSystem()
{
User32.LockWorkStation();
}
}
}

View File

@@ -0,0 +1,19 @@
using MemoryPack;
namespace cmonitor.server.client.reports.notify
{
public interface INotify
{
public void Update(NotifyInfo notify);
}
[MemoryPackable]
public sealed partial class NotifyInfo
{
public byte Speed { get; set; }
public string Msg { get; set; }
public byte Star1 { get; set; } = 1;
public byte Star2 { get; set; } = 1;
public byte Star3 { get; set; } = 1;
}
}

View File

@@ -0,0 +1,9 @@
namespace cmonitor.server.client.reports.notify
{
public sealed class NotifyLinux : INotify
{
public void Update(NotifyInfo notify)
{
}
}
}

View File

@@ -0,0 +1,9 @@
namespace cmonitor.server.client.reports.notify
{
public sealed class NotifyMacOS : INotify
{
public void Update(NotifyInfo notify)
{
}
}
}

View File

@@ -1,14 +1,13 @@
using common.libs;
using MemoryPack;
namespace cmonitor.server.client.reports.notify
namespace cmonitor.server.client.reports.notify
{
public sealed class NotifyReport : IReport
{
public string Name => "Notify";
public NotifyReport()
private readonly INotify notify;
public NotifyReport(INotify notify)
{
this.notify = notify;
}
public object GetReports(ReportType reportType)
@@ -18,23 +17,8 @@ namespace cmonitor.server.client.reports.notify
public void Update(NotifyInfo notify)
{
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] {
$"start notify.win.exe {notify.Speed} \"{notify.Msg}\" {notify.Star1} {notify.Star2} {notify.Star3}"
});
});
this.notify.Update(notify);
}
}
[MemoryPackable]
public sealed partial class NotifyInfo
{
public byte Speed { get; set; }
public string Msg { get; set; }
public byte Star1 { get; set; } = 1;
public byte Star2 { get; set; } = 1;
public byte Star3 { get; set; } = 1;
}
}

View File

@@ -0,0 +1,22 @@
using common.libs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cmonitor.server.client.reports.notify
{
public sealed class NotifyWindows : INotify
{
public void Update(NotifyInfo notify)
{
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] {
$"start notify.win.exe {notify.Speed} \"{notify.Msg}\" {notify.Star1} {notify.Star2} {notify.Star3}"
});
});
}
}
}

View File

@@ -6,11 +6,10 @@ namespace cmonitor.server.client.reports.screen
public class DesktopFrame
{
public Memory<byte> FullImage { get; internal set; }
public Rectangle[] UpdatedRegions { get; internal set; }
public Memory<byte> RegionImage { get; internal set; }
public Rectangle[] UpdatedRegions { get; internal set; }
public MovedRegion[] MovedRegions { get; internal set; }
//public Rectangle[] Updateds { get; internal set; }
}

View File

@@ -0,0 +1,26 @@
using common.libs.helpers;
namespace cmonitor.server.client.reports.screen
{
public interface IScreen
{
public DisplayInfo[] GetDisplays(out int w, out int h);
public void SetDisplayState(bool onState);
public uint GetLastInputTime();
public void Clip(ScreenClipInfo _screenClipInfo);
public bool IsClip();
public DesktopFrame GetClipFrame();
public DesktopFrame GetFullFrame();
public DesktopFrame GetRegionFrame();
public void WakeUp();
public void ScreenShareState(ScreenShareStates screenShareState);
public void ScreenShare(Memory<byte> data);
}
}

View File

@@ -0,0 +1,55 @@
using common.libs.helpers;
namespace cmonitor.server.client.reports.screen
{
public sealed class ScreenLinux : IScreen
{
public DisplayInfo[] GetDisplays(out int w, out int h)
{
w = 0; h = 0;
return Array.Empty<DisplayInfo>();
}
public void SetDisplayState(bool onState)
{
}
public void Clip(ScreenClipInfo _screenClipInfo)
{
}
public bool IsClip()
{
return false;
}
public uint GetLastInputTime()
{
return 0;
}
public DesktopFrame GetClipFrame()
{
return null;
}
public DesktopFrame GetFullFrame()
{
return null;
}
public DesktopFrame GetRegionFrame()
{
return null;
}
public void WakeUp()
{
}
public void ScreenShareState(ScreenShareStates screenShareState)
{
}
public void ScreenShare(Memory<byte> data)
{
}
}
}

View File

@@ -0,0 +1,55 @@
using common.libs.helpers;
namespace cmonitor.server.client.reports.screen
{
public sealed class ScreenMacOS : IScreen
{
public DisplayInfo[] GetDisplays(out int w, out int h)
{
w = 0; h = 0;
return Array.Empty<DisplayInfo>();
}
public void SetDisplayState(bool onState)
{
}
public void Clip(ScreenClipInfo _screenClipInfo)
{
}
public bool IsClip()
{
return false;
}
public uint GetLastInputTime()
{
return 0;
}
public DesktopFrame GetClipFrame()
{
return null;
}
public DesktopFrame GetFullFrame()
{
return null;
}
public DesktopFrame GetRegionFrame()
{
return null;
}
public void WakeUp()
{
}
public void ScreenShareState(ScreenShareStates screenShareState)
{
}
public void ScreenShare(Memory<byte> data)
{
}
}
}

View File

@@ -2,9 +2,7 @@
using common.libs;
using cmonitor.server.service.messengers.screen;
using MemoryPack;
using cmonitor.server.client.reports.screen.helpers;
using cmonitor.server.client.reports.screen.winapiss;
using System.IO.MemoryMappedFiles;
using common.libs.helpers;
namespace cmonitor.server.client.reports.screen
{
@@ -16,27 +14,26 @@ namespace cmonitor.server.client.reports.screen
private readonly MessengerSender messengerSender;
private readonly Config config;
private readonly ClientConfig clientConfig;
private readonly IScreen screen;
private ScreenReportInfo report = new ScreenReportInfo();
private uint lastInput;
private readonly DxgiDesktop dxgiDesktop;
private readonly GdiDesktop gdiDesktop;
private DisplayInfo[] displays;
public ScreenReport(ClientSignInState clientSignInState, MessengerSender messengerSender, Config config, ClientConfig clientConfig)
public ScreenReport(ClientSignInState clientSignInState, MessengerSender messengerSender, Config config, ClientConfig clientConfig, IScreen screen)
{
this.clientSignInState = clientSignInState;
this.messengerSender = messengerSender;
this.config = config;
this.clientConfig = clientConfig;
this.screen = screen;
if (config.IsCLient)
{
dxgiDesktop = new DxgiDesktop(0, config);
gdiDesktop = new GdiDesktop(config);
CaptureTask();
DisplaysInit();
ScreenShareInit();
displays = screen.GetDisplays(out int w,out int h);
report.W = w;
report.H = h;
}
}
@@ -50,8 +47,7 @@ namespace cmonitor.server.client.reports.screen
{
report.Displays = Array.Empty<DisplayInfo>();
}
report.LT = LastInputHelper.GetLastInputInfo();
report.LT = screen.GetLastInputTime();
if (reportType == ReportType.Full || report.LT < lastInput || report.LT - lastInput > 1000)
{
lastInput = report.LT;
@@ -61,70 +57,36 @@ namespace cmonitor.server.client.reports.screen
}
private void DisplaysInit()
public void SetDisplayState(bool onState)
{
displays = DisplaysEnumerationHelper.GetDisplays();
if (DisplayHelper.GetSystemScale(out _, out _, out int w, out int h))
{
report.W = w;
report.H = h;
}
}
public void DisplayState(bool onState)
{
if (onState)
{
DisplayHelper.On();
}
else
{
DisplayHelper.Off();
}
screen.SetDisplayState(onState);
}
MemoryMappedFile mmf;
MemoryMappedViewAccessor accessor;
byte[] shareScreenBytes = new byte[1 * 1024 * 1024];
private void ScreenShareInit()
public void SetScreenShareState(ScreenShareStates screenShareState)
{
if (OperatingSystem.IsWindows())
{
mmf = MemoryMappedFile.CreateOrOpen($"{config.ShareMemoryKey}/screen", shareScreenBytes.Length);
accessor = mmf.CreateViewAccessor();
}
screen.ScreenShareState(screenShareState);
}
public void ScreenShareState(ScreenShareStates screenShareState)
public void SetScreenShareData(Memory<byte> data)
{
clientConfig.ScreenShareState = screenShareState;
screen.ScreenShare(data);
}
public void ScreenShare(Memory<byte> data)
{
if (data.Length > 0 && data.Length <= shareScreenBytes.Length && accessor != null)
{
data.CopyTo(shareScreenBytes);
accessor.WriteArray(0, shareScreenBytes, 0, data.Length);
}
}
private ScreenReportType screenReportType = ScreenReportType.Full;
private ScreenReportFullType screenReportFullType = ScreenReportFullType.Full | ScreenReportFullType.Trim;
private long ticks = 0;
public void CaptureFull(ScreenReportFullType screenReportFullType)
public void SetCaptureFull(ScreenReportFullType screenReportFullType)
{
ticks = DateTime.UtcNow.Ticks;
screenReportType = ScreenReportType.Full;
this.screenReportFullType |= screenReportFullType;
}
public void CaptureClip(ScreenClipInfo screenClipInfo)
public void SetCaptureClip(ScreenClipInfo screenClipInfo)
{
ticks = DateTime.UtcNow.Ticks;
screenReportType = ScreenReportType.Full;
gdiDesktop.Clip(screenClipInfo);
screen.Clip(screenClipInfo);
}
public void CaptureRegion()
public void SetCaptureRegion()
{
ticks = DateTime.UtcNow.Ticks;
screenReportType = ScreenReportType.Region;
@@ -134,10 +96,6 @@ namespace cmonitor.server.client.reports.screen
private Memory<byte> fullImageMemory = Helper.EmptyArray;
private void CaptureTask()
{
if (OperatingSystem.IsWindows() == false)
{
return;
}
Task.Factory.StartNew(async () =>
{
while (true)
@@ -181,13 +139,13 @@ namespace cmonitor.server.client.reports.screen
DesktopFrame frame = null;
long ticks = DateTime.UtcNow.Ticks;
if (gdiDesktop.IsClip())
if (screen.IsClip())
{
frame = gdiDesktop.GetLatestFrame();
frame = screen.GetClipFrame();
}
else if (screenReportType == ScreenReportType.Full)
{
frame = dxgiDesktop.GetLatestFullFrame();
frame = screen.GetFullFrame();
if (frame.FullImage.Length > 0)
{
fullImageMemory = frame.FullImage;
@@ -207,7 +165,7 @@ namespace cmonitor.server.client.reports.screen
}
else if (screenReportType == ScreenReportType.Region)
{
frame = dxgiDesktop.GetLatestRegionFrame();
frame = screen.GetRegionFrame();
}
report.CT = (uint)((DateTime.UtcNow.Ticks - ticks) / TimeSpan.TicksPerMillisecond);
@@ -251,21 +209,7 @@ namespace cmonitor.server.client.reports.screen
private void RandomCursorPos()
{
if (config.WakeUp == false) return;
try
{
if (CursorHelper.GetCursorPosition(out int x, out int y))
{
User32.SetCursorPos(x + 1, y + 1);
MouseHelper.MouseMove(1, 1);
}
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
Logger.Instance.Error(ex);
}
}
screen.WakeUp();
}
}

View File

@@ -10,12 +10,12 @@ using SharpDX.Mathematics.Interop;
using common.libs;
using Factory1 = SharpDX.DXGI.Factory1;
using common.libs.extends;
using cmonitor.server.client.reports.screen.helpers;
using System.Diagnostics;
using common.libs.winapis;
using common.libs.helpers;
namespace cmonitor.server.client.reports.screen
{
public sealed class DxgiDesktop
public sealed class ScreenWIndowsDxgi
{
private Adapter1 adapter;
private Device mDevice;
@@ -37,10 +37,10 @@ namespace cmonitor.server.client.reports.screen
private readonly Config config;
public DxgiDesktop(int whichMonitor, Config config)
public ScreenWIndowsDxgi(int whichMonitor, Config config)
: this(0, whichMonitor, config) { }
public DxgiDesktop(int whichGraphicsCardAdapter, int whichOutputDevice, Config config)
public ScreenWIndowsDxgi(int whichGraphicsCardAdapter, int whichOutputDevice, Config config)
{
this.whichGraphicsCardAdapter = whichGraphicsCardAdapter;
this.whichOutputDevice = whichOutputDevice;

View File

@@ -0,0 +1,108 @@
using common.libs;
using common.libs.helpers;
using common.libs.winapis;
using System.IO.MemoryMappedFiles;
namespace cmonitor.server.client.reports.screen
{
public sealed class ScreenWindows : IScreen
{
private readonly ScreenWIndowsDxgi dxgiDesktop;
private readonly ScreenWindowsGdi gdiDesktop;
public ScreenWindows(Config config)
{
dxgiDesktop = new ScreenWIndowsDxgi(0, config);
gdiDesktop = new ScreenWindowsGdi(config);
}
public DisplayInfo[] GetDisplays(out int w, out int h)
{
DisplayInfo[] displays = DisplaysEnumerationHelper.GetDisplays();
DisplayHelper.GetSystemScale(out _, out _, out w, out h);
return displays;
}
public void SetDisplayState(bool onState)
{
if (onState)
{
DisplayHelper.On();
}
else
{
DisplayHelper.Off();
}
}
public uint GetLastInputTime()
{
return LastInputHelper.GetLastInputInfo();
}
public void Clip(ScreenClipInfo screenClipInfo)
{
gdiDesktop.Clip(screenClipInfo);
}
public bool IsClip()
{
return gdiDesktop.IsClip();
}
public DesktopFrame GetClipFrame()
{
return gdiDesktop.GetLatestFrame();
}
public DesktopFrame GetFullFrame()
{
return dxgiDesktop.GetLatestFullFrame();
}
public DesktopFrame GetRegionFrame()
{
return dxgiDesktop.GetLatestRegionFrame();
}
public void WakeUp()
{
try
{
if (CursorHelper.GetCursorPosition(out int x, out int y))
{
User32.SetCursorPos(x + 1, y + 1);
MouseHelper.MouseMove(1, 1);
}
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
Logger.Instance.Error(ex);
}
}
}
MemoryMappedFile mmf;
MemoryMappedViewAccessor accessor;
byte[] shareScreenBytes = new byte[1 * 1024 * 1024];
private void ScreenShareInit()
{
if (OperatingSystem.IsWindows())
{
// mmf = MemoryMappedFile.CreateOrOpen($"{config.ShareMemoryKey}/screen", shareScreenBytes.Length);
// accessor = mmf.CreateViewAccessor();
}
}
public void ScreenShareState(ScreenShareStates screenShareState)
{
//clientConfig.ScreenShareState = screenShareState;
}
public void ScreenShare(Memory<byte> data)
{
if (data.Length > 0 && data.Length <= shareScreenBytes.Length && accessor != null)
{
data.CopyTo(shareScreenBytes);
accessor.WriteArray(0, shareScreenBytes, 0, data.Length);
}
}
}
}

View File

@@ -1,16 +1,16 @@
using System.Drawing.Imaging;
using System.Drawing;
using common.libs;
using cmonitor.server.client.reports.screen.helpers;
using cmonitor.server.client.reports.screen.winapiss;
using System.Runtime.InteropServices;
using common.libs.winapis;
using common.libs.helpers;
namespace cmonitor.server.client.reports.screen
{
public sealed class GdiDesktop
public sealed class ScreenWindowsGdi
{
private readonly Config config;
public GdiDesktop(Config config)
public ScreenWindowsGdi(Config config)
{
this.config = config;
}

View File

@@ -1,5 +1,4 @@
using cmonitor.libs;
using common.libs.extends;
using MemoryPack;
namespace cmonitor.server.client.reports.share
@@ -10,7 +9,7 @@ namespace cmonitor.server.client.reports.share
private readonly Config config;
private ShareMemory shareMemory;
Dictionary<string, libs.ShareItemInfo> dic = new Dictionary<string, cmonitor.libs.ShareItemInfo>();
Dictionary<string, libs.ShareItemInfo> dic = new Dictionary<string, libs.ShareItemInfo>();
public ShareReport(Config config)
{
@@ -32,16 +31,13 @@ namespace cmonitor.server.client.reports.share
private void InitShare()
{
if (OperatingSystem.IsWindows())
{
shareMemory = new ShareMemory(config.ShareMemoryKey, config.ShareMemoryLength, config.ShareMemoryItemSize);
shareMemory.InitLocal();
shareMemory.InitGlobal();
shareMemory.WriteRunning(0, true);
shareMemory.WriteClosed(0, false);
shareMemory.StateAction(ShareMemoryStateChanged);
shareMemory.Loop();
}
shareMemory = new ShareMemory(config.ShareMemoryKey, config.ShareMemoryLength, config.ShareMemoryItemSize);
shareMemory.InitLocal();
shareMemory.InitGlobal();
shareMemory.WriteRunning(0, true);
shareMemory.WriteClosed(0, false);
shareMemory.StateAction(ShareMemoryStateChanged);
shareMemory.Loop();
}
private bool GetShare()
{

View File

@@ -0,0 +1,47 @@
using MemoryPack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static cmonitor.server.client.reports.system.SystemOptionHelper;
namespace cmonitor.server.client.reports.system
{
public interface ISystem
{
public ReportDriveInfo[] GetAllDrives();
public Dictionary<string, SystemOptionKeyInfo> GetOptionKeys();
public string GetOptionValues();
public bool OptionUpdate(SystemOptionUpdateInfo optionUpdateInfo);
public void OptionRefresh();
public bool Password(PasswordInputInfo command);
public double GetCpu();
public double GetMemory();
}
public sealed class ReportDriveInfo
{
public string Name { get; set; }
public long Free { get; set; }
public long Total { get; set; }
}
public sealed class SystemOptionKeyInfo
{
public string Desc { get; set; }
public ushort Index { get; set; }
}
[MemoryPackable]
public sealed partial class PasswordInputInfo
{
public string OldPassword { get; set; }
public string NewPassword { get; set; }
}
}

View File

@@ -0,0 +1,45 @@
namespace cmonitor.server.client.reports.system
{
public sealed class SystemLinux : ISystem
{
public ReportDriveInfo[] GetAllDrives()
{
return Array.Empty<ReportDriveInfo>();
}
public double GetCpu()
{
return 0;
}
public double GetMemory()
{
return 0;
}
public Dictionary<string, SystemOptionKeyInfo> GetOptionKeys()
{
return new Dictionary<string, SystemOptionKeyInfo>();
}
public string GetOptionValues()
{
return string.Empty;
}
public void OptionRefresh()
{
}
public bool OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
{
return true;
}
public bool Password(PasswordInputInfo command)
{
return true;
}
}
}

View File

@@ -0,0 +1,45 @@
namespace cmonitor.server.client.reports.system
{
public sealed class SystemMacOS : ISystem
{
public ReportDriveInfo[] GetAllDrives()
{
return Array.Empty<ReportDriveInfo>();
}
public double GetCpu()
{
return 0;
}
public double GetMemory()
{
return 0;
}
public Dictionary<string, SystemOptionKeyInfo> GetOptionKeys()
{
return new Dictionary<string, SystemOptionKeyInfo>();
}
public string GetOptionValues()
{
return string.Empty;
}
public void OptionRefresh()
{
}
public bool OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
{
return true;
}
public bool Password(PasswordInputInfo command)
{
return true;
}
}
}

View File

@@ -1,8 +1,4 @@
using cmonitor.server.client.reports.screen;
using cmonitor.server.client.reports.screen.winapis;
using common.libs;
using MemoryPack;
using Microsoft.Win32;
using MemoryPack;
namespace cmonitor.server.client.reports.system
{
@@ -11,21 +7,23 @@ namespace cmonitor.server.client.reports.system
public string Name => "System";
private readonly SystemReportInfo systemReportInfo = new SystemReportInfo();
private readonly RegistryOptionHelper registryOptionHelper;
private readonly ISystem system;
private double lastCpu;
private double lastMemory;
private ReportDriveInfo[] drives;
private Dictionary<string, RegistryOptionHelper.RegistryOptionKeyInfo> registryKeys;
private Dictionary<string, SystemOptionKeyInfo> registryKeys;
public SystemReport(ClientConfig clientConfig)
public SystemReport(ISystem system,Config config)
{
registryOptionHelper = new RegistryOptionHelper(clientConfig);
drives = WindowsDrive.GetAllDrives();
registryKeys = registryOptionHelper.GetKeys();
ReportTask();
RegistryOptions(new RegistryUpdateInfo { Name = "SoftwareSASGeneration", Value = false });
this.system = system;
if (config.IsCLient)
{
drives = system.GetAllDrives();
registryKeys = system.GetOptionKeys();
ReportTask();
}
}
@@ -53,56 +51,30 @@ namespace cmonitor.server.client.reports.system
return null;
}
public bool Password(PasswordInputInfo command)
public bool Password(PasswordInputInfo info)
{
return NetApi32.ChangePassword(null, Environment.UserName, command.OldPassword, command.NewPassword);
return system.Password(info);
}
int registryUpdated = 0;
int registryUpdateFlag = 1;
public bool RegistryOptions(RegistryUpdateInfo registryUpdateInfo)
public bool OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
{
bool result = registryOptionHelper.UpdateValue(registryUpdateInfo.Name, registryUpdateInfo.Value);
if (result)
{
Interlocked.Exchange(ref registryUpdated, 1);
}
return result;
}
private void RegistryForce()
{
if (registryUpdated == 1 && registryUpdated == 1)
{
Interlocked.CompareExchange(ref registryUpdated, 0, 1);
Interlocked.CompareExchange(ref registryUpdateFlag, 0, 1);
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
Interlocked.CompareExchange(ref registryUpdateFlag, 1, 0);
});
}
return system.OptionUpdate(registryUpdateInfo);
}
private void ReportTask()
{
CPUTime oldTime = WindowsCPU.GetCPUTime();
Task.Factory.StartNew(() =>
{
while (true)
{
if ((DateTime.UtcNow.Ticks - ticks) / TimeSpan.TicksPerMillisecond < 1000)
{
CPUTime newTime = WindowsCPU.GetCPUTime();
systemReportInfo.Cpu = CPUHelper.CalculateCPULoad(oldTime, newTime);
oldTime = newTime;
systemReportInfo.Memory = WindowsMemory.GetMemoryUsage();
systemReportInfo.RegValues = registryOptionHelper.GetValues();
systemReportInfo.Cpu = system.GetCpu();
systemReportInfo.Memory = system.GetMemory();
systemReportInfo.RegValues = system.GetOptionValues();
//systemReportInfo.Disk = WindowsDrive.GetDiskUsage();
}
RegistryForce();
system.OptionRefresh();
Thread.Sleep(1000);
@@ -120,313 +92,18 @@ namespace cmonitor.server.client.reports.system
public ReportDriveInfo[] Drives { get; set; }
public string RegValues { get; set; }
public Dictionary<string, RegistryOptionHelper.RegistryOptionKeyInfo> RegKeys { get; set; }
public Dictionary<string, SystemOptionKeyInfo> RegKeys { get; set; }
}
[MemoryPackable]
public sealed partial class PasswordInputInfo
{
public string OldPassword { get; set; }
public string NewPassword { get; set; }
}
[MemoryPackable]
public sealed partial class RegistryUpdateInfo
public sealed partial class SystemOptionUpdateInfo
{
public string Name { get; set; }
public bool Value { get; set; }
}
public sealed class RegistryOptionHelper
{
private string currentUserSid = string.Empty;
private readonly ClientConfig clientConfig;
char[] values;
public RegistryOptionHelper(ClientConfig clientConfig)
{
this.clientConfig = clientConfig;
values = string.Empty.PadLeft(Infos.Length, '0').ToCharArray();
GetSid();
}
public string GetValues()
{
GetSid();
if (OperatingSystem.IsWindows())
{
for (int i = 0; i < Infos.Length; i++)
{
RegistryOptionInfo item = Infos[i];
foreach (RegistryOptionPathInfo pathItem in item.Paths)
{
string path = ReplaceRegistryPath(pathItem.Path);
if (string.IsNullOrWhiteSpace(path))
{
continue;
}
object obj = Registry.GetValue(path, pathItem.Key, null);
values[i] = '0';
if (obj != null)
{
values[i] = (obj.ToString() == pathItem.DisallowValue ? '1' : '0');
}
}
}
}
return new string(values);
}
public bool UpdateValue(string name, bool value)
{
if (string.IsNullOrWhiteSpace(currentUserSid))
{
return false;
}
RegistryOptionInfo info = Infos.FirstOrDefault(c => c.Key == name);
if (info == null) return false;
if (OperatingSystem.IsWindows())
{
foreach (RegistryOptionPathInfo pathItem in info.Paths)
{
string path = ReplaceRegistryPath(pathItem.Path);
if (string.IsNullOrWhiteSpace(path))
{
continue;
}
string setValue = value ? pathItem.DisallowValue : pathItem.AllowValue;
if(Registry.GetValue(path, pathItem.Key, pathItem.AllowValue).ToString() != setValue)
{
Registry.SetValue(path, pathItem.Key, int.Parse(setValue), RegistryValueKind.DWord);
return true;
}
}
}
return false;
}
private string ReplaceRegistryPath(string path)
{
if (!string.IsNullOrWhiteSpace(currentUserSid))
{
return path.Replace("HKEY_CURRENT_USER", $"HKEY_USERS\\{currentUserSid}");
}
return string.Empty;
}
private void GetSid()
{
if (string.IsNullOrWhiteSpace(currentUserSid))
{
currentUserSid = clientConfig.UserSid;
}
if (string.IsNullOrWhiteSpace(currentUserSid))
{
currentUserSid = Win32Interop.GetCurrentUserSid();
clientConfig.UserSid = currentUserSid;
}
if (string.IsNullOrWhiteSpace(currentUserSid))
{
currentUserSid = Win32Interop.GetDefaultUserSid();
clientConfig.UserSid = currentUserSid;
}
}
public Dictionary<string, RegistryOptionKeyInfo> GetKeys()
{
Dictionary<string, RegistryOptionKeyInfo> keys = new Dictionary<string, RegistryOptionKeyInfo>();
for (int i = 0; i < Infos.Length; i++)
{
RegistryOptionInfo item = Infos[i];
keys[item.Key] = new RegistryOptionKeyInfo { Desc = item.Desc, Index = (ushort)i };
}
return keys;
}
//Desc为空则不显示
private RegistryOptionInfo[] Infos = new RegistryOptionInfo[] {
new RegistryOptionInfo{
Key="LockTaskbar",
Desc="任务栏锁定",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="LockTaskbar", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="TaskbarLockAll",
Desc="任务栏设置",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="TaskbarLockAll", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoTrayContextMenu",
Desc="任务栏菜单",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoTrayContextMenu", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="DisableTaskMgr",
Desc="任务管理器",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableTaskMgr", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="DisableRegistryTools",
Desc="注册表编辑",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableRegistryTools", DisallowValue="0", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="RestrictRun",
Desc="所有运行",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="RestrictRun", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoControlPanel",
Desc="系统设置",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoControlPanel", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoSaveSettings",
Desc="保存设置",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoSaveSettings", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoThemesTab",
Desc="修改主题",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoThemesTab", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoChangingWallPaper",
Desc="修改壁纸",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\ActiveDesktop", Key="NoChangingWallPaper", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoDispAppearancePage",
Desc="颜色外观",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="NoDispAppearancePage", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoDispBackgroundPage",
Desc="桌面图标",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="NoDispBackgroundPage", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="ScreenSaveActive",
Desc="屏幕保护",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Control Panel\\Desktop", Key="ScreenSaveActive", DisallowValue="0", AllowValue="1" }
}
},
new RegistryOptionInfo{
Key="ScreenSaverIsSecure",
Desc="唤醒登录",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Control Panel\\Desktop", Key="ScreenSaverIsSecure", DisallowValue="0", AllowValue="1" }
}
},
new RegistryOptionInfo{
Key="AutoLock",
Desc="关屏锁屏",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Power\\PowerSettings\\7516b95f-f776-4464-8c53-06167f40cc99\\8EC4B3A5-6868-48c2-BE75-4F3044BE88A7", Key="Attributes", DisallowValue="0", AllowValue="1" }
}
},
new RegistryOptionInfo{
Key="NoClose",
Desc="关机按钮",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoClose", DisallowValue="1", AllowValue="0" },
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="ShutdownWithoutLogon", DisallowValue="1", AllowValue="0" },
}
},
new RegistryOptionInfo{
Key="NoLogOff",
Desc="注销按钮",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="StartMenuLogOff", DisallowValue="1", AllowValue="0" },
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoLogOff", DisallowValue="1", AllowValue="0" },
}
},
new RegistryOptionInfo{
Key="DisableLockWorkstation",
Desc="锁定按钮",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableLockWorkstation", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="DisableChangePassword",
Desc="修改密码",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableChangePassword", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="HideFastUserSwitching",
Desc="切换用户",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="HideFastUserSwitching", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="SoftwareSASGeneration",
Desc="安全SAS",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="SoftwareSASGeneration", DisallowValue="0", AllowValue="3" }
}
},
new RegistryOptionInfo{
Key="USBSTOR",
Desc="U盘",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\USBSTOR", Key="Start", DisallowValue="4", AllowValue="3" }
}
}
};
sealed class RegistryOptionInfo
{
public string Key { get; set; } = string.Empty;
public string Desc { get; set; } = string.Empty;
public RegistryOptionPathInfo[] Paths { get; set; }
}
sealed class RegistryOptionPathInfo
{
public string Path { get; set; }
public string Key { get; set; }
public string DisallowValue { get; set; }
public string AllowValue { get; set; }
}
public sealed class RegistryOptionKeyInfo
{
public string Desc { get; set; }
public ushort Index { get; set; }
}
}
}

View File

@@ -0,0 +1,365 @@
using common.libs;
using common.libs.winapis;
using Microsoft.Win32;
namespace cmonitor.server.client.reports.system
{
public sealed class SystemWindows : ISystem
{
private readonly SystemOptionHelper registryOptionHelper;
public SystemWindows(ClientConfig clientConfig,Config config)
{
if (config.IsCLient)
{
registryOptionHelper = new SystemOptionHelper(clientConfig);
OptionUpdate(new SystemOptionUpdateInfo { Name = "SoftwareSASGeneration", Value = false });
}
}
public ReportDriveInfo[] GetAllDrives()
{
return DriveInfo.GetDrives().Select(c => new ReportDriveInfo
{
Name = c.Name,
Free = c.TotalFreeSpace,
Total = c.TotalSize
}).ToArray();
}
public Dictionary<string, SystemOptionKeyInfo> GetOptionKeys()
{
return registryOptionHelper.GetKeys();
}
public string GetOptionValues()
{
return registryOptionHelper.GetValues();
}
public bool OptionUpdate(SystemOptionUpdateInfo registryUpdateInfo)
{
bool result = registryOptionHelper.UpdateValue(registryUpdateInfo.Name, registryUpdateInfo.Value);
if (result)
{
Interlocked.Exchange(ref registryUpdated, 1);
}
return result;
}
int registryUpdated = 0;
int registryUpdateFlag = 1;
public void OptionRefresh()
{
if (registryUpdated == 1 && registryUpdated == 1)
{
Interlocked.CompareExchange(ref registryUpdated, 0, 1);
Interlocked.CompareExchange(ref registryUpdateFlag, 0, 1);
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
Interlocked.CompareExchange(ref registryUpdateFlag, 1, 0);
});
}
}
public bool Password(PasswordInputInfo command)
{
return NetApi32.ChangePassword(null, Environment.UserName, command.OldPassword, command.NewPassword);
}
CPUTime oldTime = new CPUTime(0,0);
public double GetCpu()
{
CPUTime newTime = SystemWindowsCPU.GetCPUTime();
double value = CPUHelper.CalculateCPULoad(oldTime, newTime);
oldTime = newTime;
return value;
}
public double GetMemory()
{
return SystemWindowsMemory.GetMemoryUsage();
}
}
public sealed class SystemOptionHelper
{
private string currentUserSid = string.Empty;
private readonly ClientConfig clientConfig;
char[] values;
public SystemOptionHelper(ClientConfig clientConfig)
{
this.clientConfig = clientConfig;
values = string.Empty.PadLeft(Infos.Length, '0').ToCharArray();
GetSid();
}
public string GetValues()
{
GetSid();
if (OperatingSystem.IsWindows())
{
for (int i = 0; i < Infos.Length; i++)
{
RegistryOptionInfo item = Infos[i];
foreach (RegistryOptionPathInfo pathItem in item.Paths)
{
string path = ReplaceRegistryPath(pathItem.Path);
if (string.IsNullOrWhiteSpace(path))
{
continue;
}
object obj = Registry.GetValue(path, pathItem.Key, null);
values[i] = '0';
if (obj != null)
{
values[i] = (obj.ToString() == pathItem.DisallowValue ? '1' : '0');
}
}
}
}
return new string(values);
}
public bool UpdateValue(string name, bool value)
{
if (string.IsNullOrWhiteSpace(currentUserSid))
{
return false;
}
RegistryOptionInfo info = Infos.FirstOrDefault(c => c.Key == name);
if (info == null) return false;
if (OperatingSystem.IsWindows())
{
foreach (RegistryOptionPathInfo pathItem in info.Paths)
{
string path = ReplaceRegistryPath(pathItem.Path);
if (string.IsNullOrWhiteSpace(path))
{
continue;
}
string setValue = value ? pathItem.DisallowValue : pathItem.AllowValue;
if (Registry.GetValue(path, pathItem.Key, pathItem.AllowValue).ToString() != setValue)
{
Registry.SetValue(path, pathItem.Key, int.Parse(setValue), RegistryValueKind.DWord);
return true;
}
}
}
return false;
}
private string ReplaceRegistryPath(string path)
{
if (!string.IsNullOrWhiteSpace(currentUserSid))
{
return path.Replace("HKEY_CURRENT_USER", $"HKEY_USERS\\{currentUserSid}");
}
return string.Empty;
}
private void GetSid()
{
if (string.IsNullOrWhiteSpace(currentUserSid))
{
currentUserSid = clientConfig.UserSid;
}
if (string.IsNullOrWhiteSpace(currentUserSid))
{
currentUserSid = Win32Interop.GetCurrentUserSid();
clientConfig.UserSid = currentUserSid;
}
if (string.IsNullOrWhiteSpace(currentUserSid))
{
currentUserSid = Win32Interop.GetDefaultUserSid();
clientConfig.UserSid = currentUserSid;
}
}
public Dictionary<string, SystemOptionKeyInfo> GetKeys()
{
Dictionary<string, SystemOptionKeyInfo> keys = new Dictionary<string, SystemOptionKeyInfo>();
for (int i = 0; i < Infos.Length; i++)
{
RegistryOptionInfo item = Infos[i];
keys[item.Key] = new SystemOptionKeyInfo { Desc = item.Desc, Index = (ushort)i };
}
return keys;
}
//Desc为空则不显示
private RegistryOptionInfo[] Infos = new RegistryOptionInfo[] {
new RegistryOptionInfo{
Key="LockTaskbar",
Desc="任务栏锁定",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="LockTaskbar", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="TaskbarLockAll",
Desc="任务栏设置",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="TaskbarLockAll", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoTrayContextMenu",
Desc="任务栏菜单",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoTrayContextMenu", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="DisableTaskMgr",
Desc="任务管理器",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableTaskMgr", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="DisableRegistryTools",
Desc="注册表编辑",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableRegistryTools", DisallowValue="0", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="RestrictRun",
Desc="所有运行",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="RestrictRun", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoControlPanel",
Desc="系统设置",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoControlPanel", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoSaveSettings",
Desc="保存设置",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoSaveSettings", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoThemesTab",
Desc="修改主题",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoThemesTab", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoChangingWallPaper",
Desc="修改壁纸",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\ActiveDesktop", Key="NoChangingWallPaper", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoDispAppearancePage",
Desc="颜色外观",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="NoDispAppearancePage", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="NoDispBackgroundPage",
Desc="桌面图标",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="NoDispBackgroundPage", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="ScreenSaveActive",
Desc="屏幕保护",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Control Panel\\Desktop", Key="ScreenSaveActive", DisallowValue="0", AllowValue="1" }
}
},
new RegistryOptionInfo{
Key="ScreenSaverIsSecure",
Desc="唤醒登录",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Control Panel\\Desktop", Key="ScreenSaverIsSecure", DisallowValue="0", AllowValue="1" }
}
},
new RegistryOptionInfo{
Key="AutoLock",
Desc="关屏锁屏",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Power\\PowerSettings\\7516b95f-f776-4464-8c53-06167f40cc99\\8EC4B3A5-6868-48c2-BE75-4F3044BE88A7", Key="Attributes", DisallowValue="0", AllowValue="1" }
}
},
new RegistryOptionInfo{
Key="NoClose",
Desc="关机按钮",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoClose", DisallowValue="1", AllowValue="0" },
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="ShutdownWithoutLogon", DisallowValue="1", AllowValue="0" },
}
},
new RegistryOptionInfo{
Key="NoLogOff",
Desc="注销按钮",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="StartMenuLogOff", DisallowValue="1", AllowValue="0" },
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", Key="NoLogOff", DisallowValue="1", AllowValue="0" },
}
},
new RegistryOptionInfo{
Key="DisableLockWorkstation",
Desc="锁定按钮",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableLockWorkstation", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="DisableChangePassword",
Desc="修改密码",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="DisableChangePassword", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="HideFastUserSwitching",
Desc="切换用户",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="HideFastUserSwitching", DisallowValue="1", AllowValue="0" }
}
},
new RegistryOptionInfo{
Key="SoftwareSASGeneration",
Desc="安全SAS",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", Key="SoftwareSASGeneration", DisallowValue="0", AllowValue="3" }
}
},
new RegistryOptionInfo{
Key="USBSTOR",
Desc="U盘",
Paths = new RegistryOptionPathInfo[]{
new RegistryOptionPathInfo{ Path="HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\USBSTOR", Key="Start", DisallowValue="4", AllowValue="3" }
}
}
};
sealed class RegistryOptionInfo
{
public string Key { get; set; } = string.Empty;
public string Desc { get; set; } = string.Empty;
public RegistryOptionPathInfo[] Paths { get; set; }
}
sealed class RegistryOptionPathInfo
{
public string Path { get; set; }
public string Key { get; set; }
public string DisallowValue { get; set; }
public string AllowValue { get; set; }
}
}
}

View File

@@ -8,7 +8,7 @@ namespace cmonitor.server.client.reports.system
public static CPUTime GetCPUTime()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return WindowsCPU.GetCPUTime();
return SystemWindowsCPU.GetCPUTime();
return new CPUTime();
}
@@ -24,7 +24,7 @@ namespace cmonitor.server.client.reports.system
}
public partial class WindowsCPU
public partial class SystemWindowsCPU
{
#if NET7_0_OR_GREATER
[LibraryImport("kernel32.dll", SetLastError = true)]

View File

@@ -2,7 +2,7 @@
namespace cmonitor.server.client.reports.system
{
public static class WindowsMemory
public static class SystemWindowsMemory
{
public static double GetMemoryUsage()

View File

@@ -1,55 +0,0 @@
namespace cmonitor.server.client.reports.system
{
public static class WindowsDrive
{
public static ReportDriveInfo[] GetAllDrives()
{
return DriveInfo.GetDrives().Select(c => new ReportDriveInfo
{
Name = c.Name,
Free = c.TotalFreeSpace,
Total = c.TotalSize
}).ToArray();
}
/*
static PerformanceCounter diskTimeCounter;
static DateTime previousTime = DateTime.Now;
static float previousValue = 0;
public static float GetDiskUsage()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (diskTimeCounter == null)
{
diskTimeCounter = new PerformanceCounter("PhysicalDisk", "% Disk Time", "_Total");
previousValue = diskTimeCounter.NextValue();
previousTime = DateTime.Now;
return 0;
}
float currentValue = diskTimeCounter.NextValue();
DateTime currentTime = DateTime.Now;
float deltaTimeSeconds = (float)(currentTime - previousTime).TotalSeconds;
float diskUsage = Math.Min(100f, ((currentValue + previousValue) / 2f) * deltaTimeSeconds);
previousValue = currentValue;
previousTime = currentTime;
return diskUsage;
}
return 0;
}
*/
}
public sealed class ReportDriveInfo
{
public string Name { get; set; }
public long Free { get; set; }
public long Total { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
namespace cmonitor.server.client.reports.volume
{
public interface IVolume
{
public float GetVolume();
public void SetVolume(float value);
public float GetMasterPeak();
public bool GetMute();
public void SetMute(bool value);
public void Play(byte[] audioBytes);
}
}

View File

@@ -0,0 +1,32 @@
namespace cmonitor.server.client.reports.volume
{
public sealed class VolumeLinux : IVolume
{
public float GetMasterPeak()
{
return 0;
}
public bool GetMute()
{
return false;
}
public float GetVolume()
{
return 0;
}
public void Play(byte[] audioBytes)
{
}
public void SetMute(bool value)
{
}
public void SetVolume(float value)
{
}
}
}

View File

@@ -0,0 +1,32 @@
namespace cmonitor.server.client.reports.volume
{
public sealed class VolumeMacOS : IVolume
{
public float GetMasterPeak()
{
return 0;
}
public bool GetMute()
{
return false;
}
public float GetVolume()
{
return 0;
}
public void Play(byte[] audioBytes)
{
}
public void SetMute(bool value)
{
}
public void SetVolume(float value)
{
}
}
}

View File

@@ -1,7 +1,4 @@
using NAudio.CoreAudioApi;
using NAudio.Wave;
namespace cmonitor.server.client.reports.volume
namespace cmonitor.server.client.reports.volume
{
public sealed class VolumeReport : IReport
{
@@ -12,22 +9,20 @@ namespace cmonitor.server.client.reports.volume
private float lastMasterPeak;
private readonly Config config;
public VolumeReport(Config config)
private readonly IVolume volume;
public VolumeReport(Config config, IVolume volume)
{
this.config = config;
Init();
this.volume = volume;
}
public object GetReports(ReportType reportType)
{
if (OperatingSystem.IsWindows())
report.Value = volume.GetVolume();
report.Mute = volume.GetMute();
if (config.VolumeMasterPeak)
{
report.Value = GetVolume();
report.Mute = GetVolumeMute();
if (config.VolumeMasterPeak)
{
report.MasterPeak = GetMasterPeakValue();
}
report.MasterPeak = volume.GetMasterPeak();
}
if (reportType == ReportType.Full || report.Value != lastValue || report.Mute != lastMute || report.MasterPeak != lastMasterPeak)
{
@@ -40,247 +35,19 @@ namespace cmonitor.server.client.reports.volume
}
private float GetVolume()
public void SetVolume(float value)
{
try
{
return defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100;
}
catch (Exception)
{
}
return 0;
volume.SetVolume(value);
}
public void SetVolume(float volume)
public void SetMute(bool value)
{
try
{
volume = Math.Max(0, Math.Min(volume, 1));
defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar = volume;
}
catch (Exception)
{
}
volume.SetMute(value);
}
public void Play(byte[] audioBytes)
{
volume.Play(audioBytes);
}
public bool GetVolumeMute()
{
try
{
return defaultDevice.AudioEndpointVolume.Mute;
}
catch (Exception)
{
}
return false;
}
public bool SetVolumeMute(bool mute)
{
try
{
defaultDevice.AudioEndpointVolume.Mute = mute;
}
catch (Exception)
{
}
return false;
}
private float GetMasterPeakValue()
{
try
{
return information.MasterPeakValue * 100;
}
catch (Exception)
{
}
return 0;
}
public void PlayAudio(byte[] audioBytes)
{
using WaveFileReader stream = new WaveFileReader(new MemoryStream(audioBytes));
using WaveOutEvent player = new WaveOutEvent();
player.Init(stream);
player.Play();
while (player.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(100);
}
}
MMDeviceEnumerator deviceEnumerator;
MMDevice defaultDevice;
AudioMeterInformation information;
private void Init()
{
if (OperatingSystem.IsWindows())
{
deviceEnumerator = new MMDeviceEnumerator();
defaultDevice = deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
information = defaultDevice.AudioMeterInformation;
}
}
/*
private IntPtr pEnumerator = IntPtr.Zero;
private IntPtr pDevice = IntPtr.Zero;
private IntPtr pEndpointVolume = IntPtr.Zero;
private IntPtr pMeterInfo = IntPtr.Zero;
private float GetVolume()
{
try
{
if (pEndpointVolume != IntPtr.Zero)
{
return GetSystemVolume(pEndpointVolume) * 100;
}
}
catch (Exception)
{
}
return 0;
}
private float GetMasterPeakValue()
{
try
{
if (pMeterInfo != IntPtr.Zero)
{
return GetSystemMasterPeak(pMeterInfo) * 100;
}
}
catch (Exception)
{
}
return 0;
}
private bool GetVolumeMute()
{
try
{
if (pEndpointVolume != IntPtr.Zero)
{
return GetSystemMute(pEndpointVolume);
}
}
catch (Exception)
{
}
return false;
}
public void SetVolume(float volume)
{
try
{
volume = Math.Max(0, Math.Min(1, volume));
if (pEndpointVolume != IntPtr.Zero)
{
SetSystemVolume(pEndpointVolume, volume);
}
}
catch (Exception)
{
}
}
public void SetVolumeMute(bool mute)
{
try
{
if (pEndpointVolume != IntPtr.Zero)
{
SetSystemMute(pEndpointVolume, mute);
}
}
catch (Exception)
{
}
}
private void Init()
{
if (OperatingSystem.IsWindows())
{
try
{
pEnumerator = InitSystemDeviceEnumerator();
if (pEnumerator != IntPtr.Zero)
{
pDevice = InitSystemDevice(pEnumerator);
if (pDevice != IntPtr.Zero)
{
pEndpointVolume = InitSystemAudioEndpointVolume(pDevice);
pMeterInfo = InitSystemAudioMeterInformation(pDevice);
}
}
FreeDevice();
}
catch (Exception ex)
{
Logger.Instance.Error(ex);
}
}
}
private void FreeVolume()
{
FreeSystemDevice(pEnumerator, pDevice, pEndpointVolume, pMeterInfo);
pEnumerator = IntPtr.Zero;
pDevice = IntPtr.Zero;
pEndpointVolume = IntPtr.Zero;
pMeterInfo = IntPtr.Zero;
}
private void FreeDevice()
{
FreeSystemDevice(pEnumerator, pDevice, IntPtr.Zero, IntPtr.Zero);
pEnumerator = IntPtr.Zero;
pDevice = IntPtr.Zero;
}
~VolumeReport()
{
FreeVolume();
pEnumerator = IntPtr.Zero;
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing && pEnumerator != IntPtr.Zero)
{
FreeVolume();
}
}
[DllImport("cmonitor.volume.dll")]
public static extern IntPtr InitSystemDeviceEnumerator();
[DllImport("cmonitor.volume.dll")]
public static extern IntPtr InitSystemDevice(IntPtr pEnumerator);
[DllImport("cmonitor.volume.dll")]
public static extern IntPtr InitSystemAudioEndpointVolume(IntPtr pDevice);
[DllImport("cmonitor.volume.dll")]
public static extern IntPtr InitSystemAudioMeterInformation(IntPtr pDevice);
[DllImport("cmonitor.volume.dll")]
public static extern bool FreeSystemDevice(IntPtr pEnumerator, IntPtr pDevice, IntPtr pEndpointVolume, IntPtr pMeterInfo);
[DllImport("cmonitor.volume.dll")]
public static extern float GetSystemVolume(IntPtr pEndpointVolume);
[DllImport("cmonitor.volume.dll")]
public static extern bool SetSystemVolume(IntPtr pEndpointVolume, float volume);
[DllImport("cmonitor.volume.dll")]
public static extern float GetSystemMasterPeak(IntPtr pMeterInfo);
[DllImport("cmonitor.volume.dll")]
public static extern bool GetSystemMute(IntPtr pEndpointVolume);
[DllImport("cmonitor.volume.dll")]
public static extern bool SetSystemMute(IntPtr pEndpointVolume, bool mute);
*/
}
public sealed class VolumeReportInfo

View File

@@ -0,0 +1,93 @@
using NAudio.CoreAudioApi;
using NAudio.Wave;
namespace cmonitor.server.client.reports.volume
{
public sealed class VolumeWindows : IVolume
{
MMDeviceEnumerator deviceEnumerator;
MMDevice defaultDevice;
AudioMeterInformation information;
public VolumeWindows(Config config)
{
if (config.IsCLient)
{
deviceEnumerator = new MMDeviceEnumerator();
defaultDevice = deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
information = defaultDevice.AudioMeterInformation;
}
}
public float GetMasterPeak()
{
try
{
return information.MasterPeakValue * 100;
}
catch (Exception)
{
}
return 0;
}
public bool GetMute()
{
try
{
return defaultDevice.AudioEndpointVolume.Mute;
}
catch (Exception)
{
}
return false;
}
public void SetMute(bool value)
{
try
{
defaultDevice.AudioEndpointVolume.Mute = value;
}
catch (Exception)
{
}
}
public float GetVolume()
{
try
{
return defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100;
}
catch (Exception)
{
}
return 0;
}
public void SetVolume(float value)
{
try
{
value = Math.Max(0, Math.Min(value, 1));
defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar = value;
}
catch (Exception)
{
}
}
public void Play(byte[] audioBytes)
{
using WaveFileReader stream = new WaveFileReader(new MemoryStream(audioBytes));
using WaveOutEvent player = new WaveOutEvent();
player.Init(stream);
player.Play();
while (player.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(100);
}
}
}
}

View File

@@ -0,0 +1,7 @@
namespace cmonitor.server.client.reports.wallpaper
{
public interface IWallpaper
{
public void Set(bool value, string url);
}
}

View File

@@ -0,0 +1,9 @@
namespace cmonitor.server.client.reports.wallpaper
{
public sealed class WallpaperLinux : IWallpaper
{
public void Set(bool value, string url)
{
}
}
}

View File

@@ -0,0 +1,9 @@
namespace cmonitor.server.client.reports.wallpaper
{
public sealed class WallpaperMacOS : IWallpaper
{
public void Set(bool value, string url)
{
}
}
}

View File

@@ -1,7 +1,6 @@
using cmonitor.server.client.reports.share;
using common.libs;
namespace cmonitor.server.client.reports.llock
namespace cmonitor.server.client.reports.wallpaper
{
public sealed class WallpaperReport : IReport
{
@@ -9,15 +8,15 @@ namespace cmonitor.server.client.reports.llock
private WallpaperReportInfo report = new WallpaperReportInfo();
private bool lastValue;
private readonly Config config;
private readonly ShareReport shareReport;
private readonly ClientConfig clientConfig;
private readonly IWallpaper wallpaper;
public WallpaperReport(Config config, ShareReport shareReport, ClientConfig clientConfig)
public WallpaperReport(ShareReport shareReport, ClientConfig clientConfig, IWallpaper wallpaper)
{
this.config = config;
this.shareReport = shareReport;
this.clientConfig = clientConfig;
this.wallpaper = wallpaper;
Update(clientConfig.Wallpaper, clientConfig.WallpaperUrl);
}
@@ -25,7 +24,7 @@ namespace cmonitor.server.client.reports.llock
DateTime startTime = new DateTime(1970, 1, 1);
public object GetReports(ReportType reportType)
{
clientConfig.Wallpaper = report.Value = shareReport.GetShare(Name, out cmonitor.libs.ShareItemInfo share)
clientConfig.Wallpaper = report.Value = shareReport.GetShare(Name, out libs.ShareItemInfo share)
&& string.IsNullOrWhiteSpace(share.Value) == false
&& long.TryParse(share.Value, out long time) && (long)(DateTime.UtcNow.Subtract(startTime)).TotalMilliseconds - time < 1000;
@@ -45,13 +44,7 @@ namespace cmonitor.server.client.reports.llock
{
shareReport.WriteClose(Config.ShareMemoryWallpaperIndex);
await Task.Delay(100);
if (open)
{
CommandHelper.Windows(string.Empty, new string[] {
$"start wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}"
});
}
wallpaper.Set(open,url);
});
}

View File

@@ -0,0 +1,22 @@
using common.libs;
namespace cmonitor.server.client.reports.wallpaper
{
public sealed class WallpaperWindows : IWallpaper
{
private readonly Config config;
public WallpaperWindows(Config config)
{
this.config = config;
}
public void Set(bool value, string url)
{
if (value)
{
CommandHelper.Windows(string.Empty, new string[] {
$"start wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}"
});
}
}
}
}

View File

@@ -25,7 +25,7 @@ namespace cmonitor.server.service.messengers.active
[MessengerId((ushort)ActiveMessengerIds.Windows)]
public void Windows(IConnection connection)
{
connection.Write(MemoryPackSerializer.Serialize(activeWindowReport.GetWIndows()));
connection.Write(MemoryPackSerializer.Serialize(activeWindowReport.GetWindows()));
}

View File

@@ -1,4 +1,4 @@
using cmonitor.server.client.reports.command;
using cmonitor.server.client.reports.keyboard;
using MemoryPack;
namespace cmonitor.server.service.messengers.keyboard

View File

@@ -24,7 +24,7 @@ namespace cmonitor.server.service.messengers.llock
[MessengerId((ushort)LLockMessengerIds.LockSystem)]
public void LockSystem(IConnection connection)
{
lLockReport.LockSystem();
//lLockReport.LockSystem();
}
}

Some files were not shown because too many files have changed in this diff Show More