Compare commits

...

19 Commits

Author SHA1 Message Date
Liang Su 14d6b2c4a5 移除安装脚本中RtIpAddressSetting快捷方式的创建。 2023-12-14 19:54:13 +08:00
Liang Su 5fb73414b8 修正SicUI的窗口标题。 2023-12-14 11:44:00 +08:00
Liang Su b23d475f69 修正SicSetup无法正确添加SicSimulator项目的问题。 2023-12-14 11:42:07 +08:00
Liang Su 01a45e72a2 修正UI的标题名称、版本号。 2023-12-14 11:31:12 +08:00
Liang Su 4f89a02f2b Merge branch 'Sic8ToSic6' into feature/evaluation-edition 2023-12-14 11:18:30 +08:00
Liang Su 682f0a0834 Simulator增加许可控制。
RT的LicenseError状态增加许可循环检查,当检测到可用许可时自动退出当前状态。
2023-12-14 11:18:06 +08:00
Liang Su 586a369e9f 更新库文件5bf383d,合并最新的develop分支更改的内容。 2023-12-14 11:17:00 +08:00
Liang Su 1cd12c6eb4 更新库文件6bee6e9,CDKey输入面板控件移至UI库。
MainView使用UI库中的CDKey输入面板控件。
2023-12-14 09:14:02 +08:00
Liang Su 1eec01bb21 修改安装包文件名。 2023-12-14 08:33:08 +08:00
Liang Su 3d1970419a SicSetup编译脚本增加SicSimulator处理。
NSIS脚本增加SicSimulator打包逻辑。
2023-12-13 17:35:32 +08:00
Liang Su 5de77049a8 MainView中License到期剩余天数小于3天时,剩余天数显示为红色。 2023-12-13 17:06:33 +08:00
Liang Su b8f991ed93 更新库文件83b5acb,LicManager的CheckInline()函数增加一些参数用于输出CDKEY信息。
MainView右下角增加License信息徽标。
2023-12-13 16:48:32 +08:00
Liang Su 3050159635 修正MainView加载时License输入框会短暂出现的问题。 2023-12-13 15:45:24 +08:00
Liang Su 74fed42f0a 调整MainView中License输入框的顺序。 2023-12-13 15:41:29 +08:00
Liang Su 275ea5924d 更新库文件c88f752,完善许可证相关代码。
EquipmentManager状态机中增加许可证检测相关的状态。
MainView增加许可证检查逻辑和许可证输入窗口。
修正许可证不可用时,OverView的Init等按钮使能状态不对的问题。
HomeAll中移除许可证检查相关的代码。
2023-12-12 18:48:10 +08:00
Liang Su fa89f27ebf 更新库文件587aa83,增加许可控制功能。
在HomeAll的Start()函数、MainView的OnTimer()函数中增加许可检查逻辑。
2023-12-12 11:01:23 +08:00
Liang Su 0867107863 整理MaineViewModel.cs代码格式。 2023-12-12 10:18:26 +08:00
Liang Su 8ed0c8561f 整理TimeredMainViewModel.cs代码格式。 2023-12-12 09:58:38 +08:00
Liang Su b9ab3770bf 安装脚本新增安装密码支持。 2023-12-12 08:44:45 +08:00
25 changed files with 756 additions and 207 deletions

View File

