[开源]FreeSCADA的研究
1.開源項目概述
a) 官網:http://www.free-scada.org/
b) 項目目的:設計一個組態軟件,功能為SCADA系統,最終目標為MES系統。
c) 項目技術點:The main programming language for the project is C# and .Net 3.0 platform. At this moment there are several parts of .Net used:
WinForms (GUI controls and window management), WPF and XAML (schema editing capabilities) and OPC (communication with 3rd party devices).
There are also plans to try a few more things:
ADO.NET, WCF, LINQ, Silverlight 2.0 and OPC UA.
d) 項目狀態:目前已經停止更新,最后一個版本為FreeSCADA 2.0.0.3。
2. 項目源碼解析
a) 項目工程整體結構圖如下:
There are two main modules for interacting with users: Designer and Run Time.
Designer - a tool used for creation of documents:
1) Definition of links with data sources
2) Setting up rules for archiving
3) Declaring alarms and expected user reaction for them
4) Creation of visual schemes and report templates
5) Setting up scheduler of report generation
Run Time - a tool used to regular work with the document:
1) Archiving data in real time
2) Alarm generation
3) Data visualization
4) Report generation
5) Sending visual data (schemes) to remote clients by using HTTP protocol for Web access as Silverlight 2.0 application
6) Sending data to remote clients by OPC XMLDA protocol
There is also a set of communication plugins which provide abstract communication layer with other applications (e.g. OPC, MODBUS).
b) 項目C#工程結構如下:
一共20個工程,其中Designer為啟動工程(主UI)。
3. 工程源碼詳細分析
1) Archiver(對應主UI->Project->Database settings界面)
特殊引用:
1) Common
普通類文件:
1)Archiver.cs:定義了公共類ArchiverMain。該類主要完成通道(ChannelsSettings)和數據庫設定(databaseSettings),數據庫讀(DbReader)和寫(DbWriter),通道更新線程開始/停止(Thread channelUpdaterThread)。
2)ChannelInfo.cs:定義了公共類ChannelInfo。該類主要完成通道屬性的定義,以及兩個基類函數的復寫(Equals(object obj)和GetHashCode())。
3)ChannelsSettings.cs:定義了公共類ChannelsSettings。該類主要完成List<ChannelInfo>和List<Rule>的聲明,和規則(Rule)的增加和清除,以及相關配置的XML方式存儲和載入。
4)Conditions.cs:定義了抽象類BaseCondition和繼承類TimeIntervalCondition。BaseCondition類中的函數全部為虛擬函數,子類可以選擇性繼承。其中虛擬函數Process()用于觸發一次計時檢驗,在固定時間間隔后通過IsValid變量來呈現結果。
[Serializable]關鍵字:串行化是指存儲和獲取磁盤文件、內存或其他地方中的對象。在串行化時,所有的實例數據都保存到存儲介質上,在取消串行化時,對象會被還原,且不能與其原實例區別開來。
[XmlInclude(typeof(TimeIntervalCondition))]關鍵字:在Web Services方法中,往往使用的都是一個具體類型的參數,這個參數一般就是一個數據對象。ASP.NET Web Services通過聲明XmlIncludeAttribute可以實現Web Services方法中運用多態。
XmlIncludeAttribute允許XmlSerializer在序列化或反序列化對象時識別類型。當應用XmlIncludeAttribute時,需指定派生類的Type。XmlSerializer序列化同時包含基類和派生類的對象之后,它就可以識別兩種對象類型。(詳細參見:http://www.cnblogs.com/zhaozhan/archive/2010/10/25/1860867.html)
[Browsable(false)]關鍵字:使用值 false的BrowsableAttribute構造函數標記的成員不適合在設計時進行編輯,因此,它們不會在可視化編輯器中顯示。默認為 true。
[XmlIgnore]關鍵字:XmlIgnoreAttribute 指示XmlSerializer方法不序列化公共字段或公共讀/寫屬性值。
5)DatabaseFactory.cs:定義了公共靜態類DatabaseFactory。其中枚舉變量ProcessorType用來定義三種CPU架構(x86, x64, IPF)。GetProcessorArch()用來獲取機器CPU的架構;DataTableGetAvailableDB()用來返回一個含有一條SQLite數據庫連接信息的DataTable;DbProviderFactory Get(string invariantName)用來根據參數返回一個DbProviderFactory(DbProviderFactory用來達到實現多數據庫訪問的文章)。
其中DbProviderFactory的定義常放在app.config中,形如:
<system.data>
<DbProviderFactories>
<add name="OracleClientFactory" invariant="OracleClientFactory" description="Oracle.ManagedDataAccess.Client.OracleClientFactory"
type="Oracle.ManagedDataAccess.Client.OracleClientFactory,Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
其中要注意的,是 invariant 和 type 屬性。
invariant: 可以通過這個屬性值獲取到對應DbProviderFactory類型,如DbProviderFactories.GetFactory("OracleClientFactory") ;
type:類名(含命名空間),程序集名稱,程序集信息。
6)DatabaseSettings.cs:定義了可序列化的公共類DatabaseSettings。主要完成數據庫的設置(DbProvider,DbFile, DbSource, DbCatalog, DbUser, DbPassword, DbConnectionString);Load()完成讀入settings/archiver/database.cfg的數據流,并XML反序列化為DatabaseSettings對象;Save()完成XML序列化DatabaseSettings為數據流并存入到settings/archiver/database.cfg;CreateConnectionString()根據DbConnectionString的內容創建數據庫連接的字符串。
7)DbReader.cs:定義了私有類DbReader。主要完成數據庫讀取相關的操作,兩個主要成員變量為DbProviderFactory和DbConnection類型。Open()完成數據庫的開啟;Close()完成數據庫的關閉和相關資源的釋放;DataTable ExecCommand(string selectCommand)完成相關數據庫讀取操作并返回相關數據表。
8)DbWriter.cs:定義了私有類DbWriter。主要完成數據庫讀取相關的操作,兩個主要成員變量為DbProviderFactory和DbConnection類型。Open()完成數據庫的開啟;Close()完成數據庫的關閉和相關資源的釋放;bool WriteChannels(List<ChannelInfo> channels)完成相關數據庫寫入操作(寫入的數據為SCADA各記錄通道的數據)。
9)PropertyCommand.cs:定義了私有類PropertyCommand(繼承自Common工程下的BaseCommand抽象類,BaseCommand類實現了ICommand接口,而ICommand接口又使用了ICommandItems接口)。重寫的Execute()方法用于新建并顯示UI類實例DatabaseSettingsForm。
10)Rule.cs:定義了可序列化的公共類Rule。主要成員變量為List<ChannelInfo>和List<BaseCondition>。AddChannel(ChannelInfo channel)完成ChannelInfo對象的添加;AddCondition(BaseCondition condition)完成BaseCondition對象的添加。
11)Storage.cs:空白類。
UI類:
1)DatabaseSettingsForm.cs:
特殊文件:
1)StringConstants.resx:用于存儲字符串鍵值對比如(TimeIntervalConditionName<->Time interval condition,調用的話形如StringConstants.TimeIntervalConditionName)
2)Archiver.Tests(工程Archiver的測試工程)
特殊引用:
1) Archiver
2) Common
3) Communication.SimulatorPlug
4) nunit.framework(NUnit測試框架插件):
[TestFixture]關鍵字:本屬性標記一個類包含測試。
[SetUp]關鍵字:定義測試函數初始化函數,每個測試函數運行前都會被調用一次。
[TearDown]關鍵字:定義測試函數銷毀函數,每個測試函數執行完后都會被調用一次。
[Test]關鍵字:Test屬性用來標記一個類(已經標記為TestFixture)的某個方法是可以測試的。
5) NUnitForms(NUnit測試框架插件)
6) SourceGrid(SourceGrid4_11數據顯示的表格控件)
普通類文件:
1)ChannelsSettingsTest.cs:測試Archiver工程下的ChannelsSettings類。[Test]GetChannelList()用于測試創建數據通道操作的正確性(注意ArchiverMain.Current返回的是靜態變量static ArchiverMain instance;);[Test]SaveLoadRules()用于測試存儲/載入規則的正確性。非測試類方法CreateFewChannels()方法用于創建幾個測試數據通道;CreateRandomChannels()方法是CreateFewChannels()方法中ExpectModal方法的參數。
2)DatabaseSettingsTest.cs:測試Archiver工程下的DatabaseSettings類。[Test]SaveLoad()用于測試導出數據庫配置到settings/archiver/database.cfg和從settings/archiver/database.cfg導入數據庫配置的過程的數據一致性。
3)DbFactoryTest.cs:測試Archiver工程下的DatabaseFactory類。[Test]ProvidersList用于測試靜態類DatabaseFactory可用的數據庫種類;[Test]CreateProvider用于測試根據靜態類DatabaseFactory可用的數據庫種類來創建DbProviderFactory是否正常。
4)Helpers.cs:定義了GridTester類(繼承自NUnit測試框架下的ControlTester類)。SetChannelType(int channelNo, string type)用于設置成員變量SourceGrid.Grid Control去更新對應表格部分的內容;SetChannelName(int channelNo, string name)用于設置成員變量SourceGrid.Grid Control去更新對應表格部分的內容。
UI類:無
3) CLServer(Command Line Server)
特殊引用:
1) Common
2) Plossum CommandLine(???)
普通類文件:
1)ChannelEventHandler.cs:定義了私有類ChannelEventHandler。主要成員變量IDataUpdatedCallback(接口)和IChannel(接口),以及一個EventHandler。構造函數ChannelEventHandler(IChannel channel, IDataUpdatedCallback callback, IContextChannel contextChannel)實現成員變量的賦值以及成員變量事件的綁定;OnContextChannelClosing(object sender, EventArgs e)實現通道關閉時的事件響應;OnChannelValueChanged(object sender, EventArgs e)實現通道數值更改時的事件響應。
2)ChannelInfo.cs:定義了公共類ChannelInfo。
[DataContract]服務契約定義了遠程訪問對象和可供調用的方法,數據契約則是服務端和客戶端之間要傳送的自定義數據類型,一旦聲明一個類型為DataContract,那么該類型就可以被序列化在服務端和客戶端之間傳送。
[DataMember]經常看到某些類的屬性上面標示[Serializable]或者[DataContract]序列化時,用到,一般都是用[Serializable]wcf中如果你的model類需要client和server之間傳遞,用[DataContract]屬性上面加[DataMember]也是WCF中用到的,[DataContract]在類的頂部寫上,[DataMember]在公共的屬性頂部寫上。
3)ChannelState.cs:定義了枚舉變量ChannelStatusFlags和公共類ChannelState。
4)IChannelInformationRetriever.cs:定義了私有接口IChannelInformationRetriever。
[ServiceContract]和[OperationContract]:接口前面加了[ServiceContract],意思是是把這個接口(把擴繼承這個接口的類)聲明為服務契約,服務契約是對客戶端而言的,就是這個接口暴露在客戶端面前。但看得見接口不代表可以看得見接口里的方法,所以想把方法也聲明為對客戶端可見,得在聲明方法的簽名加[OperationContract]。
5)IDataRetriever.cs:定義了私有接口IDataRetriever。
[ServiceContract(CallbackContract = typeof(IDataUpdatedCallback), SessionMode = SessionMode.Required)]:SerivceContract特性的成員列表
參數 說明
CallbackContract 當契約是雙工時,讀取或設置回調契約的類型
ConfigurationName 獲取或設置服務在應用程序配置文件中的名稱
HasProtectionLevel 讀取一個值,表示此成員是否有一個保護級別
Name 獲取或設置WSDL文檔中<portType>元素的名稱
Namespace 獲取或設置WSDL文檔中<portType>元素的名稱空間
ProtectionLevel 設置對契約的綁定是否支持ProtectionLevel屬性的值
SessionMode 獲取或設置會話是否允許,以及是否得到了請求
[OperationContract(IsOneWay = true)]:“單向操作”客戶端一旦發出請求,WCF會生成一個請求,不會給客戶端返回任何消息。“單向操作”不同于異步操作,雖然“單向操作”只是在發出調用的瞬間阻塞客戶端,但如果發出多個單向調用,WCF會將請求調用放入隊列,并在某個時候執行。隊列存儲調用的個數是有限的,一旦發出的調用個數超出了隊列存儲調用的設置值,則會發生阻塞現象,因為調用無法放入隊列。當隊列的請求出列后,產生阻塞的調用就會放入隊列,并解除對客戶端的阻塞。所有的WCF綁定通信協議都支持“單向操作”。配置“單向操作”的方式也很簡單,WCF的OperationContract 定義了IsOneWay屬性,IsOneWay默認是false(因為默認是請求-應答模式,不是單向操作模式),我們在方法契約中指定IsOneWay屬性為true就可以了。
6)IDataUpdatedCallback.cs:定義了私有接口IDataUpdatedCallback。
7)Options.cs:定義了私有類Options。
[CommandLineManager]開源插件Plossum CommandLine提供的特性。
[CommandLineOptionGroup]開源插件Plossum CommandLine提供的特性。
8)Program.cs:定義了私有類Program。
9)Service.cs:定義了私有類Service(實現了IChannelInformationRetriever接口,IDataRetriever接口)。主要成員變量有List<ChannelEventHandler>和ChannelInfo[]。GetChannels()返回當前通訊服務插件并返回所有的數據采集通道信息列表;GetChannelsCount()返回所有數據采集通道列表的長度;GetChannel(long index)返回特定數據采集通道的信息;RegisterCallback(string channelId)注冊相關數據采集通道的回調事件;OnHandlerDisconnected(object sender, EventArgs e)定義回調事件;SetChannelValue(string channelId, string value)設置對應數據采集通道的相關值;GetChannelState(string channelId)返回相關數據采集通道的狀態。
UI類:無
4) CLServer.ClientProxies
特殊引用:無
普通類文件:
1)Service.cs:
UI類:無
5) CLServer.Tests(工程CLServer的測試工程)
特殊引用:
1) CLServer.ClientProxies:
2) nunit.framework:
普通類文件:
1)ChannelInformationRetrieverTest.cs:
2)DataRetrieverTest.cs:
3)ServerStarter.cs:
UI類:無
6) Common
特殊引用:
1) ICsharpCode.SharpZipLib(SharpZipLib插件。一個免費的Zip操作類庫,可以利用它對 ZIP 等多種格式進行壓縮與解壓。http://icsharpcode.github.io/SharpZipLib)
2) IronPython(IronPython插件。IronPython is an implementation of the Python programming language for Microsoft .NET and Mono.。http://ironpython.codeplex.com)
3) IronPython.Modules(IronPython)
4) Microsoft.Scripting(IronPython)
5) Mircosoft.Scripting.Core(IronPython)
6) WindowsBase(.NET framework 3.0特性。WPF,或者是FORMS或web編程中調用了WPF,都必須要增加這該空間的引用)
普通類文件:
1)BaseChannel.cs:
2)BaseCommand.cs:
3)BaseCommandContext.cs:
4)BaseDropDownCommand.cs:
5)Commands.cs:
6)CommunationPlugs.cs:
7)ConfigurationManager.cs:
8)Env.cs:
9)IChannel.cs:
10)ICommand.cs:
11)ICommandContext.cs:
12)ICommandItems.cs:
13)ICommands.cs:
14)ICommunicationPlug.cs:
15)IEnvironment.cs:
16)IVisualControlDescriptor.cs:
17)IVisualControlsPlug.cs:
18)Logger.cs:
19)MRUManager.cs:
20)NullCommand.cs:
21)Project.cs:
22)VisualControlsPlugs.cs:
UI類:無
特殊文件:
1) Common.snk:密鑰和簽名文件
2) ReadOnlyPropertyGrid.cs:
3) StringReources.resx:
7) Common.Tests(工程Common的測試工程)
特殊引用:
1) Common
2) nunit.framework
普通類文件:
1)CommandMock.cs:
2)CommandsTest.cs:
3)CommunationPlugsTest.cs:
4)ConfigurationManagerTest.cs:
5)ProjectTest.cs:
UI類:無
8) CommonGUI
特殊引用:
1) Archiver
2) Common
3) DynamicDataDisplay(DynamicDataDisplay控件是一個功能很強的繪圖工具,除了能生成曲線外,還有很多其他功能,具體見http://dynamicdatadisplay.codeplex.com)
4) IronPython
5) IronPython.Modules
6) Microsoft.Scripting
7) Mircosoft.Scripting.Core
8) PresentationFramework(.NET framework 3.0特性)
9) PresentationCore(.NET framework 3.0特性)
10) WindowsBase
11) WindowsFormsIntegration(.NET framework 3.0特性。用于WPF引入WindowsForms)
12) WPFToolkit(wpftoolkit插件。http://wpf.codeplex.com)
普通類文件:
1)AnimatedImage.cs:
2)BaseManipulator.cs:
3)BaseTool.cs:
4)ChannelDataProvider.cs:
5)ChannelDataSource.cs:
6)MediaProvider.cs:
7)PerfTimer.cs:
8)QuadTree.cs:
9)SchemaDocument.cs:
10)SolidBrushConverter.cs:
11)TimeChartControl.cs:
12)VirtualCanvas.cs:
13)VirtualElement.cs:
14)WPFShemaContainer.cs:
UI類:無
9) Communication.CLServer
特殊引用:
1) CLServer.ClientProxies
2) Common
3) DevAge.Core(SourceGrid4_11數據顯示的表格控件)
4) DevAge.Windows.Forms(SourceGrid4_11數據顯示的表格控件)
5) SourceGrid
普通類文件:
1)ChannelConnection.cs:
2)ChannelFactory.cs:
3)ConnectionGroup.cs:
4)Plugin.cs:
5)PropertyCommand.cs:
6)RemoutingChannel.cs:
7)StringConstants.cs:
UI類:
1)ImportChannelsForm.cs:
2)ImportProgressForm.cs:
3)SettingsForm.cs:
10)Communication.MODBUSPlug
特殊引用:
1) Common
2) DevAge.Core
3) DevAge.Windows.Forms
4) Modbus(NModbus插件)
5) OpcRcw.Comn(OPC插件)
6) OpcRcw.Da(OPC插件)
7) SourceGrid
普通類文件:
1)Channel.cs:
2)ChannelFactory.cs:
3)IModbusStation.cs:
4)ModbusBaseClientStation.cs:
5)ModbusEnums.cs:
6)ModbusSerialClientStation.cs:
7)ModbusTCPClientStation.cs:
8)Plugin.cs:
9)PropertyCommand.cs:
10)StationFactory.cs:
11)StringConstants.cs:
UI類:
1)AddStationForm.cs:
2)ModifyChannelForm.cs:
3)ModifySerialClientStationForm.cs:
4)ModifyTCPClientStationForm.cs:
5)SettingsForm.cs:
11)Communication.OPCPlug
特殊引用:
1) Common
2) DevAge.Core
3) DevAge.Windows.Forms
4) OpcRcw.Comn
5) OpcRcw.Da
6) SourceGrid
普通類文件:
1)ChannelFactory.cs:
2)ConnectionGroup.cs:
3)OPCBaseChannel.cs:
4)OPCDataCallback.cs:
5)Plugin.cs:
6)PropertyCommand.cs:
7)StringConstants.cs:
UI類:
1)ImportOPCForm.cs:
2)SettingsForm.cs:
12)Communication.OPCPlug.Tests(工程Communication.OPCPlug的測試工程)
特殊引用:
1) Common
2) Communication.OPCPlug
3) nunit.framework
4) NUnitForms
5) SourceGrid
普通類文件:
1)PluginLoadingTest.cs:
2)ReadWriteChannelsTest.cs:
UI類:無
13)Communication.SimulatorPlug
特殊引用:
1) Common
2) DevAge.Core
3) DevAge.Windows.Forms
4) IronPython
5) IronPython.Modules
6) Microsoft.Scripting
7) Microsoft.Scripting.Core
8) Puzzle.SyntaxBox.NET3.5(SyntaxBox插件。Powerful Syntax Highlight Windows Forms Control for the Microsoft.NET Platform)
9) SourceGrid
普通類文件:
1)ChannelFactory.cs:
2)ComputableChannel.cs:
3)CurrentTimeChannel.cs:
4)GenericChannel.cs:
5)Plugin.cs:
6)PropertyCommand.cs:
7)RampIntegerChannel.cs:
8)RandomIntegerChannel.cs:
9)SawIntegerChannel.cs:
10)SinusDoubleChannel.cs:
11)StringConstants.cs:
UI類:
1)SettingsForm.cs:
14)Communication.SimulatorPulg.Tests(工程Communication.SimulatorPulg的測試工程)
特殊引用:
1) Common
2) Communication.SimulatorPlug
3) nuint.framework
4) NUnitForms
5) SourceGrid
普通類文件:
1)PluginLoadingTest.cs:
2)PluginSettingsFormTest.cs:
3)PluginTest.cs:
UI類:無
15)Communication.SNMPPlug
特殊引用:
1) Common
2) DevAge.Core
3) DevAge.Windows.Forms
4) Microsoft.Practices.Unity(#SNMP插件)
5) Microsoft.Practices.Unity.Configuration(#SNMP插件)
6) SharpSnmpLib(#SNMP插件)
7) SharpSnmpLib.Controls(#SNMP插件)
8) SharpSnmpLib.Mib(#SNMP插件)
9) SourceGrid
普通類文件:
1)AgentFactory.cs:
2)Channel.cs:
3)ChannelFactory.cs:
4)IProfileRegistry.cs:
5)Plugin.cs:
6)PropertyCommand.cs:
7)SNMPAgent.cs:
8)StringConstants.cs:
UI類:
1)FormProfile.cs:
2)FormTable.cs:
3)ModifyChannelForm.cs:
4)SettingsForm.cs:
特殊文件:
1) app.config:
16)Communication.Timers
特殊引用:
1) Common
2) DevAge.Core
3) DevAge.Windows.Forms
4) SourceGrid
普通類文件:
1)AbsoluteTimerChannel.cs:
2)ChannelFactory.cs:
3)Plugin.cs:
4)PropertyCommand.cs:
5)RelativeTimerChannel.cs:
6)StringConstants.cs:
UI類:
1)SettingsForm.cs:
17) Designer
特殊引用:
1) Archiver
2) Common
3) CommonGUI
4) DevAge.Core
5) DevAge.Windows.Forms
6) Kent.Boogaart.Converters(WPF Converters provides a number of generic binding converters for use in WPF and Silverlight applications. Online at http://wpfconverters.codeplex.com)
7) PresemtationCore
8) PresentationFramework
9) Puzzle.SyntaxBox.NET3.5
10) SourceGrid
11) ToolBox(toolbox插件)
12) UIAutomationProvider(.NET framework 3.0特性)
13) Weifenluo.WinFormsUI.Docking(布局控件。https://sourceforge.net/projects/dockpanelsuite)
14) WindowsBase
15) WindowsFormsIntegration
普通類文件:
1)CommandManager.cs:
2)HelpCommands.cs:
3)Program.cs:
4)TooloxContext.cs:
5)WindowManager.cs:
UI類:
1)MainForm.cs:
特殊文件:
1)DialogMessages.resx:
18) Designer.Tests(工程Designer的測試工程)
特殊引用:
1) Core
2) Designer
3) nunit.framework
4) UIAutomationClient(.NET framework 3.0特性)
5) UIAutomationTypes(.NET framework 3.0特性)
6) White.Nunit(White測試框架。White與WatiN類似,它封裝了微軟的UIAutomation庫和Window消息,可以用于測試包括Win32,WinForm, WPF和SWT(java)在內的軟件。http://white.codeplex.com)
7) WindowsBase
普通類文件:
1)BindingDialogWrapper.cs:
2)BindingEditingTest.cs:
3)GridWrapper.cs:
4)Helpers.cs:
5)SaveLoadFunctionalityTest.cs:
6)SchemaEditingTest.cs:
7)ToolBoxWrapper.cs:
UI類:無
特殊文件:
1) App.config
19) RunTime
特殊引用:
1) Archiver
2) Common
3) CommonGUI
4) DevAge.Core
5) DevAge.Windows.Forms
6) NPlot(NPlot插件。NPlot is a free charting library for .NET。http://netcontrols.org/nplot/wiki)
7)PresemtationCore
8)PresemtationFramework
9) SourceGrid
10) Weifenluo.WinFormsUI.Docking
11)WindowsBase
12)WindowsFormsIntegration
普通類文件:
1)CommandManager.cs:
2)DocumentCommands.cs:
3)Program.cs:
4)WindowManager.cs:
UI類:
1)MainForm.cs:
特殊文件:
1)DialogMessages.resx:
2)StringResources.resx:
20)VisualControls.FS2EasyControls
特殊引用:
1) Common
2) Design
3)PresemtationCore
4)PresemtationFramework
5)WindowsBase
普通類文件:
1)AnalogTextValue.cs:
2)AnalogTextValueWrappers.cs:
3)BinaryColorText.cs:
4)BinaryColorTextWrappers.cs:
5)Plugin.cs:
6)PropertyCommand.cs:
7)StringConstants.cs:
UI類:無
總結
以上是生活随笔為你收集整理的[开源]FreeSCADA的研究的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ApiPost
- 下一篇: 判断wifi连接是否可用