@ -193,10 +193,7 @@ namespace SicModules.PMs
{
get { return !IsInit && !IsSafety && !IsError && !IsIdle && !IsProcessIdle; }
}
public bool IsProcessing
{
get { return FsmState == (int)STATE.Process; }
}
public bool IsProcessing => FsmState is (int)STATE.Process or (int)STATE.PreProcess or (int)STATE.PostProcess;
public override bool IsIdle
{

View File

@ -571,5 +571,16 @@
Notify after mapped wafer.
</Solution>
</EventDefinition>
<EventDefinition>
<Id>6666</Id>
<Description>License checking failed, {0}</Description>
<Level>Alarm</Level>
<EventEnum>LicError</EventEnum>
<DetailDesc></DetailDesc>
<Solution>
Please apply new CD-KEY from supplier.
</Solution>
</EventDefinition>
</EventDefine>

View File

@ -1,8 +1,12 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Core.License;
using SicModules.Aligners;
using SicModules.Buffers;
using SicModules.Cassettes;
@ -31,7 +35,6 @@ namespace SicRT.Modules
EV.PostInfoLog("System",
"这是一个长字符串用于测试MainWindow的LOG下拉框是否约束了显示宽度这是一个长字符串用于测试MainWindow的LOG下拉框是否约束了显示宽度这是一个长字符串用于测试MainWindow的LOG下拉框是否约束了显示宽度");
_lstModules.Clear();
_homingModules.Clear();

View File

@ -13,7 +13,6 @@ using System.Threading.Tasks;
using Aitex.Core.RT.Device.Unit;
using Aitex.Core.RT.SCCore;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.UPS;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.AE;
using Aitex.Core.RT.Device.Devices;
using SicModules.Aligners;
using SicModules.Buffers;
@ -24,6 +23,7 @@ using SicModules.PMs;
using SicModules.TMs;
using SicModules.UnLoads;
using System.Diagnostics;
using MECF.Framework.Common.Core.License;
using MECF.Framework.RT.EquipmentLibrary.Devices;
namespace SicRT.Equipments.Systems
@ -46,6 +46,7 @@ namespace SicRT.Equipments.Systems
ReturnAllWafer,
Error,
LicenseError,
ShutDown = 999
}
@ -90,6 +91,7 @@ namespace SicRT.Equipments.Systems
SetOffline,
ModuleError,
Activated,
ShutDown = 999,
}
@ -118,6 +120,7 @@ namespace SicRT.Equipments.Systems
{
get { return FsmState == (int)RtState.Idle; }
}
public bool IsAlarm
{
get { return FsmState == (int)RtState.Error; }
@ -184,6 +187,8 @@ namespace SicRT.Equipments.Systems
public override bool Initialize()
{
GetMachineCode();
InitModules();
GetMainSignalTower();
@ -215,9 +220,11 @@ namespace SicRT.Equipments.Systems
_returnAll = new ReturnAllWafer();
SC.RegisterValueChangedCallback("TM.ProcessPressure", SetTansferPressure1);
SC.RegisterValueChangedCallback("TM.VacuumPressureBaseOffset", SetTansferPressure2);
// check license immediately
MonitorLicense();
return true;
}
@ -403,6 +410,7 @@ namespace SicRT.Equipments.Systems
//ShutDown
Transition(RtState.Init, MSG.ShutDown, FsmStartShutDown, RtState.ShutDown);
Transition(RtState.Idle, MSG.ShutDown, FsmStartShutDown, RtState.ShutDown);
Transition(RtState.LicenseError, MSG.ShutDown, FsmStartShutDown, RtState.ShutDown);
Transition(RtState.AutoIdle, MSG.ShutDown, FsmStartShutDown, RtState.ShutDown);
EnterExitTransition<RtState, FSM_MSG>(RtState.ShutDown, FsmShutDown, null, null);
@ -411,7 +419,6 @@ namespace SicRT.Equipments.Systems
Transition(RtState.Idle, MSG.HOME, FsmStartHome, RtState.Initializing);
Transition(RtState.Error, MSG.HOME, FsmStartHome, RtState.Initializing);
// EnterExitTransition<RtState, FSM_MSG>(RtState.Initializing, fStartInit, FSM_MSG.NONE, null);
Transition(RtState.Initializing, FSM_MSG.TIMER, FsmMonitorHome, RtState.Idle);
Transition(RtState.Initializing, MSG.ERROR, fError, RtState.Error);
@ -421,6 +428,14 @@ namespace SicRT.Equipments.Systems
Transition(RtState.Idle, MSG.SetOnline, FsmStartSetOnline, RtState.Idle);
Transition(RtState.Idle, MSG.SetOffline, FsmStartSetOffline, RtState.Idle);
// License
AnyStateTransition(FSM_MSG.LICERR, fLicenseError, RtState.LicenseError);
Transition(RtState.Init, FSM_MSG.TIMER, fMonitorlicense, RtState.Init);
Transition(RtState.Idle, FSM_MSG.TIMER, fMonitorlicense, RtState.Idle);
Transition(RtState.Error, FSM_MSG.TIMER, fMonitorlicense, RtState.Error);
Transition(RtState.LicenseError, FSM_MSG.TIMER, fMonitorlicense, RtState.LicenseError);
Transition(RtState.LicenseError, MSG.Activated, fLicenseActivated, RtState.Init);
//Reset
AnyStateTransition(MSG.RESET, fStartReset, RtState.Idle);
@ -471,14 +486,19 @@ namespace SicRT.Equipments.Systems
void SubscribeDataVariable()
{
DATA.Subscribe("Rt.Status", () => StringFsmStatus);
DATA.Subscribe("System.IsOnline", () => IsOnline);
DATA.Subscribe("System.IsIdle", () => IsIdle || IsInit);
DATA.Subscribe("System.IsAlarm", () => IsAlarm);
DATA.Subscribe("System.IsBusy", () => IsRunning);//System.IsBusy=>IsRunning绑定相同的值不同的地方用
DATA.Subscribe("System.IsAutoIdle", () => IsAutoIdle);
DATA.Subscribe("System.IsAutoRunning", () => IsRunning);//System.IsAutoRunning=>IsRunning绑定相同的值不同的地方用
DATA.Subscribe("System.Modules", () => _modules);
DATA.Subscribe("System.SignalTowerData", () => _mainSignalTower?.DeviceData);
DATA.Subscribe($"{ModuleName.System}.IsOnline", () => IsOnline);
DATA.Subscribe($"{ModuleName.System}.IsIdle", () => IsIdle || IsInit);
DATA.Subscribe($"{ModuleName.System}.IsAlarm", () => IsAlarm);
DATA.Subscribe($"{ModuleName.System}.IsBusy", () => IsRunning);//System.IsBusy=>IsRunning绑定相同的值不同的地方用
DATA.Subscribe($"{ModuleName.System}.IsAutoIdle", () => IsAutoIdle);
DATA.Subscribe($"{ModuleName.System}.IsAutoRunning", () => IsRunning);//System.IsAutoRunning=>IsRunning绑定相同的值不同的地方用
DATA.Subscribe($"{ModuleName.System}.Modules", () => _modules);
DATA.Subscribe($"{ModuleName.System}.SignalTowerData", () => _mainSignalTower?.DeviceData);
DATA.Subscribe($"{ModuleName.System}.IsLicValid", () => IsLicValid, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{ModuleName.System}.CurrentCDKey", () => CurrentCDKey, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{ModuleName.System}.CDKeyCreationDate", () => CDKeyCreationDate, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{ModuleName.System}.CDKeyDaysLeft", () => CDKeyDaysLeft, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{ModuleName.System}.MachineCode", () => MachineCode, SubscriptionAttribute.FLAG.IgnoreSaveDB);
}
void SubscribeOperation()
@ -612,6 +632,15 @@ namespace SicRT.Equipments.Systems
//{
// return CheckToPostMessage((int)MSG.StartJob, args[0]);
//});
OP.Subscribe("System.Activate", (string cmd, object[] args) =>
{
if (args.Length == 1 && args[0] is string cdKey)
return Activate(cdKey);
EV.PostAlarmLog("System", "The CD-KEY is incorrect.");
return false;
});
#region Recipe Editor Lock Password Management
@ -774,18 +803,45 @@ namespace SicRT.Equipments.Systems
return false;
}
private bool fMonitorlicense(object[] objs)
{
if (!MonitorLicense())
return false;
return true;
}
private bool fError(object[] objs)
{
IsOnline = false;
if (FsmState == (int)RtState.Transfer)
{
_manualTransfer.Clear();
}
// LicenseError优先级高保持此状态
if (FsmState == (int)RtState.LicenseError)
return false;
return true;
}
private bool fLicenseError(object[] args)
{
// PM工艺中不要跳到LicenseError状态
var keyPms = Modules.Keys.Where(x => x.ToString().StartsWith("PM")).ToList();
// 没找到PM或所有PM均没有在工艺中允许跳进LicenseError状态否则不要跳到LicenseError状态
return !keyPms.Any() || // 没找到PM返回true
keyPms.All(k => Modules[k] is not PMModule { IsProcessing: true }); // 没有做工艺的PM返回true
}
private bool fLicenseActivated(object[] args)
{
return true;
}
#endregion
@ -793,7 +849,10 @@ namespace SicRT.Equipments.Systems
private bool FsmMonitorAutoIdle(object[] param)
{
//fMonitorFAJob(param);
//fMonitorFAJob(param)
if (!MonitorLicense())
return false;
Result ret = _auto.Monitor();
@ -826,6 +885,9 @@ namespace SicRT.Equipments.Systems
private bool fAutoTransfer(object[] objs)
{
if(!MonitorLicense())
return false;
Result ret = _auto.Monitor();
if (_auto.CheckAllJobDone())
@ -943,9 +1005,14 @@ namespace SicRT.Equipments.Systems
{
EV.ClearAlarmEvent();
if (FsmState == (int)RtState.AutoRunning)
switch (FsmState)
{
_auto.ResetTask();
case (int)RtState.LicenseError:
return false; // NoLicense状态Reset后保持
case (int)RtState.AutoRunning:
_auto.ResetTask();
break;
}
Singleton<DeviceEntity>.Instance.PostMsg(DeviceEntity.MSG.RESET);
@ -1476,6 +1543,89 @@ namespace SicRT.Equipments.Systems
}
}
#endregion
#region License
public bool IsLicValid => FsmState != (int)RtState.LicenseError;
public string CurrentCDKey { get; private set; }
public DateTime CDKeyCreationDate { get; private set; }
public int CDKeyDaysLeft { get; private set; }
public string MachineCode
{
get;
private set;
}
private void GetMachineCode()
{
try
{
using var licGen = new MachineInfo();
MachineCode = licGen.MachineCode.ToString();
}
catch (Exception ex)
{
EV.PostAlarmLog("System", $"Unable to get machine code, {ex.Message}");
MachineCode = "NULL";
}
}
private bool MonitorLicense()
{
if (!LicManager.CheckInline(out var reason, out var cdKey, out var creationDate, out var daysLeft))
{
PostMsg(FSM_MSG.LICERR);
CurrentCDKey = "N/A";
CDKeyCreationDate = DateTime.MinValue;
CDKeyDaysLeft = -1;
return false;
}
CurrentCDKey = cdKey;
CDKeyCreationDate = creationDate;
CDKeyDaysLeft = daysLeft;
if (FsmState == (int)RtState.LicenseError)
PostMsg(MSG.Activated);
return true;
}
private bool Activate(string cdKey)
{
// check the CD-KEY
try
{
LicManager.Check(DateTime.Now, cdKey);
}
catch (Exception ex)
{
EV.PostAlarmLog("System", $"Activation failed, {ex.Message}");
return false;
}
// Save the CD-KEY
try
{
LicManager.Save(DateTime.Now, cdKey);
}
catch (Exception ex)
{
EV.PostAlarmLog("System", $"Save CD-KEY failed, {ex.Message}");
return false;
}
PostMsg(MSG.Activated);
return true;
}
#endregion
}
}

View File

@ -51,5 +51,5 @@ using System.Windows;
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 方法是按如下所示使用“*”: :
[assembly: AssemblyVersion("1.1.3.8")]
[assembly: AssemblyInformationalVersion("自动通用版有EFEM")]
[assembly: AssemblyVersion("1.1.5.9")]
[assembly: AssemblyInformationalVersion("Evaluation Edition")]

View File

@ -7,14 +7,20 @@
!include "MUI2.nsh"
;--------------------------------
; Password
!define Password "sic2023"
;PasswordBox ID
!define IDC_PASSWORD 1214
;--------------------------------
;General
!getdllversion "sicui\sicui.exe" ver
;Name and file
Name "Sic ${ver1}.${ver2}.${ver3}.${ver4}"
OutFile "Sic_自动通用有EFEM_Setup_v${ver1}.${ver2}.${ver3}.${ver4}.exe"
Name "Sic Evaluation Edition v${ver1}.${ver2}.${ver3}.${ver4}"
OutFile "Sic_EVE_Setup_v${ver1}.${ver2}.${ver3}.${ver4}.exe"
;Default installation folder
;InstallDir "$LOCALAPPDATA\Modern UI Test"
@ -32,8 +38,9 @@
!define MUI_ABORTWARNING
;--------------------------------
;Pages
;Pages@
Page Custom PasswordPageShow PasswordPageLeave
!insertmacro MUI_PAGE_LICENSE "License.txt"
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
@ -41,6 +48,8 @@
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
;--------------------------------
;Languages
@ -50,7 +59,7 @@
;--------------------------------
;Installer Sections
Section "All" SecAll
Section "Control Apps" SecControlApp
SetOutPath "$INSTDIR"
@ -67,20 +76,41 @@ Section "All" SecAll
;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
CreateShortCut "$DESKTOP\SicRTIPConfig.lnk" "$INSTDIR\SicUI\SicUI.exe" "--is-set-rt-ip" "$INSTDIR\SicUI\RtIpAddressSetting.ico" 0
;CreateShortCut "$DESKTOP\SicRTIPConfig.lnk" "$INSTDIR\SicUI\SicUI.exe" "--is-set-rt-ip" "$INSTDIR\SicUI\RtIpAddressSetting.ico" 0
CreateShortCut "$DESKTOP\SicUI.lnk" "$INSTDIR\SicUI\SicUI.exe"
SectionEnd
Section "Simulator" SecSim
SetOutPath "$INSTDIR"
;ADD YOUR OWN FILES HERE...
SetOutPath "$INSTDIR\SicSimulator"
File /r "SicSimulator\*"
;Store installation folder
WriteRegStr HKCU "Software\Sicentury\CVD" "" $INSTDIR
;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
CreateShortCut "$DESKTOP\SicSimulator.lnk" "$INSTDIR\SicSimulator\SicSimulator.exe"
SectionEnd
;--------------------------------
;Descriptions
;Language strings
LangString DESC_SecAll ${LANG_ENGLISH} "Install SicRT and SicUI."
LangString DESC_SecControlApp ${LANG_ENGLISH} "Install SicRT and SicUI."
LangString DESC_SecSim ${LANG_ENGLISH} "Install Simulator."
;Assign language strings to sections
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SecAll} $(DESC_SecAll)
!insertmacro MUI_DESCRIPTION_TEXT ${SecControlApp} $(DESC_SecControlApp)
!insertmacro MUI_DESCRIPTION_TEXT ${SecSim} $(DESC_SecSim)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
;--------------------------------
@ -93,10 +123,52 @@ Section "Uninstall"
Delete "$INSTDIR\Uninstall.exe"
Delete "$DESKTOP\SicRTIPConfig.lnk"
Delete "$DESKTOP\SicUI.lnk"
Delete "$DESKTOP\SicSimulator.lnk"
RMDir /r "$INSTDIR\SicUI"
RMDir /r "$INSTDIR\SicRT"
RMDir /r "$INSTDIR\SicSimulator"
DeleteRegKey /ifempty HKCU "Software\Sicentury\CVD"
SectionEnd
;--------------------------------
; Password Dialog Functions
## Displays the password dialog
Function PasswordPageShow
!insertmacro MUI_HEADER_TEXT "CAUTION!" "This is an EVALUATION version for testing or training purposes, DO NOT use it in a production environment!"
PassDialog::InitDialog Password /HEADINGTEXT "Enter a password to install"
Pop $R0 # Page HWND
# Use the following code to set a custom password character
;GetDlgItem $R1 $R0 ${IDC_PASSWORD}
;SendMessage $R1 ${EM_SETPASSWORDCHAR} 178 0
PassDialog::Show
FunctionEnd
## Validate password
Function PasswordPageLeave
## Pop password from stack
Pop $R0
## A bit of validation
StrCmp $R0 '${Password}' +3
MessageBox MB_OK|MB_ICONEXCLAMATION "The password is incorrect!"
Abort
FunctionEnd
Function ComponentsPageShow
## Disable the Back button
GetDlgItem $R0 $HWNDPARENT 3
EnableWindow $R0 0
FunctionEnd

View File

@ -579,23 +579,40 @@ xcopy /e "$(ProjectDir)..\..\SicRT\bin\Debug\*.*" "$(ProjectDir)..\Packages\SicR
echo 清理SicRT文件夹
del "$(ProjectDir)..\Packages\SicRT\*.pdb"
del "$(ProjectDir)..\Packages\SicRT\Config\*.data"
del "$(ProjectDir)..\Packages\SicRT\Config\*.bak"
if exist "$(ProjectDir)..\Packages\SicRT\Config\Account\_Account.xml" del "$(ProjectDir)..\Packages\SicRT\Config\Account\_Account.xml"
if exist "$(ProjectDir)..\Packages\SicRT\Objects" del "$(ProjectDir)..\Packages\SicRT\Objects\*.obj"
if exist "$(ProjectDir)..\Packages\SicRT\Logs" rd "$(ProjectDir)..\Packages\SicRT\Logs" /s /q
if exist "$(ProjectDir)..\Packages\SicRT\Recipes" rd "$(ProjectDir)..\Packages\SicRT\Recipes" /s /q</PreBuildEvent>
if exist "$(ProjectDir)..\Packages\SicRT\Recipes" rd "$(ProjectDir)..\Packages\SicRT\Recipes" /s /q
REM Copying SicSimulator .....
if exist "$(ProjectDir)..\Packages\SicSimulator" rd "$(ProjectDir)..\Packages\SicSimulator" /s /q
md "$(ProjectDir)..\Packages\SicSimulator\"
echo 拷贝SicSimulator文件"$(ProjectDir)..\..\SicSimulator\bin\Debug\"
xcopy /e "$(ProjectDir)..\..\SicSimulator\bin\Debug\*.*" "$(ProjectDir)..\Packages\SicSimulator\" /q
echo 清理SicSimulator文件夹
del "$(ProjectDir)..\Packages\SicSimulator\*.pdb"
del "$(ProjectDir)..\Packages\SicSimulator\*.rar"
del "$(ProjectDir)..\Packages\SicSimulator\*.zip"
del "$(ProjectDir)..\Packages\SicSimulator\*.bak"
if exist "$(ProjectDir)..\Packages\SicSimulator\Logs" rd "$(ProjectDir)..\Packages\SicSimulator\Logs" /s /q</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>echo 清理旧的打包文件。。。
if exist "$(ProjectDir)..\Packages\NSIS" rd "$(ProjectDir)..\Packages\NSIS" /s /q
del "$(ProjectDir)..\Packages\*.exe"
del "$(ProjectDir)..\Packages\SicRT\Config\*.data"
del "$(ProjectDir)..\Packages\SicRT\Config\*.bak"
echo 复制NSIS工程文件到输出目录。。。
copy "$(TargetDir)CVD.nsi" "$(ProjectDir)..\Packages\CVD.nsi" /y
copy "$(TargetDir)license.txt" "$(ProjectDir)..\Packages\license.txt" /y
xcopy "$(ProjectDir)NSIS\*.*" "$(ProjectDir)..\Packages\NSIS\" /E
xcopy "$(ProjectDir)NSIS\*.*" "$(ProjectDir)..\Packages\NSIS\" /E /q
echo 开始执行NSIS打包程序。。。
cd "$(ProjectDir)..\Packages\NSIS"

View File

@ -1,6 +1,11 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Controls;
using SicSimulator.Instances;
using MECF.Framework.UI.Core.Applications;
using MECF.Framework.UI.Client.Ctrlib.Controls;
using MECF.Framework.Common.Core.License;
using MECF.Framework.UI.Client.ClientBase;
namespace SicSimulator
{
@ -15,7 +20,93 @@ namespace SicSimulator
UiApplication.Instance.Initialize(new UiInstance());
SimulatorSystem.Instance.Initialize();
if(CheckLicense())
SimulatorSystem.Instance.Initialize();
}
private void Panel_ActivateClicked(object sender, RoutedEventArgs e)
{
if (sender is LicenseInputPanel licPanel)
{
if (string.IsNullOrEmpty(licPanel.CDKey))
ShowErrorMessageBox("The CD-KEY can not be empty.");
else if (!LicManager.ValidateCdKeyFormat(licPanel.CDKey))
ShowErrorMessageBox("The format of CD-KEY is error.");
else
{ // check the CD-KEY
try
{
LicManager.Check(DateTime.Now, licPanel.CDKey);
}
catch (Exception ex)
{
ShowErrorMessageBox($"Activate license failed, {ex.Message}");
return;
}
// Save the CD-KEY
try
{
LicManager.Save(DateTime.Now, licPanel.CDKey);
}
catch (Exception ex)
{
ShowErrorMessageBox($"Activate license failed, {ex.Message}");
return;
}
licPanel.Visibility = Visibility.Collapsed;
SimulatorSystem.Instance.Initialize();
}
}
else
{
ShowErrorMessageBox("Failed to load the license input panel.");
}
}
private bool CheckLicense()
{
var isLicValid = LicManager.CheckInline(out var reason, out _, out _, out _);
if (!isLicValid)
{
try
{
var mainWindow = Current?.MainWindow;
if (mainWindow != null)
{
var brdLic = mainWindow.FindName("LicInputPanel") as Border;
if (brdLic == null)
{
ShowErrorMessageBox("Unable to find container of license input panel.");
return false;
}
// show license input panel
var licGen = new MachineInfo();
var panel = new LicenseInputPanel();
panel.MachineCode = licGen.MachineCode.ToString();
panel.ActivateClicked += Panel_ActivateClicked;
brdLic.Child = panel;
Panel.SetZIndex(brdLic, 999);
brdLic.Visibility = Visibility.Visible;
brdLic.UpdateLayout();
}
}
catch (Exception ex)
{
ShowErrorMessageBox($"Unable to generate license input panel, {ex.Message}");
}
}
return isLicValid;
}
private void ShowErrorMessageBox(string message)
{
MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
protected override void OnExit(ExitEventArgs e)

View File

@ -372,6 +372,7 @@ namespace SicSimulator.Instances
{
LOG.Write(e);
}
return true;
}

View File

@ -0,0 +1,31 @@
using System;
using System.Drawing;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
using Brush = System.Windows.Media.Brush;
namespace SicUI.Converter
{
public class LicenseExpiredToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Brush foreground;
if (parameter is Brush brush)
foreground = brush;
else
foreground = new SolidColorBrush(Colors.White);
if (value is int and <= 3)
foreground = new SolidColorBrush(Colors.Red);
return foreground;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -13,10 +13,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converter="clr-namespace:SicUI.Converter"
Title="Sic Auto Edition"
Title="Sic Evaluation Edition for Training&amp;Demo Purpose Only"
WindowStartupLocation="CenterScreen"
WindowState="Maximized"
mc:Ignorable="d"
d:DesignHeight="1000"
d:DataContext="{d:DesignInstance Type=client:MainViewModel, IsDesignTimeCreatable=False}">
<Window.Resources>
<client:CollectionLastIndexConverter x:Key="collectionLastIndexConverter" />
@ -24,6 +25,7 @@
</Window.Resources>
<Grid Background="{DynamicResource MainArea_BG}">
<!--#region Login Window -->
<Grid x:Name="LoginPart" Panel.ZIndex="0" Background="{StaticResource Login_BG}">
<Grid.Style>
<Style>
@ -343,7 +345,9 @@
</Border>
</Grid>
</Grid>
<!--#endregion Login Window -->
<!--#region Main Container -->
<Border
Margin="3,1"
Padding="1"
@ -375,6 +379,8 @@
<RowDefinition Height="30" />
<RowDefinition Height="70" />
</Grid.RowDefinitions>
<!--#region Top Toolbar -->
<Grid x:Name="Top_Frame">
<Grid.RowDefinitions>
<RowDefinition Height="30*" />
@ -700,10 +706,24 @@
</Grid>
</Border>
</Grid>
<!--#endregion Top Toolbar -->
<!--#region License Input Panel -->
<controls:LicenseInputPanel Grid.Row="1" Grid.RowSpan="3"
d:MachineCode="12345"
MachineCode="{Binding MachineCode}"
CDKey="{Binding NewCdKey, Mode=OneWayToSource}"
ActivationMessage="{Binding ActivateMessage}"
cal:Message.Attach="[ActivateClicked] = [Action Activate()]"
Visibility="{Binding IsLicenseValid, Converter={StaticResource BoolVisibilityConverter}, ConverterParameter=True}"/>
<!--#endregion License Input Panel -->
<!--#region Body -->
<Grid Grid.Row="1"
x:Name="GdContentContainer"
Background="{DynamicResource MainArea_BG}"
IsHitTestVisible="{Binding IsReadOnlyMode, Converter={StaticResource BoolReverseConverter}}"
Visibility="{Binding IsLicenseValid, Converter={StaticResource BoolVisibilityConverter}}"
PreviewKeyDown="GdContentContainer_OnPreviewKeyDown">
<ContentControl
x:Name="ActiveItem"
@ -711,9 +731,13 @@
cal:View.Context="{Binding Context}"
cal:View.Model="{Binding ActiveItem}" />
</Grid>
<!--#endregion Body -->
<!--#region Sub Menu -->
<Border
x:Name="Sub_Menu_Bar"
Grid.Row="2"
Visibility="{Binding IsLicenseValid, Converter={StaticResource BoolVisibilityConverter}}"
Style="{DynamicResource Sub_Menu_BarStyle}">
<Menu
Grid.Row="0"
@ -728,14 +752,19 @@
</Menu.ItemTemplate>
</Menu>
</Border>
<!--#endregion Sub Menu -->
<!--#region Main Menu -->
<Border
x:Name="Bottom_Frame"
Grid.Row="3"
Visibility="{Binding IsLicenseValid, Converter={StaticResource BoolVisibilityConverter}}"
Style="{DynamicResource Bottom_FrameStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!--<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="LOGO" VerticalAlignment="Center" FontFamily="Arial" Foreground="White" FontSize="50" FontWeight="Bold" Margin="9,10,1743,2" FontStyle="Italic" RenderTransformOrigin="-5.298,-0.284"/>-->
<!--<Image Source="/SicUI;component/Themes/images/parts/logo1.png" Margin="10,0,0,0"></Image>-->
@ -754,11 +783,71 @@
</DataTemplate>
</Menu.ItemTemplate>
</Menu>
<Border Grid.Column="2" Background="#8800FF80" Opacity="1" >
<Grid Margin="10 2 5 2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<converter:LicenseExpiredToColorConverter x:Key="ExpiredToColorConverter"/>
<Style x:Key="TextBlockBaseStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource FG_White}"/>
<Setter Property="FontSize" Value="11"/>
</Style>
<Style x:Key="TitleStyle" TargetType="TextBlock" BasedOn="{StaticResource TextBlockBaseStyle}">
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style x:Key="CaptionStyle" TargetType="TextBlock" BasedOn="{StaticResource TextBlockBaseStyle}">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style x:Key="ContentStyle" TargetType="TextBlock" BasedOn="{StaticResource TextBlockBaseStyle}">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Grid.Resources>
<TextBlock Grid.ColumnSpan="2"
Text="* Evaluation Edition"
Style="{StaticResource TitleStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="CD-KEY" Style="{StaticResource CaptionStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="1" d:Text="MWVNZ-5FLAR-Z2BGZ-H5WTF"
Text="{Binding CurrentCDKey}"
Style="{StaticResource ContentStyle}"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="From" Style="{StaticResource CaptionStyle}"/>
<TextBlock Grid.Row="2" Grid.Column="1" d:Text="2023/03/10"
Text="{Binding CDKeyCreationDate, StringFormat=d}"
Style="{StaticResource ContentStyle}"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Expired" Style="{StaticResource CaptionStyle}"/>
<TextBlock Grid.Row="3" Grid.Column="1" d:Text="1 Days"
Text="{Binding CDKeyDaysLeft, StringFormat={}{0} Days}"
Foreground="{Binding CDKeyDaysLeft,
Converter={StaticResource ExpiredToColorConverter},
ConverterParameter={StaticResource FG_White}}"
Style="{StaticResource ContentStyle}"/>
</Grid>
</Border>
</Grid>
</Border>
<!--#endregion Main Menu -->
</Grid>
</Border>
<!--#endregion Main Container -->
</Grid>
</wnd:CustomWnd>

View File

@ -10,18 +10,10 @@ using MECF.Framework.UI.Core.Accounts;
using OpenSEMI.ClientBase;
using OpenSEMI.ClientBase.Command;
using OpenSEMI.ClientBase.Utility;
using SciChart.Charting.ChartModifiers;
using SciChart.Charting.Visuals;
using SciChart.Charting.Visuals.Annotations;
using SciChart.Charting.Visuals.Axes;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
@ -34,10 +26,10 @@ using Cali = Caliburn.Micro.Core;
using System.Diagnostics;
using Caliburn.Micro.Core;
using MECF.Framework.UI.Client.Ctrlib.Controls;
using System.Net;
using MECF.Framework.UI.Client.Core;
using MECF.Framework.UI.Client.ClientBase.Dialog;
using MECF.Framework.Common.Account.Permissions;
using MECF.Framework.Common.Core.License;
using MECF.Framework.Common.MECF.Framework.Common.SCCore;
namespace SicUI.Client
@ -836,7 +828,7 @@ namespace SicUI.Client
protected override void OnInitialize()
{
//display system version or other info...
this.DisplayName = "Sic Auto-GE";
this.DisplayName = "Sic Evaluation Edition for Training&Demo Purpose Only";
base.OnInitialize();
this.StartTimer();
@ -1056,54 +1048,54 @@ namespace SicUI.Client
switch (retKeepAlive.State)
{
case CredentialKeepAliveStates.Alive or CredentialKeepAliveStates.NotFound:
{
if (_ctsLoginRequestConfirmDialog is { IsCancellationRequested: false })
_ctsLoginRequestConfirmDialog.Cancel();
if (retKeepAlive.State == CredentialKeepAliveStates.NotFound)
{
if (_ctsLoginRequestConfirmDialog is { IsCancellationRequested: false })
_ctsLoginRequestConfirmDialog.Cancel();
if (retKeepAlive.State == CredentialKeepAliveStates.NotFound)
{
Logoff();
Execute.OnUIThread(() => { DialogBox.ShowError("You are kicked by RT."); });
}
break;
Logoff();
Execute.OnUIThread(() => { DialogBox.ShowError("You are kicked by RT."); });
}
break;
}
case CredentialKeepAliveStates.RequestingLogin:
{
// 当前用户在其它地方请求登录
if (_ctsLoginRequestConfirmDialog == null ||
_ctsLoginRequestConfirmDialog.IsCancellationRequested)
{
// 当前用户在其它地方请求登录
if (_ctsLoginRequestConfirmDialog == null ||
_ctsLoginRequestConfirmDialog.IsCancellationRequested)
{
_ctsLoginRequestConfirmDialog = new CancellationTokenSource();
_prgShowLoginRequestConfirmDialog.Report(retKeepAlive.RequestingCredential);
}
/* Execute.OnUIThread(() =>
{
var dlgConfirm = new LoginRequestConfirmationDialog(retKeepAlive.RequestingCredential);
var retDlg = dlgConfirm.ShowDialog();
if (retDlg == true)
{
AccountClient.Instance.Service.ConfirmLoginRequest(retKeepAlive.RequestingCredential.AccountInfo.LoginName);
Logoff();
// 降级为仅查看模式
IsReadOnlyMode = true;
BaseApp.Instance.UserContext.Role = role;
BaseApp.Instance.UserContext.Credential = Credential.ReadOnlyOne;
}
else
{
AccountClient.Instance.Service.RejectLoginRequest(retKeepAlive.RequestingCredential.AccountInfo.LoginName);
}
});*/
// 等待RT处理凭据否则有可能反复触发请求登录确认窗口.
Thread.Sleep(1000);
break;
_ctsLoginRequestConfirmDialog = new CancellationTokenSource();
_prgShowLoginRequestConfirmDialog.Report(retKeepAlive.RequestingCredential);
}
/* Execute.OnUIThread(() =>
{
var dlgConfirm = new LoginRequestConfirmationDialog(retKeepAlive.RequestingCredential);
var retDlg = dlgConfirm.ShowDialog();
if (retDlg == true)
{
AccountClient.Instance.Service.ConfirmLoginRequest(retKeepAlive.RequestingCredential.AccountInfo.LoginName);
Logoff();
// 降级为仅查看模式
IsReadOnlyMode = true;
BaseApp.Instance.UserContext.Role = role;
BaseApp.Instance.UserContext.Credential = Credential.ReadOnlyOne;
}
else
{
AccountClient.Instance.Service.RejectLoginRequest(retKeepAlive.RequestingCredential.AccountInfo.LoginName);
}
});*/
// 等待RT处理凭据否则有可能反复触发请求登录确认窗口.
Thread.Sleep(1000);
break;
}
}
}
}
@ -1137,5 +1129,41 @@ namespace SicUI.Client
#endregion
#endregion
#region License
[Subscription($"System.IsLicValid")]
public bool IsLicenseValid { get; set; }
[Subscription($"System.MachineCode")]
public string MachineCode { get; set; }
[Subscription($"System.CurrentCDKey")]
public string CurrentCDKey { get; set; }
[Subscription($"System.CDKeyCreationDate")]
public string CDKeyCreationDate { get; set; }
[Subscription($"System.CDKeyDaysLeft")]
public int CDKeyDaysLeft { get; set; }
public string ActivateMessage { get; private set; }
public string NewCdKey { get; set; }
public void Activate()
{
ActivateMessage = "";
if (string.IsNullOrEmpty(NewCdKey))
ActivateMessage = "The CD-KEY can not be empty.";
else if(!LicManager.ValidateCdKeyFormat(NewCdKey))
ActivateMessage = "The format of CD-KEY is error.";
else
InvokeClient.Instance.Service.DoOperation("System.Activate", NewCdKey);
}
#endregion
}
}

View File

@ -594,6 +594,8 @@ namespace SicUI.Models.Operations.Overviews
#region Scheduler
public bool IsLicenseError => RtStatus == "LicenseError";
public bool IsRtInitialized
{
get
@ -699,6 +701,9 @@ namespace SicUI.Models.Operations.Overviews
{
get
{
if(IsLicenseError)
return false;
if (IsAuto)
return !string.IsNullOrEmpty(CassALJobStatus) || !string.IsNullOrEmpty(CassARJobStatus);
@ -708,23 +713,49 @@ namespace SicUI.Models.Operations.Overviews
public bool IsEnableAuto
{
get { return !IsAuto && IsRtInitialized; }
get
{
if (IsLicenseError)
return false;
return !IsAuto && IsRtInitialized;
}
}
public bool IsEnableManual
{
get { return IsAuto && IsRtInitialized && string.IsNullOrEmpty(CassALJobStatus) && string.IsNullOrEmpty(CassARJobStatus); }
get
{
if (IsLicenseError)
return false;
return IsAuto && IsRtInitialized && string.IsNullOrEmpty(CassALJobStatus) &&
string.IsNullOrEmpty(CassARJobStatus);
}
}
public bool IsEnableInitialize
{
get { return !IsAuto && !IsRtRunning; }
get
{
if (IsLicenseError)
return true;
return !IsAuto && !IsRtRunning;
}
}
public bool IsEnableReturnAll
{
get { return !IsAuto && IsRtInitialized && RtStatus == "Idle"; }
get
{
if (IsLicenseError)
return false;
return !IsAuto && IsRtInitialized && RtStatus == "Idle";
}
}
#endregion

View File

@ -54,5 +54,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.1.5.0")]
[assembly: AssemblyInformationalVersion("自动通用版有EFEM")]
[assembly: AssemblyVersion("1.1.5.9")]
[assembly: AssemblyInformationalVersion("Evaluation Edition")]

View File

@ -246,6 +246,7 @@ if exist "$(ProjectDir)..\SicSetup\Packages\SicUI\PresetGroups" rd "$(ProjectDir
<Compile Include="Controls\WaferAssociationUnitLite.xaml.cs">
<DependentUpon>WaferAssociationUnitLite.xaml</DependentUpon>
</Compile>
<Compile Include="Converter\LicenseExpiredToColorConverter.cs" />
<Compile Include="GlobalUsings.cs" />
<Compile Include="Models\Maintenances\RuntimeView.xaml.cs">
<DependentUpon>RuntimeView.xaml</DependentUpon>

View File

@ -1,5 +1,4 @@
using Aitex.Core.Util;
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
@ -7,29 +6,15 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using Aitex.Core.RT.Log;
using Cali = Caliburn.Micro.Core;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.Equipment;
namespace SicUI
{
public class TimeredMainViewModel : Cali.Conductor<Cali.Screen>.Collection.OneActive
{
PeriodicJob _timer;
ConcurrentBag<string> _subscribedKeys = new ConcurrentBag<string>();
Func<object, bool> _isSubscriptionAttribute;
Func<MemberInfo, bool> _hasSubscriptionAttribute;
public TimeredMainViewModel()
{
_timer = new PeriodicJob(1000, this.OnTimer, "UIUpdaterThread - " + GetType().Name);
_isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
_hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
SubscribeKeys(this);
}
#region Variables
[StructLayout(LayoutKind.Sequential)]
internal struct LASTINPUTINFO
@ -42,6 +27,32 @@ namespace SicUI
[DllImport("user32.dll")]
internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
private readonly PeriodicJob _timer;
private readonly ConcurrentBag<string> _subscribedKeys = new();
private readonly Func<object, bool> _isSubscriptionAttribute;
private readonly Func<MemberInfo, bool> _hasSubscriptionAttribute;
private readonly R_TRIG _rTrigLicPollFailed = new();
#endregion
#region Constructors
public TimeredMainViewModel()
{
_timer = new PeriodicJob(1000, this.OnTimer, "UIUpdaterThread - " + GetType().Name);
_isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
_hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
SubscribeKeys(this);
}
#endregion
#region Methods
/// <summary>
/// 获取鼠标键盘不活动的时间
/// </summary>
@ -61,106 +72,12 @@ namespace SicUI
return ((idleTime > 0) ? (idleTime / 1000) : 0);
}
protected virtual bool OnTimer()
{
try
{
Poll();
}
catch (Exception ex)
{
LOG.Error(ex.Message);
}
return true;
}
public virtual void EnableTimer(bool enable)
{
if (enable) _timer.Start();
else _timer.Pause();
}
protected virtual void Poll()
{
if (_subscribedKeys.Count > 0)
{
Dictionary<string, object> result = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
if (result == null)
{
LOG.Error("获取RT数据失败");
return;
}
if (result.Count != _subscribedKeys.Count)
{
string unknowKeys = string.Empty;
foreach (string key in _subscribedKeys)
{
if (!result.ContainsKey(key))
{
unknowKeys += key + "\r\n";
}
}
//System.Diagnostics.Debug.Assert(false, unknowKeys);
}
InvokeBeforeUpdateProperty(result);
UpdateValue(result);
Application.Current.Dispatcher.Invoke(new System.Action(() =>
{
InvokePropertyChanged();
InvokeAfterUpdateProperty(result);
}));
}
}
private void InvokePropertyChanged()
{
Refresh();
}
protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
{
}
protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
{
}
void UpdateValue(Dictionary<string, object> data)
{
if (data == null)
return;
UpdateSubscribe(data, this);
var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<SubscriptionModuleAttribute>() != null);
foreach (var property in properties)
{
var moduleAttr = property.GetCustomAttribute<SubscriptionModuleAttribute>();
UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module);
}
}
protected void Subscribe(string key)
{
if (!string.IsNullOrEmpty(key))
{
_subscribedKeys.Add(key);
}
}
public void SubscribeKeys(TimeredMainViewModel target)
{
Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
@ -239,5 +156,115 @@ namespace SicUI
});
}
protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
{
}
protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
{
}
protected void Subscribe(string key)
{
if (!string.IsNullOrEmpty(key))
{
_subscribedKeys.Add(key);
}
}
protected virtual bool OnTimer()
{
try
{
Poll();
}
catch (Exception ex)
{
LOG.Error(ex.Message);
}
return true;
}
protected virtual void Poll()
{
if (_subscribedKeys.Count > 0)
{
Dictionary<string, object> result = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
if (result == null)
{
LOG.Error("获取RT数据失败");
return;
}
if (result.Count != _subscribedKeys.Count)
{
string unknowKeys = string.Empty;
foreach (string key in _subscribedKeys)
{
if (!result.ContainsKey(key))
{
unknowKeys += key + "\r\n";
}
}
//System.Diagnostics.Debug.Assert(false, unknowKeys);
}
InvokeBeforeUpdateProperty(result);
UpdateValue(result);
Application.Current.Dispatcher.Invoke(new Action(() =>
{
InvokePropertyChanged();
InvokeAfterUpdateProperty(result);
}));
}
}
/*protected bool CheckLic()
{
var isLicValid = false;
var licKey = $"{ModuleName.System}.LicValid";
var dic = QueryDataClient.Instance.Service.PollData(new []{ licKey });
_rTrigLicPollFailed.CLK = dic == null || !dic.TryGetValue(licKey, out var ret) ||
!bool.TryParse(ret.ToString(), out isLicValid);
if (_rTrigLicPollFailed.Q)
{
LOG.Error("It's failed to poll license info from RT.");
return false;
}
return isLicValid;
}*/
private void UpdateValue(Dictionary<string, object> data)
{
if (data == null)
return;
UpdateSubscribe(data, this);
var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<SubscriptionModuleAttribute>() != null);
foreach (var property in properties)
{
var moduleAttr = property.GetCustomAttribute<SubscriptionModuleAttribute>();
UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module);
}
}
private void InvokePropertyChanged()
{
Refresh();
}
#endregion
}
}

Binary file not shown.