Browse Source

小米自动化

liu.ben 5 months ago
commit
3836fe6e6a
100 changed files with 9267 additions and 0 deletions
  1. 409 0
      .gitignore
  2. BIN
      1_Picture/res/1070632.png
  3. BIN
      1_Picture/res/1072393.png
  4. BIN
      1_Picture/res/1072763.png
  5. BIN
      1_Picture/res/1077384.png
  6. BIN
      1_Picture/res/1077543.png
  7. BIN
      1_Picture/res/1096355.png
  8. BIN
      1_Picture/res/1115543.png
  9. BIN
      1_Picture/res/1130316.png
  10. BIN
      1_Picture/res/1130631.png
  11. BIN
      1_Picture/res/1138496.png
  12. BIN
      1_Picture/res/1144981.png
  13. BIN
      1_Picture/res/1155785.png
  14. BIN
      1_Picture/res/1168386.png
  15. BIN
      1_Picture/res/1168389.png
  16. BIN
      1_Picture/res/1168392.png
  17. BIN
      1_Picture/res/1168394.png
  18. BIN
      1_Picture/res/1199314.png
  19. BIN
      1_Picture/res/26276.png
  20. BIN
      1_Picture/res/26408.png
  21. BIN
      1_Picture/res/3717.png
  22. BIN
      1_Picture/res/508249.png
  23. BIN
      1_Picture/res/528787.png
  24. BIN
      1_Picture/res/537779.png
  25. BIN
      1_Picture/res/542926.png
  26. BIN
      1_Picture/res/543529.png
  27. BIN
      1_Picture/res/543531.png
  28. BIN
      1_Picture/res/544437.png
  29. BIN
      1_Picture/res/546567.png
  30. BIN
      1_Picture/res/562255.png
  31. BIN
      1_Picture/res/Alarm_Off.png
  32. BIN
      1_Picture/res/Alarm_On.png
  33. BIN
      1_Picture/res/Data_Information_Off.png
  34. BIN
      1_Picture/res/Data_Information_On.png
  35. BIN
      1_Picture/res/File_Excel_Off.png
  36. BIN
      1_Picture/res/File_Excel_On.png
  37. BIN
      1_Picture/res/Googol.bmp
  38. BIN
      1_Picture/res/HQ.PNG
  39. BIN
      1_Picture/res/Home_Off.png
  40. BIN
      1_Picture/res/Home_on.png
  41. BIN
      1_Picture/res/Login_Off.png
  42. BIN
      1_Picture/res/Login_On.png
  43. BIN
      1_Picture/res/MainBackGround.bmp
  44. BIN
      1_Picture/res/Mannual_Off.png
  45. BIN
      1_Picture/res/Mannual_On.png
  46. BIN
      1_Picture/res/Pause_Off.png
  47. BIN
      1_Picture/res/Pause_On.png
  48. BIN
      1_Picture/res/Start_Off.png
  49. BIN
      1_Picture/res/Start_On.png
  50. BIN
      1_Picture/res/Stop_Off.png
  51. BIN
      1_Picture/res/Stop_On.png
  52. BIN
      1_Picture/res/Vision_Off.png
  53. BIN
      1_Picture/res/Vision_On.png
  54. BIN
      1_Picture/res/chart_line.png
  55. BIN
      1_Picture/res/half_pie.png
  56. BIN
      1_Picture/res/ico_folder.png
  57. BIN
      1_Picture/res/ico_save.png
  58. BIN
      1_Picture/res/light_gray.png
  59. BIN
      1_Picture/res/light_green.png
  60. BIN
      1_Picture/res/light_red.png
  61. BIN
      1_Picture/res/menu_save.png
  62. BIN
      1_Picture/res/msdn.ico
  63. BIN
      1_Picture/res/servo_Left.png
  64. BIN
      1_Picture/res/servo_Stop.png
  65. BIN
      1_Picture/res/servo_back.png
  66. BIN
      1_Picture/res/servo_down.png
  67. BIN
      1_Picture/res/servo_front.png
  68. BIN
      1_Picture/res/servo_right.png
  69. BIN
      1_Picture/res/servo_turn_left.png
  70. BIN
      1_Picture/res/servo_turn_right.png
  71. BIN
      1_Picture/res/servo_up.png
  72. BIN
      1_Picture/res/set.png
  73. BIN
      1_Picture/res/流水线.bmp
  74. BIN
      1_Picture/res/载具图.PNG
  75. 49 0
      Fa_Xiaomi_N801A.sln
  76. 674 0
      LICENSE
  77. BIN
      MainForm/115Box.lnk.ico
  78. 52 0
      MainForm/CheckOneData.ini
  79. 95 0
      MainForm/ClassFile/DbHelper/JsonFileHelper.cs
  80. 422 0
      MainForm/ClassFile/DbHelper/PracticeContext.cs
  81. 333 0
      MainForm/ClassFile/DbHelper/SqlHelper.cs
  82. 144 0
      MainForm/ClassFile/FALibraryClass/CsvFunction.cs
  83. 416 0
      MainForm/ClassFile/FALibraryClass/DataFunction.cs
  84. 205 0
      MainForm/ClassFile/FALibraryClass/FileFunction.cs
  85. 64 0
      MainForm/ClassFile/FALibraryClass/FormAutoScaling.cs
  86. 336 0
      MainForm/ClassFile/FALibraryClass/IniFunction.cs
  87. 482 0
      MainForm/ClassFile/FALibraryClass/InovancePLC.cs
  88. 97 0
      MainForm/ClassFile/FALibraryClass/IsStrLegal.cs
  89. 83 0
      MainForm/ClassFile/FALibraryClass/LogMgr.cs
  90. 101 0
      MainForm/ClassFile/FALibraryClass/Md5Helper.cs
  91. 95 0
      MainForm/ClassFile/FALibraryClass/SingletonTemplate.cs
  92. 140 0
      MainForm/ClassFile/FALibraryClass/SystemParameter.cs
  93. 309 0
      MainForm/ClassFile/FALibraryClass/TcpFunction.cs
  94. 230 0
      MainForm/ClassFile/FALibraryClass/XmlHandle.cs
  95. 102 0
      MainForm/ClassFile/FileIOHelper.cs
  96. 3101 0
      MainForm/ClassFile/Inovance_EIP.cs
  97. 1058 0
      MainForm/ClassFile/ModbusClientHelper.cs
  98. 182 0
      MainForm/ClassFile/NPOIHelper.cs
  99. 88 0
      MainForm/ClassFile/NPOIOperate.cs
  100. 0 0
      MainForm/ClassFile/ProcessHelper.cs

+ 409 - 0
.gitignore

@@ -0,0 +1,409 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+13-小米汽车电子项目
+/开发文档/00 客户原始文件/13-小米汽车电子项目.zip
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK.zip
+/开发文档/10 交付文件/数据库安装包/SQL2016_x64_CHS.7z
+/开发文档/10 交付文件/数据库安装包/SSMS-Setup-CHS.exe
+/开发文档/01 客户原始资料/13-小米汽车电子项目.zip
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/DataTransferDll/DataTransferDll.h
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/MqttClientCSharp/App.config
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/MqttClientCSharp/MqttClientCSharp.csproj
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/MqttClientCSharp/Program.cs
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/MqttClientCSharp/Properties/AssemblyInfo.cs
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/CommonLog.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/DigitalBase.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/Digitizing.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/DZx64.exe
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/DZx86.exe
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/FileAutoUpload.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/M2Mqtt.Net.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/MQTT.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/MqttServer.exe
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/Newtonsoft.Json.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/CommonLog.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/DataTransferDll.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/Newtonsoft.Json.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/OpenHardwareMonitorLib.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/PCMonitor.exe
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/System.Data.SQLite.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/System.Threading.Tasks.Dataflow.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/System.ValueTuple.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/msvcp140.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/ucrtbase.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/PCMonitor/vcruntime140.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/Shell.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/System.Data.SQLite.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/TestRecordUpload.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/ThingsModel.json
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/ark.x64.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/bz.exe
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/fastJSON.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/generateComputerId.exe
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/msvcp71.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ThirdPartyAll/ThingsMode/msvcr71.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/libcurl.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/msvcp140d.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/ucrtbased.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/CompileDllx64/vcruntime140d.dll
+/开发文档/01 客户原始资料/小米-IoT数据采集SDK/小米SDK/MIAutomation/Config/DigitConfig.xml

BIN
1_Picture/res/1070632.png


BIN
1_Picture/res/1072393.png


BIN
1_Picture/res/1072763.png


BIN
1_Picture/res/1077384.png


BIN
1_Picture/res/1077543.png


BIN
1_Picture/res/1096355.png


BIN
1_Picture/res/1115543.png


BIN
1_Picture/res/1130316.png


BIN
1_Picture/res/1130631.png


BIN
1_Picture/res/1138496.png


BIN
1_Picture/res/1144981.png


BIN
1_Picture/res/1155785.png


BIN
1_Picture/res/1168386.png


BIN
1_Picture/res/1168389.png


BIN
1_Picture/res/1168392.png


BIN
1_Picture/res/1168394.png


BIN
1_Picture/res/1199314.png


BIN
1_Picture/res/26276.png


BIN
1_Picture/res/26408.png


BIN
1_Picture/res/3717.png


BIN
1_Picture/res/508249.png


BIN
1_Picture/res/528787.png


BIN
1_Picture/res/537779.png


BIN
1_Picture/res/542926.png


BIN
1_Picture/res/543529.png


BIN
1_Picture/res/543531.png


BIN
1_Picture/res/544437.png


BIN
1_Picture/res/546567.png


BIN
1_Picture/res/562255.png


BIN
1_Picture/res/Alarm_Off.png


BIN
1_Picture/res/Alarm_On.png


BIN
1_Picture/res/Data_Information_Off.png


BIN
1_Picture/res/Data_Information_On.png


BIN
1_Picture/res/File_Excel_Off.png


BIN
1_Picture/res/File_Excel_On.png


BIN
1_Picture/res/Googol.bmp


BIN
1_Picture/res/HQ.PNG


BIN
1_Picture/res/Home_Off.png


BIN
1_Picture/res/Home_on.png


BIN
1_Picture/res/Login_Off.png


BIN
1_Picture/res/Login_On.png


BIN
1_Picture/res/MainBackGround.bmp


BIN
1_Picture/res/Mannual_Off.png


BIN
1_Picture/res/Mannual_On.png


BIN
1_Picture/res/Pause_Off.png


BIN
1_Picture/res/Pause_On.png


BIN
1_Picture/res/Start_Off.png


BIN
1_Picture/res/Start_On.png


BIN
1_Picture/res/Stop_Off.png


BIN
1_Picture/res/Stop_On.png


BIN
1_Picture/res/Vision_Off.png


BIN
1_Picture/res/Vision_On.png


BIN
1_Picture/res/chart_line.png


BIN
1_Picture/res/half_pie.png


BIN
1_Picture/res/ico_folder.png


BIN
1_Picture/res/ico_save.png


BIN
1_Picture/res/light_gray.png


BIN
1_Picture/res/light_green.png


BIN
1_Picture/res/light_red.png


BIN
1_Picture/res/menu_save.png


BIN
1_Picture/res/msdn.ico


BIN
1_Picture/res/servo_Left.png


BIN
1_Picture/res/servo_Stop.png


BIN
1_Picture/res/servo_back.png


BIN
1_Picture/res/servo_down.png


BIN
1_Picture/res/servo_front.png


BIN
1_Picture/res/servo_right.png


BIN
1_Picture/res/servo_turn_left.png


BIN
1_Picture/res/servo_turn_right.png


BIN
1_Picture/res/servo_up.png


BIN
1_Picture/res/set.png


BIN
1_Picture/res/流水线.bmp


BIN
1_Picture/res/载具图.PNG


+ 49 - 0
Fa_Xiaomi_N801A.sln

@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34622.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MainForm", "MainForm\MainForm.csproj", "{486CDA85-35DC-443E-91EB-A369F0047391}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MqttClientCSharp", "MqttClientCSharp\MqttClientCSharp.csproj", "{C339F0BD-441C-4E22-9CFE-2374A1F78F62}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Debug|x64.ActiveCfg = Debug|x64
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Debug|x64.Build.0 = Debug|x64
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Debug|x86.ActiveCfg = Debug|x86
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Debug|x86.Build.0 = Debug|x86
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Release|Any CPU.Build.0 = Release|Any CPU
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Release|x64.ActiveCfg = Release|x64
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Release|x64.Build.0 = Release|x64
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Release|x86.ActiveCfg = Release|x86
+		{486CDA85-35DC-443E-91EB-A369F0047391}.Release|x86.Build.0 = Release|x86
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Debug|x64.ActiveCfg = Debug|x64
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Debug|x64.Build.0 = Debug|x64
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Release|x64.ActiveCfg = Release|x64
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Release|x64.Build.0 = Release|x64
+		{C339F0BD-441C-4E22-9CFE-2374A1F78F62}.Release|x86.ActiveCfg = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {D0091873-05BD-4E41-BC97-0DB373850684}
+	EndGlobalSection
+EndGlobal

+ 674 - 0
LICENSE

@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.

BIN
MainForm/115Box.lnk.ico


File diff suppressed because it is too large
+ 52 - 0
MainForm/CheckOneData.ini


+ 95 - 0
MainForm/ClassFile/DbHelper/JsonFileHelper.cs

@@ -0,0 +1,95 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.IO;
+using System.Text;
+
+namespace MainForm.Common
+{
+    public class JsonFileHelper
+    {
+        /// <summary>
+        /// 读取JSON文件
+        /// </summary>
+        /// <typeparam name="T">返回的类型</typeparam>
+        /// <param name="fileName">打开的文件路径</param>
+        /// <returns>实体类</returns>
+        public static T ReadjsonT<T>(string fileName)
+        {
+            //using (System.IO.StreamReader file = System.IO.File.OpenText(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + fileName))
+            using (System.IO.StreamReader file = System.IO.File.OpenText(fileName))
+            {
+                return JsonConvert.DeserializeObject<T>(file.ReadToEnd());
+            }
+        }
+        //Config config = new Config();
+        //config= JsonfileTools.ReadjsonT<Config>("SendDataZCCAconfig.json");
+
+        /// <summary>
+        /// 写入JSON文件
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fileName">保存使用的文件路径</param>
+        /// <param name="tParameter">实体类</param>
+        /// <returns>成功状态</returns>
+        public static bool WritejsonT<T>(string fileName, T tParameter)
+        {
+            //string fp = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + fileName;
+            string fp = fileName;
+            try
+            {
+                File.WriteAllText(fp, JsonConvert.SerializeObject(tParameter));  // 覆盖写入
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 修改-Value通过Key(AppSetting)
+        /// </summary>
+        /// <param name="filePath">文件路径</param>
+        /// <param name="key">需要修改的key</param>
+        /// <param name="value">更改为的值</param>
+        /// <returns></returns>
+        public static void ModifyValueByKey(string filePath, string[] key, string value)
+        {
+            try
+            {
+                if (!File.Exists(filePath))
+                {
+                    throw new Exception("需要修改的json文件不存在!");
+                }
+                string jsonStr = File.ReadAllText(filePath, Encoding.UTF8); // 读取文件流
+
+                JObject json = JObject.Parse(jsonStr);  // 解析成json
+                                                        //json[key] = value;  // 修改需要修改的字段
+                switch (key.Length)
+                {
+                    case 1:
+                        json[key[0]] = value;
+                        break;
+                    case 2:
+                        json[key[0]][key[1]] = value;
+                        break;
+                    case 3:
+                        json[key[0]][key[1]][key[2]] = value;
+                        break;
+                    default:
+                        // 目前只用到最多三层的
+                        break;
+                }
+
+                jsonStr = Convert.ToString(json);
+                File.WriteAllText(filePath, jsonStr, Encoding.UTF8);
+            }
+            catch
+            {
+                throw new Exception($"修改{filePath}文件出错!");
+            }
+            
+        }
+    }
+}

+ 422 - 0
MainForm/ClassFile/DbHelper/PracticeContext.cs

@@ -0,0 +1,422 @@
+using MainForm.Common;
+using Newtonsoft.Json;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MainForm.DbHelper
+{
+    /// <summary>
+    /// 连接
+    /// </summary>
+    public class PracticeContext
+    {
+        //private static readonly string _connectionString = ConfigurationManager.AppSettings["DefaultConnection"];
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public SqlSugarClient Db;
+
+        /// <summary>
+        /// 初始化
+        /// </summary>
+        /// <param name="connName">连接字符串名称</param>
+        public PracticeContext()
+        {
+            Db = new SqlSugarClient(new ConnectionConfig()
+            {
+                //ConnectionString = AESEncryptHelper.Decode(_connectionString,AESEncryptHelper.EncryptKey),  // 连接字符串
+                ConnectionString = @"server= " + GlobalContext.Server +
+                ";database= DBMain" +
+                ";uid=" + GlobalContext.User +
+                ";pwd=" + GlobalContext.PassWord,
+                DbType = DbType.SqlServer,              // 数据库类型
+                InitKeyType = InitKeyType.Attribute,    // 从特性读取主键和自增列信息
+                IsAutoCloseConnection = true            // 开启自动释放模式,和EF原理一样
+            }) ;
+
+            //// 每次Sql执行前事件,记录进行的操作
+            //Db.Aop.OnLogExecuting = (sql, pars) =>
+            //{
+            //    StringBuilder sqlStr = new();
+
+            //    if (sql.StartsWith("UPDATE") || sql.StartsWith("INSERT"))
+            //    {
+            //        Console.ForegroundColor = ConsoleColor.Blue;
+            //        sqlStr.AppendLine($"==============将要执行新增/修改操作==============");
+            //    }
+            //    if (sql.StartsWith("DELETE"))
+            //    {
+            //        Console.ForegroundColor = ConsoleColor.Red;
+            //        sqlStr.AppendLine($"==============将要执行删除操作==============");
+            //    }
+            //    if (sql.StartsWith("SELECT"))
+            //    {
+            //        Console.ForegroundColor = ConsoleColor.Green;
+            //        sqlStr.AppendLine($"==============将要执行查询操作==============");
+            //    }
+            //    sqlStr.AppendLine("预SQL:");
+            //    sqlStr.AppendLine("    " + sql);
+
+            //    string sqlPars = Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));
+            //    sqlStr.AppendLine("SQL预传参:");
+            //    sqlStr.AppendLine("    " + sqlPars);
+            //    Console.WriteLine(sqlStr.ToString());  // 打印
+            //    Console.ForegroundColor = ConsoleColor.White;
+
+            //    // 记录执行的信息
+
+            //};
+
+            ////每次Sql执行后事件,记录SQL执行完的信息
+            //Db.Aop.OnLogExecuted = (sql, pars) =>
+            //{
+            //    // 执行时间超过1秒
+            //    if (Db.Ado.SqlExecutionTime.TotalSeconds > 1)
+            //    {
+            //        StringBuilder sqlPStr = new();
+            //        sqlPStr.AppendLine($"==============执行了下面的操作==============");
+            //        var fileName = Db.Ado.SqlStackTrace.FirstFileName;           // 代码CS文件名
+            //        sqlPStr.AppendLine("代码CS文件名:" + fileName);
+            //        var fileLine = Db.Ado.SqlStackTrace.FirstLine;               // 代码行数
+            //        sqlPStr.AppendLine("代码行数:" + fileLine);
+            //        var FirstMethodName = Db.Ado.SqlStackTrace.FirstMethodName;  // 方法名
+            //        sqlPStr.AppendLine("方法名:" + FirstMethodName);
+            //        sqlPStr.AppendLine("SQL:");
+            //        sqlPStr.AppendLine("    " + sql);
+            //        var sqlPars = Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));  // 参数
+            //        sqlPStr.AppendLine("SQL传参:");
+            //        sqlPStr.AppendLine("    " + sqlPars);
+            //        // 打印
+            //        Console.ForegroundColor = ConsoleColor.Green;
+            //        Console.WriteLine(sqlPStr);
+            //        Console.ForegroundColor = ConsoleColor.White;
+
+            //        // 记录执行的信息
+
+            //    }
+            //};
+
+            //// 记录SQL报错
+            //Db.Aop.OnError = (exp) =>
+            //{
+            //    StringBuilder sqlStr = new();
+            //    sqlStr.AppendLine($"==============数据库执行报错==============");
+            //    sqlStr.AppendLine("SQL: ");
+            //    sqlStr.AppendLine("    " + exp.Sql);
+            //    Console.ForegroundColor = ConsoleColor.Red;
+            //    Console.WriteLine(sqlStr);   // 打印
+            //    Console.ForegroundColor = ConsoleColor.White;
+            //    // 记录执行的信息
+            //};
+        }
+
+        /// <summary>
+        /// 初始化
+        /// </summary>
+        /// <param name="connName">连接字符串名称</param>
+        public PracticeContext(string connectionString)
+        {
+            Db = new SqlSugarClient(new ConnectionConfig()
+            {
+                ConnectionString = connectionString,    // 连接字符串
+                DbType = DbType.SqlServer,              // 数据库类型
+                InitKeyType = InitKeyType.Attribute,    // 从特性读取主键和自增列信息
+                IsAutoCloseConnection = true            // 开启自动释放模式,和EF原理一样
+            });
+
+            //// 每次Sql执行前事件,记录进行的操作
+            //Db.Aop.OnLogExecuting = (sql, pars) =>
+            //{
+            //    StringBuilder sqlStr = new();
+
+            //    if (sql.StartsWith("UPDATE") || sql.StartsWith("INSERT"))
+            //    {
+            //        Console.ForegroundColor = ConsoleColor.Blue;
+            //        sqlStr.AppendLine($"==============将要执行新增/修改操作==============");
+            //    }
+            //    if (sql.StartsWith("DELETE"))
+            //    {
+            //        Console.ForegroundColor = ConsoleColor.Red;
+            //        sqlStr.AppendLine($"==============将要执行删除操作==============");
+            //    }
+            //    if (sql.StartsWith("SELECT"))
+            //    {
+            //        Console.ForegroundColor = ConsoleColor.Green;
+            //        sqlStr.AppendLine($"==============将要执行查询操作==============");
+            //    }
+            //    sqlStr.AppendLine("预SQL:");
+            //    sqlStr.AppendLine("    " + sql);
+
+            //    string sqlPars = Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));
+            //    sqlStr.AppendLine("SQL预传参:");
+            //    sqlStr.AppendLine("    " + sqlPars);
+            //    Console.WriteLine(sqlStr.ToString());  // 打印
+            //    Console.ForegroundColor = ConsoleColor.White;
+
+            //    // 记录执行的信息
+
+            //};
+
+            ////每次Sql执行后事件,记录SQL执行完的信息
+            //Db.Aop.OnLogExecuted = (sql, pars) =>
+            //{
+            //    // 执行时间超过1秒
+            //    if (Db.Ado.SqlExecutionTime.TotalSeconds > 1)
+            //    {
+            //        StringBuilder sqlPStr = new();
+            //        sqlPStr.AppendLine($"==============执行了下面的操作==============");
+            //        var fileName = Db.Ado.SqlStackTrace.FirstFileName;           // 代码CS文件名
+            //        sqlPStr.AppendLine("代码CS文件名:" + fileName);
+            //        var fileLine = Db.Ado.SqlStackTrace.FirstLine;               // 代码行数
+            //        sqlPStr.AppendLine("代码行数:" + fileLine);
+            //        var FirstMethodName = Db.Ado.SqlStackTrace.FirstMethodName;  // 方法名
+            //        sqlPStr.AppendLine("方法名:" + FirstMethodName);
+            //        sqlPStr.AppendLine("SQL:");
+            //        sqlPStr.AppendLine("    " + sql);
+            //        var sqlPars = Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));  // 参数
+            //        sqlPStr.AppendLine("SQL传参:");
+            //        sqlPStr.AppendLine("    " + sqlPars);
+            //        // 打印
+            //        Console.ForegroundColor = ConsoleColor.Green;
+            //        Console.WriteLine(sqlPStr);
+            //        Console.ForegroundColor = ConsoleColor.White;
+
+            //        // 记录执行的信息
+
+            //    }
+            //};
+
+            //// 记录SQL报错
+            //Db.Aop.OnError = (exp) =>
+            //{
+            //    StringBuilder sqlStr = new();
+            //    sqlStr.AppendLine($"==============数据库执行报错==============");
+            //    sqlStr.AppendLine("SQL: ");
+            //    sqlStr.AppendLine("    " + exp.Sql);
+            //    Console.ForegroundColor = ConsoleColor.Red;
+            //    Console.WriteLine(sqlStr);   // 打印
+            //    Console.ForegroundColor = ConsoleColor.White;
+            //    // 记录执行的信息
+            //};
+        }
+        /// <summary>
+        /// 根据Entity(实体)生成数据库中的表
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="entity">指定Entity名;不指定时生成指定作用域中/默认作用域(一般指文件夹名)下所有Entity的表结构</param>
+        /// <param name="dllName">指定类的包名</param>
+        /// <param name="classNameSpaces">指定类的包名</param>
+        public void CodeFirst<T>(T entity = null, string dllName = "BOZHON.Repository.dll", string[] classNameSpaces = null) where T : class, new()
+        {
+            classNameSpaces = classNameSpaces == null ? new string[] { "Entity" } : classNameSpaces;
+
+            if (entity is null)
+            {
+                var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
+                List<Type> entitylist = new List<Type>();
+                if (!string.IsNullOrWhiteSpace(dllName))
+                {
+                    dllName = path + dllName;
+                    Assembly assembly = Assembly.LoadFrom(dllName);
+                    Type[] ts = assembly.GetTypes();
+                    foreach (string classNameSpace in classNameSpaces)
+                    {
+                        foreach (Type t in ts)
+                        {
+                            if (t.FullName.Contains(classNameSpace))
+                            {
+                                entitylist.Add(t);
+                            }
+                        }
+                    }
+                }
+                Db.CodeFirst.SetStringDefaultLength(255).InitTables(entitylist.ToArray());
+            }
+            else
+            {
+                Db.CodeFirst.SetStringDefaultLength(255).InitTables(typeof(T));
+            }
+        }
+
+        /// <summary>
+        /// 导入种子数据
+        /// 注:批量不可用(指定Entity名时功能可用,通过“classNameSpaces”批量导入时功能不可用)
+        /// ① DBSeed文件使用json文件保存;
+        /// ② 一张表一个DBSeed文件;
+        /// ③ 文件名字与表名保持一致;
+        /// </summary>
+        /// <param name="dbSeedFileDirec">DB种子数据所在的的文件夹(放在程序目录下)</param>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="entity">指定Entity名;不指定时生成指定作用域中/默认作用域(一般指文件夹名)下所有Entity的表的数据</param>
+        /// <param name="dllName">指定实体类的包名</param>
+        /// <param name="classNameSpaces">指定实体类的包名</param>
+        /// <exception cref="NotImplementedException"></exception>
+        public void ImportDBSeed<T>(string dbSeedFileDirec, T entity = null, string dllName = "BOZHON.Repository.dll", string[] classNameSpaces = null) where T : class, new()
+        {
+            classNameSpaces = classNameSpaces == null ? new string[] { "Entity" } : classNameSpaces;
+
+            var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
+            string dbSeedFileDirecPath = path + dbSeedFileDirec + @"/";
+            if (!Directory.Exists(dbSeedFileDirecPath))
+            {
+                throw new Exception("DB数据初始化失败!在程序目录下找不到DB种子数据文件夹!");
+            }
+
+            if (entity is null)
+            {
+                List<Type> entitylist = new List<Type>();
+                if (!string.IsNullOrWhiteSpace(dllName))
+                {
+                    dllName = path + dllName;
+                    Assembly assembly = Assembly.LoadFrom(dllName);
+                    Type[] ts = assembly.GetTypes();
+                    foreach (string classNameSpace in classNameSpaces)
+                    {
+                        foreach (Type t in ts)
+                        {
+                            if (t.FullName.Contains(classNameSpace))
+                            {
+                                entitylist.Add(t);
+                            }
+                        }
+                    }
+                }
+
+                foreach (Type type in entitylist)
+                {
+                    string dbSeedFilePath = dbSeedFileDirecPath + type.Name + ".json";
+
+                    if (File.Exists(dbSeedFilePath))
+                    {
+                        Type typeList = typeof(List<>);
+                        Type actualType = typeList.MakeGenericType(type);
+                        dynamic obj = Activator.CreateInstance(actualType);
+
+                        obj = JsonFileHelper.ReadjsonT<object>(dbSeedFilePath);  // 加载数据
+                        //Db.Insertable(obj).ExecuteCommand();  // 未找到合适的无实体插入方法
+
+                        throw new Exception("批量插入请使用方法ImportDBSeed2!");
+                    }
+                }
+            }
+            else
+            {
+                string dbSeedFilePath = dbSeedFileDirecPath + entity.GetType().Name + ".json";
+                if (File.Exists(dbSeedFilePath))
+                {
+                    T obj = JsonFileHelper.ReadjsonT<T>(dbSeedFilePath);  // 加载数据
+
+                    Db.Insertable(obj);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 导入种子数据-批量
+        /// ① DBSeed文件使用json文件保存;
+        /// ② 一张表一个DBSeed文件;
+        /// ③ 文件名字与表名保持一致;
+        /// </summary>
+        /// <param name="dbSeedFileDirec">DB种子数据所在的的文件夹(放在程序目录下)</param>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="entity">指定Entity名;不指定时生成指定作用域中/默认作用域(一般指文件夹名)下所有Entity的表的数据</param>
+        /// <param name="dllName">指定实体类的包名</param>
+        /// <param name="classNameSpaces">指定实体类的包名</param>
+        /// <exception cref="NotImplementedException"></exception>
+        public void ImportDBSeed2(string dbSeedFileDirec) 
+        {
+            var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
+            string dbSeedFileDirecPath = path + dbSeedFileDirec + @"/";
+            if (!Directory.Exists(dbSeedFileDirecPath))
+            {
+                throw new Exception("DB数据初始化失败!在程序目录下找不到DB种子数据文件夹!");
+            }
+
+            #region 设置DBSeed
+            //ImportDBSeed2<SYS_USER>(dbSeedFileDirecPath);
+            //ImportDBSeed2<SYS_USER_ROLE>(dbSeedFileDirecPath);
+            #endregion 设置DBSeed
+        }
+
+        /// <summary>
+        /// ImportDBSeed2-导入种子数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="dbSeedFileDirecPath">文件夹路径</param>
+        private void ImportDBSeed2<T>(string dbSeedFileDirecPath) where T : class, new()
+        {
+            string dbSeedFilePath = dbSeedFileDirecPath + new T().GetType().Name + ".json";
+            if (File.Exists(dbSeedFilePath))
+            {
+                var objs = JsonFileHelper.ReadjsonT<List<T>>(dbSeedFilePath);  // 加载数据
+
+                Db.Insertable<T>(objs).ExecuteCommand();
+            }
+        }
+
+        /// <summary>
+        /// 导出种子数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="dbSeedFileDirec">DB种子数据导出的文件夹(生成在程序目录下)</param>
+        /// <param name="entity">指定Entity名;不指定时生成指定作用域中/默认作用域(一般指文件夹名)下所有Entity的表的数据</param>
+        /// <param name="dllName">指定实体类的包名</param>
+        /// <param name="classNameSpaces">指定实体类的包名</param>
+        public void ExportDBSeed<T>(string dbSeedFileDirec, T entity = null, string dllName = "BOZHON.Repository.dll", string[] classNameSpaces = null) where T : class, new()
+        {
+            classNameSpaces = classNameSpaces == null ? new string[] { "Entity" } : classNameSpaces;
+
+            var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
+            string dbSeedFileDirecPath = path + dbSeedFileDirec + @"/";
+            if (!Directory.Exists(dbSeedFileDirecPath))
+            {
+                Directory.CreateDirectory(dbSeedFileDirecPath);  // 生成目录
+            }
+
+            if (entity is null)
+            {
+                List<Type> entitylist = new List<Type>();
+                if (!string.IsNullOrWhiteSpace(dllName))
+                {
+                    dllName = path + dllName;
+                    Assembly assembly = Assembly.LoadFrom(dllName);
+                    Type[] ts = assembly.GetTypes();
+                    foreach (string classNameSpace in classNameSpaces)
+                    {
+                        foreach (Type t in ts)
+                        {
+                            if (t.FullName.Contains(classNameSpace))
+                            {
+                                entitylist.Add(t);
+                            }
+                        }
+                    }
+                }
+
+                foreach (Type type in entitylist)
+                {
+                    string dbSeedFilePath = dbSeedFileDirecPath + type.Name + ".json";
+
+                    var seedDatas = Db.Queryable(type.Name, type.Name).ToList();
+
+                    JsonFileHelper.WritejsonT(dbSeedFilePath, seedDatas);
+                }
+            }
+            else
+            {
+                string dbSeedFilePath = dbSeedFileDirecPath + entity.GetType().Name + ".json";
+                var seedDatas = Db.Queryable<T>().ToList();
+
+                JsonFileHelper.WritejsonT(dbSeedFilePath, seedDatas);
+            }
+        }
+    }
+}

+ 333 - 0
MainForm/ClassFile/DbHelper/SqlHelper.cs

@@ -0,0 +1,333 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MainForm.DbHelper
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public class SqlHelper : PracticeContext
+    {
+        #region 查询
+
+        /// <summary>
+        /// 查询实体
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <returns></returns>
+        public List<T> Queryable<T>() where T : class, new()
+        {
+            return Db.Queryable<T>().ToList();
+        }
+
+        /// <summary>
+        /// 根据表达式查询实体
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="expression">Where条件</param>
+        /// <returns></returns>
+        public List<T> Queryable<T>(Expression<Func<T, bool>> expression) where T : class, new()
+        {
+            return Db.Queryable<T>().Where(expression).ToList();
+        }
+
+        /// <summary>
+        /// 根据表达式查询第一条实体
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="expression">Where条件</param>
+        /// <param name="orderFileds">排序字段</param>
+        /// <returns></returns>
+        public T QueryableAscFirst<T>(Expression<Func<T, bool>> expression, string orderFileds = null) where T : class, new()
+        {
+            if (orderFileds == null)
+            {
+                return Db.Queryable<T>().Where(expression).First();
+            }
+            return Db.Queryable<T>().Where(expression).OrderBy(orderFileds).First();
+        }
+
+        /// <summary>
+        /// SQL语句查询
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="sql">SQL执行语句</param>
+        /// <returns></returns>
+        public List<T> SqlQueryable<T>(string sql) where T : class, new()
+        {
+            return Db.SqlQueryable<T>(sql).ToList();
+        }
+
+        /// <summary>
+        /// SQL语句执行
+        /// </summary>
+        /// <param name="sql">SQL执行语句</param>
+        /// <returns></returns>
+        public bool SqlExecuteCommand(string sql)
+        {
+            if (string.IsNullOrEmpty(sql)) return true;
+
+            try
+            {
+                int count = Db.Ado.ExecuteCommand(sql);
+
+                return count > 0;
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        #endregion
+
+        #region 新增
+
+        /// <summary>
+        /// 新增
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="insertObj">数据</param>
+        /// <returns>状态</returns>
+        public bool Insert<T>(T insertObj) where T : class, new()
+        {
+            if (insertObj == null) return true;
+
+            try
+            {
+                return Db.Insertable(insertObj).ExecuteCommandIdentityIntoEntity();
+            }
+            catch (Exception e)
+            {
+                throw e;
+            }
+        }
+
+        /// <summary>
+        /// 批量新增
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="insertObjs">数据</param>
+        /// <returns>状态</returns>
+        public bool Insert<T>(List<T> insertObjs) where T : class, new()
+        {
+            if (!insertObjs.Any()) return true;
+
+            try
+            {
+                //分页操作 ,如果不支持db.Fastest分页插入也是可以提升一下性能的
+                Db.Utilities.PageEach(insertObjs, 100, pageList =>
+                {
+                    int result = Db.Insertable(pageList).ExecuteCommand();
+                    if (result != pageList.Count)
+                    {
+                        throw new Exception($"批量新增失败,计划操作{pageList.Count}条,实际操作{result}条");
+                    }
+                });
+
+                return true;
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        #endregion
+
+        #region 修改
+
+        /// <summary>
+        /// 根据主键修改
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="UpdateObj">数据</param>
+        /// <returns>状态</returns>
+        public bool Update<T>(T UpdateObj) where T : class, new()
+        {
+            if (UpdateObj == null) return true;
+
+            try
+            {
+                return Db.Updateable(UpdateObj).ExecuteCommandHasChange();
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        /// <summary>
+        /// 根据主键修改实体指定列
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="UpdateObj">数据</param>
+        /// <param name="columns">需要更新的实体列</param>
+        /// <returns></returns>
+        public bool Update<T>(T UpdateObj, Expression<Func<T, object>> columns) where T : class, new()
+        {
+            if (UpdateObj == null) return true;
+
+            try
+            {
+                return Db.Updateable(UpdateObj).UpdateColumns(columns).ExecuteCommandHasChange();
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        /// <summary>
+        /// 根据主键批量修改
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="UpdateObjs">数据</param>
+        /// <returns>状态</returns>
+        public bool Update<T>(List<T> UpdateObjs) where T : class, new()
+        {
+            if (!UpdateObjs.Any()) return true;
+
+            try
+            {
+                //分页操作 ,如果不支持db.Fastest分页插入也是可以提升一下性能的
+                Db.Utilities.PageEach(UpdateObjs, 100, pageList =>
+                {
+                    int result = Db.Updateable(pageList).ExecuteCommand();
+                    if (result != pageList.Count)
+                    {
+                        throw new Exception($"批量修改失败,计划操作{pageList.Count}条,实际操作{result}条");
+                    }
+                });
+
+                return true;
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        #endregion
+
+        #region 删除
+
+        /// <summary>
+        /// 根据主键删除
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <typeparam name="PkType">主键类型</typeparam>
+        /// <param name="primaryKeyValue">主键</param>
+        /// <returns>状态</returns>
+        public bool Deleteable<T, PkType>(PkType primaryKeyValue) where T : class, new()
+        {
+            try
+            {
+                return Db.Deleteable<T>().In(primaryKeyValue).ExecuteCommandHasChange();
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        /// <summary>
+        /// 根据表达式删除
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="expression">Where条件</param>
+        /// <returns>状态</returns>
+        public bool Deleteable<T>(Expression<Func<T, bool>> expression) where T : class, new()
+        {
+            try
+            {
+                return Db.Deleteable<T>().Where(expression).ExecuteCommandHasChange();
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        /// <summary>
+        /// 根据主键批量删除
+        /// </summary>
+        /// <typeparam name="T">实体</typeparam>
+        /// <param name="UpdateObjs">数据</param>
+        /// <returns>状态</returns>
+        public bool Deleteable<T>(List<T> deleteObjs) where T : class, new()
+        {
+            if (!deleteObjs.Any()) return true;
+
+            try
+            {
+                //分页操作 ,如果不支持db.Fastest分页插入也是可以提升一下性能的
+                Db.Utilities.PageEach(deleteObjs, 100, pageList =>
+                {
+                    int result = Db.Deleteable(pageList).ExecuteCommand();
+                    if (result != pageList.Count)
+                    {
+                        throw new Exception($"批量删除失败,计划操作{pageList.Count}条,实际操作{result}条");
+                    }
+                });
+
+                return true;
+            }
+            catch (Exception e)
+            {
+                return ExceptionCapture(e);
+            }
+        }
+
+        #endregion
+
+        #region 事务  (private,后期扩展增删改方法直接把事务方法添加进去;或者根据需求public)
+
+        /// <summary>
+        /// 开始事务
+        /// </summary>
+        private void BeginTran()
+        {
+            Db.Ado.BeginTran();
+        }
+
+        /// <summary>
+        /// 提交事务
+        /// </summary>
+        private void CommitTran()
+        {
+            Db.Ado.CommitTran();
+        }
+
+        /// <summary>
+        /// 回滚事务
+        /// </summary>
+        private void RollbackTran()
+        {
+            Db.Ado.RollbackTran();
+        }
+
+        #endregion
+
+        #region 异常捕捉
+
+        /// <summary>
+        /// 异常捕捉
+        /// </summary>
+        /// <param name="e"></param>
+        /// <returns></returns>
+        private bool ExceptionCapture(Exception ex)
+        {
+            Console.WriteLine("\n异常信息:\n{0}", ex.Message);
+
+            return false;
+        }
+
+        #endregion
+    }
+}

+ 144 - 0
MainForm/ClassFile/FALibraryClass/CsvFunction.cs

@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.IO;
+
+namespace MainForm
+{
+    class CsvFunction
+    {
+        /// <summary>
+        /// 新建CSV文件,
+        /// </summary>
+        /// <param name="csvFile">文件路径+文件名(包含扩展名)</param>
+        public static void NewCsvFile(string csvFile, string title = null)
+        {
+            string path = csvFile.Substring(0, csvFile.LastIndexOf("\\"));
+            if (!Directory.Exists(path)) Directory.CreateDirectory(path); //判断路径是否存在,不存在则创建
+            if (!File.Exists(csvFile))  //判断文件是否存在,不存在则创建
+            {
+                using (FileStream fileStream = new FileStream(csvFile, FileMode.Create, FileAccess.Write))
+                {
+                    if (title != null)
+                    {
+                        StreamWriter streamWriter = new StreamWriter(fileStream,Encoding.ASCII);
+                        //sw.BaseStream的Position或Seek()可移动文件流指针到的任意位置。
+                        streamWriter.BaseStream.Seek(0, SeekOrigin.End);  //在CSV末尾写入
+                        streamWriter.Write(title);      //写入CSV文件内容
+                        streamWriter.Flush();
+                        streamWriter.Close();
+                    }
+                    fileStream.Close();
+                }
+            }
+        }
+
+        /// <summary>
+        /// 写入CSV文件
+        /// </summary>
+        /// <param name="csvFile">文件路径+文件名(包含扩展名)</param>
+        /// <param name="txt">写入内容</param>
+        public static bool WriteCsvFile(string csvFile, string txt)
+        {
+            if (!File.Exists(csvFile)) NewCsvFile(csvFile); //判断文件是否存在,不存在则新建
+            try
+            {
+                using (FileStream fileStream = new FileStream(csvFile, FileMode.Open, FileAccess.Write))    //写入文件
+                {
+                    StreamWriter streamWriter = new StreamWriter(fileStream,Encoding.Default);
+                    //sw.BaseStream的Position或Seek()可移动文件流指针到的任意位置。
+                    streamWriter.BaseStream.Seek(0, SeekOrigin.End);  //在CSV末尾写入
+                    streamWriter.Write(txt);      //写入CSV文件内容
+                    streamWriter.Flush();
+                    streamWriter.Close();
+                    fileStream.Close();
+                }
+                return true;
+            }
+            catch { return false; }
+        }
+
+        /// <summary>
+        /// 读取CSV文件内容
+        /// </summary>
+        /// <param name="csvFile">文件路径+文件名(包含扩展名)</param>
+        /// <returns>返回csv文件内容</returns>
+        public static string ReadCsvFile(string csvFile)
+        {
+            if (!File.Exists(csvFile)) return ""; //判断文件是否存在
+            string Return = "";
+            using (FileStream fileStream = new FileStream(csvFile, FileMode.Open, FileAccess.Read))
+            {
+                StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8);
+                Return = streamReader.ReadToEnd().ToString();
+                streamReader.Close();
+                fileStream.Close();
+            }
+            return Return;
+        }
+
+        public static int GetCsvRowNumber(string csvFile)
+        {
+            if (!File.Exists(csvFile)) return 0; //判断文件是否存在
+            string[] allLines = File.ReadAllLines(csvFile);
+            return allLines.Length;
+        }
+        public static string[] GetCsvAllLine(string csvFile)
+        {
+            if (!File.Exists(csvFile)) return null; //判断文件是否存在
+            string[] allLines = File.ReadAllLines(csvFile,Encoding.Default);
+            return allLines;
+        }
+
+        /// <summary>
+        /// 读取最后一行内容
+        /// </summary>
+        /// <param name="csvFile">文件路径+文件名(包含扩展名)</param>
+        /// <returns></returns>
+        public static string ReadLastLine(string csvFile)
+        {
+            if (!File.Exists(csvFile)) return ""; //判断文件是否存在
+            string[] allLines = File.ReadAllLines(csvFile);
+            if (allLines.Length > 0)
+                return allLines[allLines.Length - 1];
+            else return "";
+        }
+
+        /// <summary>
+        /// 覆盖最后一行内容
+        /// </summary>
+        /// <param name="csvFile">文件路径+文件名(包含扩展名)</param>
+        /// <param name="txt"></param>
+        public static void CoverLastLine(string csvFile, string txt)
+        {
+            if (File.Exists(csvFile))  //判断文件是否存在
+            {
+                string[] allLines = File.ReadAllLines(csvFile);
+                if (allLines.Length > 0)
+                {
+                    allLines[allLines.Length - 1] = txt;
+                    File.WriteAllLines(csvFile, allLines);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 移除最后一行内容
+        /// </summary>
+        /// <param name="csvFile">文件路径+文件名(包含扩展名)</param>
+        public static void RemoveLastLine(string csvFile)
+        {
+            if (File.Exists(csvFile))  //判断文件是否存在
+            {
+                string[] allLines = File.ReadAllLines(csvFile);
+                if (allLines.Length > 0)
+                {
+                    Array.Resize(ref allLines, allLines.Length - 1);
+                    File.WriteAllLines(csvFile, allLines);
+                }
+            }
+        }
+    }
+}

+ 416 - 0
MainForm/ClassFile/FALibraryClass/DataFunction.cs

@@ -0,0 +1,416 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StandardLibrary
+{
+    /// <summary>
+    /// 数据类型转换专用类
+    /// </summary>
+    static class TypeConversion
+    {
+        /// <summary>
+        /// 将16位整形转换成字节数组
+        /// </summary>
+        /// <param name="value">16位整形变量</param>
+        /// <returns></returns>
+        public static byte[] Short_Bytes(short[] value)
+        {
+            List<byte> bytes = new List<byte>();
+            foreach (short I16 in value)
+                bytes.AddRange(BitConverter.GetBytes(I16));
+            byte[] Return = new byte[bytes.Count];
+            bytes.CopyTo(Return, 0);
+            return Return;
+        }
+        /// <summary>
+        /// 将32位整形转换成字节数组,可传递任意数量的实参
+        /// </summary>
+        /// <param name="value">32位整形变量</param>
+        /// <returns></returns>
+        public static byte[] Int_Bytes(params int[] value)
+        {
+            List<byte> bytes = new List<byte>(256);
+            foreach (int I32 in value) bytes.AddRange(BitConverter.GetBytes(I32));
+            byte[] Return = new byte[bytes.Count];
+            bytes.CopyTo(Return, 0);
+            return Return;
+        }
+        /// <summary>
+        /// 将64位整形转换成字节数组,可传递任意数量的实参
+        /// </summary>
+        /// <param name="value">64位整形变量</param>
+        /// <returns></returns>
+        public static byte[] Long_Bytes(params long[] value)
+        {
+            List<byte> bytes = new List<byte>(256);
+            foreach (long I64 in value)
+                bytes.AddRange(BitConverter.GetBytes(I64));
+            byte[] Return = new byte[bytes.Count];
+            bytes.CopyTo(Return, 0);
+            return Return;
+        }
+        /// <summary>
+        /// 将字节数组(2个元素)转换成16位有符号整形
+        /// </summary>
+        /// <param name="value">字节数组,低字节在前</param>
+        /// <returns></returns>
+        public static short Bytes_Short(byte[] value)
+        {
+            if (value == null || value.Length != 2) throw new IndexOutOfRangeException("数组元素大小必须等于2");
+            return BitConverter.ToInt16(value, 0);
+        }
+        /// <summary>
+        /// 将2个字节转换成16位有符号整形
+        /// </summary>
+        /// <param name="lowbyte">低字节</param>
+        /// <param name="highbyte">高字节</param>
+        /// <returns></returns>
+        public static short Bytes_Short(byte lowbyte, byte highbyte)
+        {
+            byte[] value = new byte[2] { lowbyte, highbyte };
+            return BitConverter.ToInt16(value, 0);
+        }
+        /// <summary>
+        /// 将字节数组(4个元素)转换成32位有符号整形
+        /// </summary>
+        /// <param name="value">字节数组,低字节在前</param>
+        /// <returns></returns>
+        public static int Bytes_Int(byte[] value)
+        {
+            if (value == null || value.Length != 4) throw new IndexOutOfRangeException("数组元素大小必须等于4");
+            return BitConverter.ToInt32(value, 0);
+        }
+        /// <summary>
+        /// 将4个字节转换成32位有符号整形
+        /// </summary>
+        /// <param name="lowbyte">低字节</param>
+        /// <param name="secondbyte">第二字节</param>
+        /// <param name="thirdbyte">第三字节</param>
+        /// <param name="highbyte">高字节</param>
+        /// <returns></returns>
+        public static int Bytes_Int(byte lowbyte, byte secondbyte, byte thirdbyte, byte highbyte)
+        {
+            byte[] value = new byte[4] { lowbyte, secondbyte, thirdbyte, highbyte };
+            return BitConverter.ToInt32(value, 0);
+        }
+        /// <summary>
+        /// 将字节数组(8个元素)转换成64位有符号整形
+        /// </summary>
+        /// <param name="value">字节数组,低字节在前</param>
+        /// <returns></returns>
+        public static long Bytes_Long(byte[] value)
+        {
+            if (value == null || value.Length != 8) throw new IndexOutOfRangeException("数组元素大小必须等于8");
+            return BitConverter.ToInt64(value, 0);
+        }
+        /// <summary>
+        /// 将8个字节转换成64位有符号整形
+        /// </summary>
+        /// <param name="lowbyte">低字节</param>
+        /// <param name="second">第二字节</param>
+        /// <param name="third">第三字节</param>
+        /// <param name="fourth">第四字节</param>
+        /// <param name="fifth">第五字节</param>
+        /// <param name="sixth">第六字节</param>
+        /// <param name="seventh">第七字节</param>
+        /// <param name="highbyte">高字节</param>
+        /// <returns></returns>
+        public static long Bytes_Long(byte lowbyte, byte second, byte third, byte fourth, byte fifth, byte sixth, byte seventh, byte highbyte)
+        {
+            byte[] value = new byte[8] { lowbyte, second, third, fourth, fifth, sixth, seventh, highbyte };
+            return BitConverter.ToInt64(value, 0);
+        }
+        /// <summary>
+        /// 将32位浮点数转换成字节数组,可传递任意数量的实参
+        /// </summary>
+        /// <param name="value">32位浮点数变量</param>
+        /// <returns></returns>
+        public static byte[] Float_Bytes(params float[] value)
+        {
+            List<byte> bytes = new List<byte>(256);
+            foreach (float F32 in value) bytes.AddRange(BitConverter.GetBytes(F32));
+            byte[] Return = new byte[bytes.Count];
+            bytes.CopyTo(Return, 0);
+            return Return;
+        }
+        /// <summary>
+        /// 将字节数组(4个元素)转换成32位浮点数
+        /// </summary>
+        /// <param name="value">字节数组,低字节在前</param>
+        /// <returns></returns>
+        public static float Bytes_Float(byte[] value)
+        {
+            if (value == null || value.Length != 4) throw new IndexOutOfRangeException("数组元素大小必须等于4");
+            return BitConverter.ToSingle(value, 0);
+        }
+        /// <summary>
+        /// 将64位浮点数转换成字节数组,可传递任意数量的实参
+        /// </summary>
+        /// <param name="value">64位浮点数变量</param>
+        /// <returns></returns>
+        public static byte[] Double_Bytes(params double[] value)
+        {
+            List<byte> bytes = new List<byte>(256);
+            foreach (double F64 in value) bytes.AddRange(BitConverter.GetBytes(F64));
+            byte[] Return = new byte[bytes.Count];
+            bytes.CopyTo(Return, 0);
+            return Return;
+        }
+        /// <summary>
+        /// 将字节数组(8个元素)转换成64位浮点数
+        /// </summary>
+        /// <param name="value">字节数组,低字节在前</param>
+        /// <returns></returns>
+        public static double Bytes_Double(byte[] value)
+        {
+            if (value == null || value.Length != 8) throw new IndexOutOfRangeException("数组元素大小必须等于8");
+            return BitConverter.ToDouble(value, 0);
+        }
+        /// <summary>
+        /// 将bool数组(8个元素)转换成字节型
+        /// </summary>
+        /// <param name="value">bool数组</param>
+        /// <returns></returns>
+        public static byte Bools_Byte(bool[] value)
+        {
+            if (value.Length != 8) throw new IndexOutOfRangeException("数组元素大小必须等于8");
+            byte Return = 0;
+            foreach (bool a in value)
+            {
+                Return <<= 1;
+                Return = a ? Return |= 1 : Return |= 0;
+            }
+            return Return;
+        }
+        /// <summary>
+        /// 将bool数组(16个元素)转换成16位整形
+        /// </summary>
+        /// <param name="value">bool数组</param>
+        /// <returns></returns>
+        public static short Bools_Short(bool[] value)
+        {
+            if (value.Length != 16) throw new IndexOutOfRangeException("数组元素大小必须等于16");
+            short Return = 0;
+            foreach (bool a in value)
+            {
+                Return <<= 1;
+                Return = a ? Return |= 1 : Return |= 0;
+            }
+            return Return;
+        }
+        /// <summary>
+        /// 将bool数组(32个元素)转换成32位整形
+        /// </summary>
+        /// <param name="value">bool数组</param>
+        /// <returns></returns>
+        public static int Bools_Int(bool[] value)
+        {
+            if (value.Length != 32) throw new IndexOutOfRangeException("数组元素大小必须等于32");
+            int Return = 0;
+            foreach (bool a in value)
+            {
+                Return <<= 1;
+                Return = a ? Return |= 1 : Return |= 0;
+            }
+            return Return;
+        }
+        /// <summary>
+        /// 将字节变量转换成bool数组
+        /// </summary>
+        /// <param name="value">字节变量</param>
+        /// <returns></returns>
+        public static bool[] Byte_Bools(byte value)
+        {
+            bool[] Return = new bool[8];
+            for (int i = 0; i < 8; i++)
+            {
+                byte transit = value;
+                Return[i] = (transit &= 1) == 1 ? true : false;
+                value >>= 1;
+            }
+            return Return;
+        }
+        /// <summary>
+        /// 将16位无符号整形变量转换成bool数组
+        /// </summary>
+        /// <param name="value">16位无符号整形变量</param>
+        /// <returns></returns>
+        public static bool[] Short_Bools(short value)
+        {
+            bool[] Return = new bool[16];
+            for (int i = 0; i < 16; i++)
+            {
+                short transit = value;
+                Return[i] = (transit &= 1) == 1 ? true : false;
+                value >>= 1;
+            }
+            return Return;
+        }
+        /// <summary>
+        /// 将32位无符号整形变量转换成bool数组
+        /// </summary>
+        /// <param name="value">32位无符号整形变量</param>
+        /// <returns></returns>
+        public static bool[] Int_Bools(int value)
+        {
+            bool[] Return = new bool[32];
+            for (int i = 0; i < 32; i++)
+            {
+                int transit = value;
+                Return[i] = (transit &= 1) == 1 ? true : false;
+                value >>= 1;
+            }
+            return Return;
+        }
+        /// <summary>
+        /// 将任意长度的字符串转换成字节数组
+        /// </summary>
+        /// <param name="value">字符串</param>
+        /// <returns></returns>
+        public static byte[] Str_Bytes(string value)
+        {
+            if (value == null) throw new ArgumentNullException("字符串不能为空");
+            return Encoding.UTF8.GetBytes(value);
+        }
+        /// <summary>
+        /// 将单字符串转换成单字节
+        /// </summary>
+        /// <param name="value">字符串</param>
+        /// <returns></returns>
+        public static byte Str_Byte(string value)
+        {
+            if (value == null && value.Length == 1) throw new ArgumentNullException("字符串不能为空且长度必须为1");
+            return Encoding.UTF8.GetBytes(value)[0];
+        }
+        /// <summary>
+        /// 将任意长度的字节数组转换成字符串
+        /// </summary>
+        /// <param name="value">字节数组</param>
+        /// <returns></returns>
+        public static string Bytes_Str(byte[] value)
+        {
+            if (value == null) throw new ArgumentNullException("数组不能为空");
+            return Encoding.UTF8.GetString(value);
+        }
+        /// <summary>
+        /// 将16为整形变量转换成字符串
+        /// </summary>
+        /// <param name="value">16位整形变量数组</param>
+        /// <returns></returns>
+        public static string Shorts_Str(short[] value)
+        {
+            return Bytes_Str(Short_Bytes(value));
+        }
+        /// <summary>
+        /// 将单个bool变量转换成单个字符
+        /// </summary>
+        /// <param name="value">bool变量</param>
+        /// <returns>单字符</returns>
+        public static string Bool_Str(bool value)
+        {
+            if (value)  return "1";
+            else        return "0";
+        }
+        /// <summary>
+        /// 将bool数组转换成字符串
+        /// </summary>
+        /// <param name="value">bool数组</param>
+        /// <returns>字符串</returns>
+        public static string Bools_Str(bool[] value)
+        {
+            string Return = "";
+            foreach (bool a in value)
+            {
+                if (a)  Return += "1";
+                else    Return += "0";
+            }
+            return Return;
+        }
+        /// <summary>
+        /// 将字符串转换成16位整形数组
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static short[] Str_Shorts(string value)
+        {
+            List<byte> bytes = new List<byte>();
+            List<short> shorts = new List<short>();
+            bytes.AddRange(Str_Bytes(value));
+            while (bytes.Count > 0)
+            {
+                if (bytes.Count >= 2)
+                {
+                    shorts.Add(Bytes_Short(bytes[0], bytes[1]));
+                    bytes.RemoveAt(0); bytes.RemoveAt(0);
+                }
+                else
+                {
+                    shorts.Add(Bytes_Short(bytes[0], 0));
+                    bytes.Clear();
+                }
+            }
+            short[] Return = new short[shorts.Count];
+            shorts.CopyTo(Return, 0);
+            return Return;
+        }
+		 /// <summary>
+        /// 将字符串转换成16进制指节数组
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+		 public static byte[] Str_HexBytes(string hexString)
+        {
+            hexString = hexString.Replace(" ", "");
+            if ((hexString.Length % 2) != 0)
+                hexString += " ";
+            byte[] returnBytes = new byte[hexString.Length / 2];
+            for (int i = 0; i < returnBytes.Length; i++)
+                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Replace(" ", ""), 16);
+            return returnBytes;
+        }
+		 /// <summary>
+        /// 16进制显示
+        /// </summary>
+        /// <param name="bytes"></param>
+        /// <returns></returns>
+        public static string byte_HexStr(byte[] bytes)
+        {
+            string returnStr = "";
+            if (bytes != null)
+            {
+                for (int i = 0; i < bytes.Length; i++)
+                {
+                    returnStr += bytes[i].ToString("X2");
+
+                }
+            }
+            return returnStr;
+        }
+        /// <summary>
+        /// 判断字符串是否可以转换成无符号整数
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static bool JudgeInt(string value)
+        {
+            byte[] a = Str_Bytes(value);
+            if (a.Length > 0)
+            {
+                bool Return = true;
+                for (int i = 0; i < a.Length; i++)
+                {
+                    if (a[i] < 48 || a[i] > 57)
+                    {
+                        Return = false;
+                        break;
+                    }
+                }
+                return Return;
+            }
+            else return false;
+        }
+    }
+}

+ 205 - 0
MainForm/ClassFile/FALibraryClass/FileFunction.cs

@@ -0,0 +1,205 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace BZFAStandardLib
+{
+    /// <summary>
+    /// txt文件操作专用类
+    /// </summary>
+    public static class FileOperate
+    {
+        private static Mutex mutexNew = new Mutex();
+        private static Mutex mutexWrite = new Mutex();
+        /// <summary>
+        /// 新建文件,
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        public static void NewTxtFile(string txtFile)
+        {
+            string path = txtFile.Substring(0, txtFile.LastIndexOf("\\"));
+            if (!Directory.Exists(path)) Directory.CreateDirectory(path); //判断路径是否存在,不存在则创建
+            if (!File.Exists(txtFile))  //判断文件是否存在,不存在则创建
+            {
+                using (FileStream fileStream = new FileStream(txtFile, FileMode.Create, FileAccess.Write))
+                {
+                    fileStream.Close();
+                }
+            }
+
+        }
+
+        /// <summary>
+        /// 新建并写入txt文件;
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        /// <param name="txt">写入内容</param>
+        public static bool NewTxtFile(string txtFile, string txt)
+        {
+            string path = txtFile.Substring(0, txtFile.LastIndexOf("\\"));
+            if (!Directory.Exists(path)) Directory.CreateDirectory(path); //判断路径是否存在,不存在则创建
+            try
+            {
+                using (FileStream fileStream = new FileStream(txtFile, FileMode.Create, FileAccess.Write))  //创建写入文件
+                {
+                    StreamWriter streamWriter = new StreamWriter(fileStream);
+                    streamWriter.BaseStream.Seek(0, SeekOrigin.End);  //在txt末尾写入;
+                    streamWriter.Write(txt);      //写入txt文件内容;
+                    streamWriter.Flush();
+                    streamWriter.Close();
+                    fileStream.Close();
+                }
+                return true;
+            }
+            catch { return false; }
+        }
+        /// <summary>
+        /// 带锁
+        /// </summary>
+        /// <param name="txtFile"></param>
+        public static void NewFile(string file)
+        {
+            try
+            {
+                mutexNew.WaitOne();
+                string path = file.Substring(0, file.LastIndexOf("\\"));
+                if (!Directory.Exists(path)) Directory.CreateDirectory(path); //判断路径是否存在,不存在则创建
+                if (!File.Exists(file))  //判断文件是否存在,不存在则创建
+                {
+                    using (FileStream fileStream = new FileStream(file, FileMode.Create, FileAccess.Write))
+                    {
+                        fileStream.Close();
+                    }
+                }
+                mutexNew.ReleaseMutex();
+            }
+            catch (Exception ex)
+            {
+                mutexNew.ReleaseMutex();
+            }
+        }
+        /// <summary>
+        /// 写入txt文件;
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        /// <param name="txt">写入内容</param>
+        public static bool WriteTxtFile(string txtFile, string txt)
+        {
+            if (!File.Exists(txtFile)) NewTxtFile(txtFile); //判断文件是否存在,不存在则新建;
+            try
+            {
+                using (FileStream fileStream = new FileStream(txtFile, FileMode.Open, FileAccess.Write))    //写入文件
+                {
+                    StreamWriter streamWriter = new StreamWriter(fileStream);
+                    //sw.BaseStream的Position或Seek()可移动文件流指针到的任意位置;
+                    streamWriter.BaseStream.Seek(0, SeekOrigin.End);  //在txt末尾写入;
+                    streamWriter.Write(txt);      //写入txt文件内容;
+                    streamWriter.Flush();
+                    streamWriter.Close();
+                    fileStream.Close();
+                }
+                return true;
+            }
+            catch { return false; }
+        }
+        /// <summary>
+        /// 带锁
+        /// </summary>
+        /// <param name="txtFile"></param>
+        /// <param name="txt"></param>
+        public static void WriteFile(string file, string txt)
+        {
+            try
+            {
+                mutexWrite.WaitOne();
+                if (!File.Exists(file)) NewFile(file); //判断文件是否存在,不存在则新建;
+                using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Write))    //写入文件
+                {
+                    StreamWriter streamWriter = new StreamWriter(fileStream);
+                    //sw.BaseStream的Position或Seek()可移动文件流指针到的任意位置;
+                    streamWriter.BaseStream.Seek(0, SeekOrigin.End);  //在txt末尾写入;
+                    streamWriter.Write(txt);      //写入txt文件内容;
+                    streamWriter.Flush();
+                    streamWriter.Close();
+                    fileStream.Close();
+                }
+                mutexWrite.ReleaseMutex();
+            }
+            catch
+            {
+                mutexWrite.ReleaseMutex();
+            }
+        }
+
+        /// <summary>
+        /// 读取txt文件内容;
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        /// <returns>返回txt文件内容</returns>
+        public static string ReadTxtFile(string txtFile)
+        {
+            if (!File.Exists(txtFile)) return ""; //判断文件是否存在;
+            string Return = "";
+            using (FileStream fileStream = new FileStream(txtFile, FileMode.Open, FileAccess.Read))
+            {
+                StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8);
+                Return = streamReader.ReadToEnd().ToString();
+                streamReader.Close();
+                fileStream.Close();
+            }
+            return Return;
+        }
+
+        /// <summary>
+        /// 读取最后一行内容;
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        /// <returns></returns>
+        public static string ReadLastLine(string txtFile)
+        {
+            if (!File.Exists(txtFile)) return ""; //判断文件是否存在;
+            string[] allLines = File.ReadAllLines(txtFile);
+            if (allLines.Length > 0)
+                return allLines[allLines.Length - 1];
+            else return "";
+        }
+
+        /// <summary>
+        /// 覆盖最后一行内容;
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        /// <param name="txt"></param>
+        public static void CoverLastLine(string txtFile, string txt)
+        {
+            if (File.Exists(txtFile))  //判断文件是否存在;
+            {
+                string[] allLines = File.ReadAllLines(txtFile);
+                if (allLines.Length > 0)
+                {
+                    allLines[allLines.Length - 1] = txt;
+                    File.WriteAllLines(txtFile, allLines);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 移除最后一行内容;
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        public static void RemoveLastLine(string txtFile)
+        {
+            if (File.Exists(txtFile))  //判断文件是否存在
+            {
+                string[] allLines = File.ReadAllLines(txtFile);
+                if (allLines.Length > 0)
+                {
+                    Array.Resize(ref allLines, allLines.Length - 1);
+                    File.WriteAllLines(txtFile, allLines);
+                }
+            }
+        }
+    }
+}

+ 64 - 0
MainForm/ClassFile/FALibraryClass/FormAutoScaling.cs

@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace StandardLibrary
+{
+    class AutoResize
+    {
+        private float defaultX = 0;//窗体初始宽度
+        private float defaultY = 0;//窗体初始高度
+
+        Control parentControl = new Control();
+
+        public void SetAutoResize(Control cons)
+        {
+            this.defaultX = cons.Width;
+            this.defaultY = cons.Height;
+            parentControl = cons;
+            SetControlTag(cons);
+            cons.Resize += ControlAutoResize;
+        }
+
+        private void SetControlTag(Control cons)
+        {
+            foreach (Control con in cons.Controls)
+            {   //设置控件Tag属性的数据位{控件宽度:控件高度:容器左边距离:容器右边距离:文字大小}
+                con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
+                if (con.Controls.Count > 0)
+                    SetControlTag(con);
+            }
+        }
+
+        private void SetControlsAutoScaling(float newx, float newy, Control cons)
+        {
+            foreach (Control con in cons.Controls)
+            {
+                if (con.Tag == null) continue;//防止动态添加的控件(动态添加的控件没有设置Tag)
+                string[] mytag = con.Tag.ToString().Split(':');//分割控件的Tag属性值
+                float controlTags = 0;
+                controlTags = Convert.ToSingle(mytag[0]) * newx;
+                con.Width = (int)controlTags;
+                controlTags = Convert.ToSingle(mytag[1]) * newy;
+                con.Height = (int)(controlTags);
+                controlTags = Convert.ToSingle(mytag[2]) * newx;
+                con.Left = (int)(controlTags);
+                controlTags = Convert.ToSingle(mytag[3]) * newy;
+                con.Top = (int)(controlTags);
+                Single currentSize = Convert.ToSingle(mytag[4]) * Math.Min(newx, newy);
+                con.Font = new System.Drawing.Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
+                if (con.Controls.Count > 0) SetControlsAutoScaling(newx, newy, con);
+            }
+        }
+
+        private void ControlAutoResize(object sender, EventArgs e)
+        {
+            float newx = parentControl.Width / defaultX;//获取窗体宽度变化前后大小的比值
+            float newy = parentControl.Height / defaultY;//获取窗体高度变化前后大小的比值
+            SetControlsAutoScaling(newx, newy, parentControl);
+        }
+    }
+}

+ 336 - 0
MainForm/ClassFile/FALibraryClass/IniFunction.cs

@@ -0,0 +1,336 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.IO;
+
+namespace StandardLibrary
+{
+    /// <summary>
+    /// INI文件操作专用类
+    /// </summary>
+    static class IniFile
+    {
+        #region API声明  
+        /// <summary>  
+        /// 获取所有段落名称
+        /// </summary>  
+        /// <param name="lpszReturnBuffer">存放段落名称的内存地址,每个段落之间用\0分隔</param>  
+        /// <param name="nSize">内存大小(characters)</param>  
+        /// <param name="lpFileName">Ini文件</param>  
+        /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>  
+        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+        private static extern uint GetPrivateProfileSectionNames(
+            IntPtr lpszReturnBuffer, 
+            uint nSize, 
+            string lpFileName
+        );
+        /// <summary>  
+        /// 获取某个指定段落中所有KEY和Value  
+        /// </summary>  
+        /// <param name="lpAppName">段落名称</param>  
+        /// <param name="lpReturnedString">返回值的内存地址,每个之间用\0分隔</param>  
+        /// <param name="nSize">内存大小(characters)</param>  
+        /// <param name="lpFileName">Ini文件</param>  
+        /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>  
+        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+        private static extern uint GetPrivateProfileSection(
+            string lpAppName, 
+            IntPtr lpReturnedString, 
+            uint nSize, 
+            string lpFileName
+        );
+        /// <summary>  
+        /// 读取INI文件中指定的Key的值  
+        /// </summary>  
+        /// <param name="lpAppName">段落名称。如果为null,则读取INI中所有段落名称,每个节点名称之间用\0分隔</param>  
+        /// <param name="lpKeyName">Key名称。如果为null,则读取INI中指定段落中的所有KEY,每个KEY之间用\0分隔</param>  
+        /// <param name="lpDefault">读取失败时的默认值</param>  
+        /// <param name="lpReturnedString">读取的内容缓冲区,读取之后,多余的地方使用\0填充</param>  
+        /// <param name="nSize">内容缓冲区的长度</param>  
+        /// <param name="lpFileName">INI文件名</param>  
+        /// <returns>实际读取到的长度</returns>  
+        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+        private static extern uint GetPrivateProfileString(
+            string lpAppName, 
+            string lpKeyName, 
+            string lpDefault, 
+            [In, Out] char[] lpReturnedString, 
+            uint nSize, 
+            string lpFileName
+        );
+        //另一种声明方式,使用 StringBuilder 作为缓冲区类型的缺点是不能接受\0字符,会将\0及其后的字符截断,  
+        //所以对于lpAppName或lpKeyName为null的情况就不适用  
+        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+        private static extern uint GetPrivateProfileString(
+            string lpAppName, 
+            string lpKeyName, 
+            string lpDefault, 
+            StringBuilder lpReturnedString, 
+            uint nSize, 
+            string lpFileName
+        );
+        //再一种声明,使用string作为缓冲区的类型同char[]  
+        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+        private static extern uint GetPrivateProfileString(
+            string lpAppName, 
+            string lpKeyName, 
+            string lpDefault, 
+            string lpReturnedString, 
+            uint nSize, 
+            string lpFileName
+        );
+        /// <summary>  
+        /// 将指定的键值对写到指定的段落,如果已经存在则替换。  
+        /// </summary>  
+        /// <param name="lpAppName">段落,如果不存在此段落,则创建此段落</param>  
+        /// <param name="lpString">Item键值对,多个用\0分隔,形如key1=value1\0key2=value2  
+        /// <para>如果为string.Empty,则删除指定段落下的所有内容,保留段落</para>  
+        /// <para>如果为null,则删除指定段落下的所有内容,并且删除该段落</para>  
+        /// </param>  
+        /// <param name="lpFileName">INI文件</param>  
+        /// <returns>是否成功写入</returns>  
+        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+        [return: MarshalAs(UnmanagedType.Bool)]     //可以没有此行  
+        private static extern bool WritePrivateProfileSection(
+            string lpAppName, 
+            string lpString, 
+            string lpFileName
+        );
+        /// <summary>  
+        /// 将指定的键和值写到指定的段落,如果已经存在则替换  
+        /// </summary>  
+        /// <param name="lpAppName">段落名称</param>  
+        /// <param name="lpKeyName">键名称。如果为null,则删除指定的段落及其所有的项目</param>  
+        /// <param name="lpString">值内容。如果为null,则删除指定段落中指定的键。</param>  
+        /// <param name="lpFileName">INI文件</param>  
+        /// <returns>操作是否成功</returns>  
+        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        private static extern bool WritePrivateProfileString(
+            string lpAppName, 
+            string lpKeyName, 
+            string lpString, 
+            string lpFileName
+        );
+        #endregion
+
+        #region 封装
+        /// <summary>  
+        /// 读取INI文件中的所有段落名称 
+        /// </summary>  
+        /// <param name="iniFile">Ini文件</param>  
+        /// <returns>所有段落,没有内容返回string[0]</returns>  
+        public static string[] INIGetAllSectionNames(string iniFile)
+        {
+            uint MAX_BUFFER = 32767;    //默认为32767
+            string[] sections = new string[0];      //返回值  
+            //申请内存  
+            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
+            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, iniFile);
+            if (bytesReturned != 0)
+            {
+                //读取指定内存的内容  
+                string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
+                //每个段落之间用\0分隔,末尾有一个\0  
+                sections = local.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
+            }
+            //释放内存  
+            Marshal.FreeCoTaskMem(pReturnedString);
+            return sections;
+        }
+        /// <summary>  
+        /// 获取INI文件中指定段落中的所有条目(key=value形式)  
+        /// </summary>  
+        /// <param name="iniFile">Ini文件</param>  
+        /// <param name="section">段落名称</param>  
+        /// <returns>指定段落中的所有条目,没有内容返回string[0]</returns>  
+        public static string[] INIGetAllItems(string iniFile, string section)
+        {
+            //返回值形式为 key=value,例如 Color=Red  
+            uint MAX_BUFFER = 32767;    //默认为32767  
+            string[] items = new string[0];      //返回值  
+            //分配内存  
+            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
+            uint bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, iniFile);
+            if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
+            {
+                string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);
+                items = returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
+            }
+            Marshal.FreeCoTaskMem(pReturnedString);     //释放内存  
+            return items;
+        }
+        /// <summary>  
+        /// 获取INI文件中指定段落中的所有条目的Key列表  
+        /// </summary>  
+        /// <param name="iniFile">Ini文件</param>  
+        /// <param name="section">段落名称</param>  
+        /// <returns>如果没有内容,反回string[0]</returns>  
+        public static string[] INIGetAllItemKeys(string iniFile, string section)
+        {
+            string[] value = new string[0];
+            const int SIZE = 1024 * 10;
+            if (string.IsNullOrEmpty(section))
+            {
+                throw new ArgumentException("必须指定段落名称", "section");
+            }
+            char[] chars = new char[SIZE];
+            uint bytesReturned = GetPrivateProfileString(section, null, null, chars, SIZE, iniFile);
+            if (bytesReturned != 0)
+            {
+                value = new string(chars).Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
+            }
+            chars = null;
+            return value;
+        }
+        /// <summary>  
+        /// 读取INI文件中指定KEY的字符串型值  
+        /// </summary>  
+        /// <param name="iniFile">Ini文件</param>  
+        /// <param name="section">段落名称</param>  
+        /// <param name="key">键名称</param>  
+        /// <param name="defaultValue">如果没此KEY所使用的默认值</param>  
+        /// <returns>读取到的值</returns>  
+        public static string INIGetStringValue(string iniFile, string section, string key, string defaultValue)
+        {
+            string value = defaultValue;
+            const int SIZE = 1024 * 10;
+            if (string.IsNullOrEmpty(section))
+            {
+                throw new ArgumentException("必须指定段落名称", "section");
+            }
+            if (string.IsNullOrEmpty(key))
+            {
+                throw new ArgumentException("必须指定键名称", "key");
+            }
+            StringBuilder sb = new StringBuilder(SIZE);
+            uint bytesReturned = GetPrivateProfileString(section, key, defaultValue, sb, SIZE, iniFile);
+            if (bytesReturned != 0)
+            {
+                value = sb.ToString();
+            }
+            sb = null;
+            return value;
+        }
+        /// <summary>  
+        /// 在INI文件中,将指定的键值对写到指定的段落,如果已经存在则替换  
+        /// </summary>  
+        /// <param name="iniFile">INI文件</param>  
+        /// <param name="section">段落,如果不存在此段落,则创建此段落</param>  
+        /// <param name="items">键值对,多个用\0分隔,形如key1=value1\0key2=value2</param>  
+        /// <returns></returns>  
+        public static bool INIWriteItems(string iniFile, string section, string items)
+        {
+            if (string.IsNullOrEmpty(section))
+            {
+                throw new ArgumentException("必须指定段落名称", "section");
+            }
+
+            if (string.IsNullOrEmpty(items))
+            {
+                throw new ArgumentException("必须指定键值对", "items");
+            }
+            string filePath = iniFile.Remove(iniFile.LastIndexOf("\\"));
+            if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
+            return WritePrivateProfileSection(section, items, iniFile);
+        }
+        /// <summary>  
+        /// 在INI文件中,指定段落写入指定的键及值。如果已经存在,则替换。如果没有则创建。  
+        /// </summary>  
+        /// <param name="iniFile">INI文件</param>  
+        /// <param name="section">段落</param>  
+        /// <param name="key">键</param>  
+        /// <param name="value">值</param>  
+        /// <returns>操作是否成功</returns>  
+        public static bool INIWriteValue(string iniFile, string section, string key, string value)
+        {
+            if (string.IsNullOrEmpty(section))
+            {
+                throw new ArgumentException("必须指定段落名称", "section");
+            }
+            if (string.IsNullOrEmpty(key))
+            {
+                throw new ArgumentException("必须指定键名称", "key");
+            }
+            if (value == null)
+            {
+                throw new ArgumentException("值不能为null", "value");
+            }
+            string filePath = iniFile.Remove(iniFile.LastIndexOf("\\"));
+            if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
+            return WritePrivateProfileString(section, key, value, iniFile);
+        }
+        /// <summary>  
+        /// 在INI文件中,删除指定段落中的指定的键。  
+        /// </summary>  
+        /// <param name="iniFile">INI文件</param>  
+        /// <param name="section">段落</param>  
+        /// <param name="key">键</param>  
+        /// <returns>操作是否成功</returns>  
+        public static bool INIDeleteKey(string iniFile, string section, string key)
+        {
+            if (string.IsNullOrEmpty(section))
+            {
+                throw new ArgumentException("必须指定段落名称", "section");
+            }
+
+            if (string.IsNullOrEmpty(key))
+            {
+                throw new ArgumentException("必须指定键名称", "key");
+            }
+            return WritePrivateProfileString(section, key, null, iniFile);
+        }
+        /// <summary>  
+        /// 在INI文件中,删除指定的段落。  
+        /// </summary>  
+        /// <param name="iniFile">INI文件</param>  
+        /// <param name="section">段落</param>  
+        /// <returns>操作是否成功</returns>  
+        public static bool INIDeleteSection(string iniFile, string section)
+        {
+            if (string.IsNullOrEmpty(section))
+            {
+                throw new ArgumentException("必须指定段落名称", "section");
+            }
+
+            return WritePrivateProfileString(section, null, null, iniFile);
+        }
+        /// <summary>  
+        /// 在INI文件中,删除指定段落中的所有内容。  
+        /// </summary>  
+        /// <param name="iniFile">INI文件</param>  
+        /// <param name="section">段落</param>  
+        /// <returns>操作是否成功</returns>  
+        public static bool INIEmptySection(string iniFile, string section)
+        {
+            if (string.IsNullOrEmpty(section))
+            {
+                throw new ArgumentException("必须指定段落名称", "section");
+            }
+            return WritePrivateProfileSection(section, string.Empty, iniFile);
+        }
+
+        /// <summary>
+        /// 在INI文件中,删除所有段落
+        /// </summary>
+        /// <param name="iniFile">INI文件</param>
+        public static bool INIDeleteAll(string iniFile)
+        {
+            try
+            {
+                string[] section = INIGetAllSectionNames(iniFile);
+
+                for (int i = 0; i < section.Length; i++)
+                {
+                    INIDeleteSection(iniFile, section[i]);
+                }
+                return true;
+            }
+            catch { return false; }
+        }
+        #endregion
+    }
+}

+ 482 - 0
MainForm/ClassFile/FALibraryClass/InovancePLC.cs

@@ -0,0 +1,482 @@
+using System.Runtime.InteropServices;
+
+namespace MainForm
+{
+    class InovancePlc
+    { 
+        /// <summary>
+        /// H3U 软元件
+        /// </summary>
+        public enum Soft
+        {
+            REGI_H3U_Y = 0x20,      //Y元件的定义	
+            REGI_H3U_X = 0x21,      //X元件的定义							
+            REGI_H3U_S = 0x22,      //S元件的定义				
+            REGI_H3U_M = 0x23,      //M元件的定义							
+            REGI_H3U_TB = 0x24,     //T位元件的定义				
+            REGI_H3U_TW = 0x25,     //T字元件的定义				
+            REGI_H3U_CB = 0x26,     //C位元件的定义				
+            REGI_H3U_CW = 0x27,     //C字元件的定义				
+            REGI_H3U_DW = 0x28,     //D字元件的定义				
+            REGI_H3U_CW2 = 0x29,    //C双字元件的定义
+            REGI_H3U_SM = 0x2a,     //SM
+            REGI_H3U_SD = 0x2b,     //
+            REGI_H3U_R = 0x2c,       //
+
+                    //H5u
+            REGI_H5U_Y = 0x30,       //Y元件的定义	
+            REGI_H5U_X = 0x31,      //X元件的定义							
+            REGI_H5U_S = 0x32,      //S元件的定义				
+            REGI_H5U_M = 0x33,      //M元件的定义	
+            REGI_H5U_B = 0x34,       //B元件的定义
+            REGI_H5U_D = 0x35,       //D字元件的定义
+            REGI_H5U_R = 0x36,       //R字元件的定义
+        }
+
+        #region 声明
+        /// <summary>
+        /// 创建网络连接
+        /// </summary>
+        /// <param name="sIpAddr">以太网IP地址</param>
+        /// <param name="nNetId">网络链接编号,用于标记是第几条网络链接,取值范围0~255,默认0 </param>
+        /// <param name="IpPort">以太网端口号,默认502(modbusTcp协议默认端口号为502)</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "Init_ETH_String", CallingConvention = CallingConvention.Cdecl)]
+        public static extern bool Init_ETH_String(string sIpAddr, int nNetId = 0, int IpPort = 502);
+
+        /// <summary>
+        /// 关闭网络连接 
+        /// </summary>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "Exit_ETH", CallingConvention = CallingConvention.Cdecl)]
+        private static extern bool Exit_ETH(int nNetId = 0);
+
+        /// <summary>
+        /// 写入位状态(X,Y,M,C,T等软元件)
+        /// 注意 : X和Y元件地址需为8进制; 
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始位置</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">写入的数据数组,byte=0关闭软元件,byte=1打开软元件</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Write_Soft_Elem", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Write_Soft_Elem_Bit(Soft eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 写入16位有符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始位置</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">写入的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Write_Soft_Elem_Int16", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Write_Soft_Elem_Int16(Soft eType, int nStartAddr, int nCount, short[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 写入32位有符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始位置</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">写入的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Write_Soft_Elem_Int32", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Write_Soft_Elem_Int32(Soft eType, int nStartAddr, int nCount, int[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 写入16位无符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始位置</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">写入的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Write_Soft_Elem_UInt16", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Write_Soft_Elem_UInt16(Soft eType, int nStartAddr, int nCount, ushort[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 写入32位无符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始位置</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">写入的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Write_Soft_Elem_UInt32", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Write_Soft_Elem_UInt32(Soft eType, int nStartAddr, int nCount, uint[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 写入32位浮点数
+        /// </summary>
+        /// <param name="eType"></param>
+        /// <param name="nStartAddr"></param>
+        /// <param name="nCount"></param>
+        /// <param name="pValue"></param>
+        /// <param name="nNetId"></param>
+        /// <returns></returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Write_Soft_Elem_Float", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Write_Soft_Elem_Float(Soft eType, int nStartAddr, int nCount, float[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 读取位状态(X,Y,M,C,T等软元件)
+        /// 注意 : X和Y元件地址需为8进制; 
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始地址</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">读取的软元件状态数组,byte=0为关闭,byte=1为打开</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Read_Soft_Elem", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Read_Soft_Elem_Bit(Soft eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 读取16位有符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始地址</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">读取的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Read_Soft_Elem_Int16", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Read_Soft_Elem_Int16(Soft eType, int nStartAddr, int nCount, short[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 读取32位有符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始地址</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">读取的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Read_Soft_Elem_Int32", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Read_Soft_Elem_Int32(Soft eType, int nStartAddr, int nCount, int[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 读取16位无符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始地址</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">读取的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Read_Soft_Elem_UInt16", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Read_Soft_Elem_UInt16(Soft eType, int nStartAddr, int nCount, ushort[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 读取32位无符号整形
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始地址</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">读取的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Read_Soft_Elem_UInt32", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Read_Soft_Elem_UInt32(Soft eType, int nStartAddr, int nCount, uint[] pValue, int nNetId = 0);
+
+        /// <summary>
+        /// 读取32位浮点数
+        /// </summary>
+        /// <param name="eType">软元件类型,使用SoftElemType枚举</param>
+        /// <param name="nStartAddr">软元件起始地址</param>
+        /// <param name="nCount">软元件个数</param>
+        /// <param name="pValue">读取的数据数组</param>
+        /// <param name="nNetId">网络链接编号,与Init_ETH()调用的ID一样</param>
+        /// <returns>1 成功  0 失败</returns>
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H3u_Read_Soft_Elem_Float", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int H3u_Read_Soft_Elem_Float(Soft eType, int nStartAddr, int nCount, float[] pValue, int nNetId = 0);
+
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H5u_Write_Soft_Elem", CallingConvention = CallingConvention.Cdecl)]
+        public static extern int H5u_Write_Soft_Elem(Soft eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0);
+        [DllImport("StandardModbusApi.dll", EntryPoint = "H5u_Read_Device_Block", CallingConvention = CallingConvention.Cdecl)]
+        public static extern int H5u_Read_Device_Block(Soft eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0);
+        #endregion
+
+        #region 字段
+        // PLC 编号
+        private int _card = 0;   
+        /// <summary>
+        /// 获取或设置PLC的编号
+        /// </summary>
+        public int Card
+        {
+            get { return _card; }
+            set { _card = value; }
+        }
+
+        // PLC IP地址
+        private string _ip = "192.168.1.89";
+        /// <summary>
+        /// 获取或设置PLC的IP地址
+        /// </summary>
+        public string IP
+        {
+            get { return _ip; }
+            set { _ip = value; }
+        }
+
+        // PLC 端口号
+        private int _port = 502;
+        /// <summary>
+        /// 获取或设置PLC的端口号
+        /// </summary>
+        public int Port
+        {
+            get { return _port; }
+            set { _port = value; }
+        }
+
+        // 打开状态
+        private bool _openStatus = false;
+        /// <summary>
+        /// 获取PLC的打开状态
+        /// </summary>
+        public bool OpenStatus
+        {
+            get { return _openStatus; }
+        }
+        #endregion
+
+        #region 公有字段
+        #endregion
+
+        /// <summary>
+        /// 构造函数,设置PLC的编号、IP、端口属性
+        /// </summary>
+        /// <param name="card">PLC 编号</param>
+        /// <param name="ip">PLC IP地址</param>
+        /// <param name="port">PLC 端口号</param>
+        public InovancePlc(int card, string ip, int port)
+        {
+            this._card = card;
+            this._ip = ip;
+            this._port = port;
+        }
+
+        #region 封装
+        /// <summary>
+        /// 打开连接
+        /// </summary>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool Open()
+        {
+            if (!_openStatus)
+            {
+                _openStatus = Init_ETH_String(_ip, _card, _port);
+                return _openStatus;
+            }
+            else
+                return true;
+        }
+
+        /// <summary>
+        /// 关闭连接
+        /// </summary>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool Close()
+        {
+            _openStatus = false;
+            return Exit_ETH(_card);
+        }
+
+        /// <summary>
+        /// 写入位状态(位寄存器)
+        /// 注意 : X和Y元件地址需为8进制
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="writeData">写入的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Write_Bit(Soft softName, int softNum, int softCount, bool[] writeData)
+        {
+            byte[] data = new byte[writeData.Length];
+            for (int i = 0; i < writeData.Length; i++)
+            {
+                data[i] = writeData[i] == true ? (byte)1 : (byte)0;
+            }
+            int rtn = H3u_Write_Soft_Elem_Bit(softName, softNum, softCount, data, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 写入16位有符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="writeData">写入的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Write_Int16(Soft softName, int softNum, int softCount, short[] writeData)
+        {
+            int rtn = H3u_Write_Soft_Elem_Int16(softName, softNum, softCount, writeData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 写入16位无符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="writeData">写入的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Write_UInt16(Soft softName, int softNum, int softCount, ushort[] writeData)
+        {
+            int rtn = H3u_Write_Soft_Elem_UInt16(softName, softNum, softCount, writeData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 写入32位有符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="writeData">写入的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Write_Int32(Soft softName, int softNum, int softCount, int[] writeData)
+        {
+            int count = softCount * 2;
+            int rtn = H3u_Write_Soft_Elem_Int32(softName, softNum, count, writeData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 写入32位无符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="writeData">写入的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Write_UInt32(Soft softName, int softNum, int softCount, uint[] writeData)
+        {
+            int count = softCount * 2;
+            int rtn = H3u_Write_Soft_Elem_UInt32(softName, softNum, count, writeData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 写入32位浮点型
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="writeData">写入的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Write_Float(Soft softName, int softNum, int softCount, float[] writeData)
+        {
+            int count = softCount * 2;
+            int rtn = H3u_Write_Soft_Elem_Float(softName, softNum, count, writeData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 读取位状态(位寄存器)
+        /// 注意 : X和Y元件地址需为8进制
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="readData">读取的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Read_Bit(Soft softName, int softNum, int softCount, ref bool[] readData)
+        {
+            byte[] data = new byte[readData.Length];
+            int rtn = H3u_Read_Soft_Elem_Bit(softName, softNum, softCount, data, _card);
+            for (int i = 0; i < readData.Length; i++)
+            {
+                readData[i] = data[i] == 1 ? true : false;
+            }
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 读取16位有符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="readData">读取的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Read_Int16(Soft softName, int softNum, int softCount, ref short[] readData)
+        {
+            int rtn = H3u_Read_Soft_Elem_Int16(softName, softNum, softCount, readData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 读取16位无符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="readData">读取的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Read_UInt16(Soft softName, int softNum, int softCount, ref ushort[] readData)
+        {
+            int rtn = H3u_Read_Soft_Elem_UInt16(softName, softNum, softCount, readData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 读取32位有符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="readData">读取的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Read_Int32(Soft softName, int softNum, int softCount, ref int[] readData)
+        {
+            int count = softCount * 2;
+            int rtn = H3u_Read_Soft_Elem_Int32(softName, softNum, count, readData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 读取32位无符号整形
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="readData">读取的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Read_UInt32(Soft softName, int softNum, int softCount, ref uint[] readData)
+        {
+            int count = softCount * 2;
+            int rtn = H3u_Read_Soft_Elem_UInt32(softName, softNum, count, readData, _card);
+            return rtn == 1 ? true : false;
+        }
+
+        /// <summary>
+        /// 读取32位有符号浮点型
+        /// </summary>
+        /// <param name="softName">软元件类型</param>
+        /// <param name="softNum">起始软元件编号</param>
+        /// <param name="softCount">软元件数量</param>
+        /// <param name="readData">读取的数据</param>
+        /// <returns>TRUE 成功  FALSE 失败</returns>
+        public bool H3u_Read_Float(Soft softName, int softNum, int softCount, ref float[] readData)
+        {
+            int count = softCount * 2;
+            int rtn = H3u_Read_Soft_Elem_Float(softName, softNum, count, readData, _card);
+            return rtn == 1 ? true : false;
+        }
+        #endregion
+    }
+}
+

+ 97 - 0
MainForm/ClassFile/FALibraryClass/IsStrLegal.cs

@@ -0,0 +1,97 @@
+using System.Text.RegularExpressions;
+
+namespace MainForm
+{
+    /// <summary>
+    /// 判断字符串格式是否合法类
+    /// </summary>
+    class IsStrLegal
+    {
+        /// <summary>
+        /// 判断字符串是否只包含汉字
+        /// </summary>
+        /// <param name="input">字符串</param>
+        /// <returns></returns>
+        public static bool IsChineseCh(string input)
+        {
+            string pattern = @"^[\u4E00-\u9FA5]+$";
+            Regex regex = new Regex(pattern);
+            return regex.IsMatch(input);
+        }
+
+        /// <summary>   
+        /// 判断字符串是否只包含英文字母   
+        /// </summary>   
+        /// <param name="input"></param>   
+        /// <returns></returns>   
+        public static bool IsEnglisCh(string input)
+        {
+            string pattern = @"^[A-Z]|[a-z]+$";
+            Regex regex = new Regex(pattern);
+            return regex.IsMatch(input);
+        }
+
+        /// <summary>
+        /// 判断字符串是否只包含整数或浮点数
+        /// </summary>
+        /// <param name="input">字符串</param>
+        /// <returns></returns>
+        public static bool IsNumber(string input)
+        {
+            string pattern = @"^-?\d+$|^(-?\d+)(\.\d+)?$";
+            Regex regex = new Regex(pattern);
+            return regex.IsMatch(input);
+        }
+
+        /// <summary>
+        /// 判断字符串是否只包含正整数或正浮点数
+        /// </summary>
+        /// <param name="input">字符串</param>
+        /// <returns></returns>
+        public static bool IsUNumber(string input)
+        {
+            string pattern = @"^([0-9]\d*)(\.\d+)?$";
+            Regex regex = new Regex(pattern);
+            return regex.IsMatch(input);
+        }
+
+        /// <summary>
+        /// 判断字符串是否只包含整数
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public static bool IsInteger(string input)
+        {
+            string pattern = @"^-?\d+$|^(-?\d+)?$";
+            Regex regex = new Regex(pattern);
+            return regex.IsMatch(input);
+        }
+
+        /// <summary>   
+        /// 判断字符串是否只包含正整数
+        /// </summary>   
+        /// <param name="input">字符串</param>   
+        /// <returns></returns>   
+        public static bool IsUInteger(string input)
+        {
+            string pattern = @"^\d+$";
+            Regex regex = new Regex(pattern);
+            return regex.IsMatch(input);
+        }
+
+        /// <summary>
+        /// 是否为合法的XML元素节点名称
+        /// </summary>
+        /// <param name="pointName">点位名称</param>
+        /// <returns></returns>
+        public static bool IsNodeName(string pointName)
+        {
+            string RegexStr1 = @"[a-z]|[A-Z]|[_]|[\u4E00-\u9FA5]";  //名称的开头必须是字母、汉字或下划线“_”;
+            string RegexStr2 = @"^[\w-.]+$";    //名称的字符串只能包含字母,数字,下划线“_”,“-”,“.”;
+            bool result1 = Regex.IsMatch(pointName.Substring(0, 1), RegexStr1);//判断名称的开头
+            bool result2 = Regex.IsMatch(pointName, RegexStr2); //判断名称整体
+            if (result1 && result2) return true;
+            else return false;
+        }
+    }
+}

+ 83 - 0
MainForm/ClassFile/FALibraryClass/LogMgr.cs

@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace StandardLibrary
+{
+    //报警弹窗+运行Log
+    public class LogMgr : SingletonTemplate<LogMgr>
+    {
+        private bool errShow = false;
+        //运行
+        public void WriteRunLog(string message)
+        {
+            string filePath = AppDomain.CurrentDomain.BaseDirectory + "\\RunLog\\";
+            string fileName = DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
+            string time = DateTime.Now.ToString("HH:mm:ss");
+            string writeMsg = time + " " + message + "\r\n";
+            WriteLog(filePath + fileName, writeMsg);
+        }
+        //报警
+        public void WriteErrLog(string message)
+        {
+            if (!errShow)
+            {
+                errShow = true;
+                MessageBox.Show(message);
+                errShow = false;
+            }
+
+            string filePath = AppDomain.CurrentDomain.BaseDirectory + "\\ErrorLog\\";
+            string fileName = DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
+            string time = DateTime.Now.ToString("HH:mm:ss");
+            string writeMsg = time + " " + message + "\r\n";
+            WriteLog(filePath + fileName, writeMsg);
+        }
+
+        /// <summary>
+        /// 写入Log文件
+        /// </summary>
+        /// <param name="logFile">文件路径+文件名(包含扩展名)</param>
+        /// <param name="log">写入内容</param>
+        /// <returns></returns>
+        private bool WriteLog(string logFile, string log)
+        {
+            if (!File.Exists(logFile)) NewTxtFile(logFile); //判断文件是否存在,不存在则新建
+            try
+            {
+                using (FileStream fileStream = new FileStream(logFile, FileMode.Open, FileAccess.Write))    //写入文件
+                {
+                    StreamWriter streamWriter = new StreamWriter(fileStream);
+                    //sw.BaseStream的Position或Seek()可移动文件流指针到的任意位置。
+                    streamWriter.BaseStream.Seek(0, SeekOrigin.End);  //在txt末尾写入
+                    streamWriter.Write(log);      //写入txt文件内容
+                    streamWriter.Flush();
+                    streamWriter.Close();
+                    fileStream.Close();
+                }
+                return true;
+            }
+            catch { return false; }
+        }
+
+        /// <summary>
+        /// 新建txt文件,
+        /// </summary>
+        /// <param name="txtFile">文件路径+文件名(包含扩展名)</param>
+        private void NewTxtFile(string txtFile)
+        {
+            string path = txtFile.Substring(0, txtFile.LastIndexOf("\\"));
+            if (!Directory.Exists(path))
+                Directory.CreateDirectory(path); //判断路径是否存在,不存在则创建文件夹
+            if (!File.Exists(txtFile))  //判断文件是否存在,不存在则创建TXT文件
+            {
+                using (FileStream fileStream = new FileStream(txtFile, FileMode.Create, FileAccess.Write))
+                {
+                    fileStream.Close();
+                }
+            }
+        }
+    }
+}

+ 101 - 0
MainForm/ClassFile/FALibraryClass/Md5Helper.cs

@@ -0,0 +1,101 @@
+/**
+*┌──────────────────────────────────────────────────────────────┐
+*│ 描    述:日志相关的工具类                                                   
+*│ 作    者:执笔小白                                              
+*│ 版    本:1.0                                       
+*│ 创建时间:2020-6-13 15:40:56                            
+*└──────────────────────────────────────────────────────────────┘
+*┌──────────────────────────────────────────────────────────────┐
+*│ 命名空间: WMSTOMESTT                               
+*│ 类    名:ETools                                     
+*└──────────────────────────────────────────────────────────────┘
+*/
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Fa_Xiaomi_N801A.MainForm.EDEHelper
+{
+    public class Md5Helper
+    {
+        /// <summary>
+        /// 计算字符串的MD5
+        /// </summary>
+        /// <param name="str">需要计算的字符串</param>
+        /// <param name="md5_16">需不需要返回16位,默认32位</param>
+        /// <param name="capital">需不需要返回大写,默认小写</param>
+        /// <returns></returns>
+        public static string GetMD5Value_String(string str = "", bool md5_16 = false, bool capital = false)
+        {
+            string pwd = "";
+            MD5 md5 = MD5.Create();  //实例化一个md5对象
+            byte[] s = md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(str));
+
+            // 大写
+            if (capital)
+            {
+                for (int i = 0; i < s.Length; i++)
+                {
+                    // --X为十六进制,2为每次都是两位数
+                    pwd = pwd + s[i].ToString("X2");  // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母
+                }
+            }
+            else
+            {
+                for (int i = 0; i < s.Length; i++)  // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 
+                {
+                    pwd = pwd + s[i].ToString("X2").ToLower();
+                }
+            }
+
+            // 16位
+            if (md5_16)
+            {
+                pwd = pwd.Substring(4, 16);
+            }
+            return pwd;
+        }
+
+        /// <summary>
+        /// 计算文件的MD5值
+        /// </summary>
+        /// <param name="fileName">需要计算md5值的文件的路径</param>
+        /// <param name="md5_16">需不需要返回16位,默认32位</param>
+        /// <param name="capital">需不需要返回大写,默认小写</param>
+        /// <returns></returns>
+        public static string GetMD5Value_File(string fileName = "", bool md5_16 = false, bool capital = false)
+        {
+            string pwd = "";
+            MD5 md5 = MD5.Create();  //实例化一个md5对象
+            using (FileStream file = new FileStream(fileName, System.IO.FileMode.Open))
+            {
+                byte[] s = md5.ComputeHash(file);
+                file.Close();
+
+                // 大写
+                if (capital)
+                {
+                    for (int i = 0; i < s.Length; i++)
+                    {
+                        // --X为十六进制,2为每次都是两位数
+                        pwd = pwd + s[i].ToString("X2");  // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母
+                    }
+                }
+                else
+                {
+                    for (int i = 0; i < s.Length; i++)  // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 
+                    {
+                        pwd = pwd + s[i].ToString("X2").ToLower();
+                    }
+                }
+
+                // 16位
+                if (md5_16)
+                {
+                    pwd = pwd.Substring(4, 16);
+                }
+            }
+            return pwd;
+        }
+    }
+}

+ 95 - 0
MainForm/ClassFile/FALibraryClass/SingletonTemplate.cs

@@ -0,0 +1,95 @@
+using System;
+using System.Threading;
+using System.Windows.Forms;
+
+namespace StandardLibrary
+{
+    //单例模式
+    public class SingletonTemplate<T> where T : class, new()
+    {
+        // Nested Types
+        public delegate void LogHandler(ListBox logListBox, string strLog);
+        // Events
+        public event LogHandler LogEvent;
+        // Fields
+        protected bool m_bRunThread;
+        private static T m_instance;
+        private ListBox m_LogListBox;
+        private Thread m_thread;
+        private static readonly object syslock;
+
+        static SingletonTemplate()
+        {
+            SingletonTemplate<T>.syslock = new object();
+        }
+
+        public SingletonTemplate()
+        {
+            this.m_LogListBox = null;
+            this.m_thread = null;
+        }
+        public static T GetInstance()
+        {
+            if (SingletonTemplate<T>.m_instance == null)
+            {
+                object syslock = SingletonTemplate<T>.syslock;
+                lock (syslock)
+                {
+                    if (SingletonTemplate<T>.m_instance == null)
+                    {
+                        SingletonTemplate<T>.m_instance = Activator.CreateInstance<T>();
+                    }
+                }
+            }
+            return SingletonTemplate<T>.m_instance;
+        }
+
+        public void SetLogListBox(ListBox logListBox)
+        {
+            this.m_LogListBox = logListBox;
+        }
+
+        public void ShowLog(string strLog)
+        {
+            if ((this.LogEvent != null) && (this.m_LogListBox != null))
+            {
+                this.LogEvent(this.m_LogListBox, strLog);
+            }
+        }
+
+        public void StartMonitor()
+        {
+            if (this.m_thread == null)
+            {
+                this.m_thread = new Thread(new ThreadStart(this.ThreadMonitor));
+            }
+            if (this.m_thread.ThreadState > System.Threading.ThreadState.Running)
+            {
+                this.m_bRunThread = true;
+                this.m_thread.Start();
+            }
+        }
+
+        public void StopMonitor()
+        {
+            if (this.m_thread != null)
+            {
+                this.m_bRunThread = false;
+                if (!this.m_thread.Join(0x1388))
+                {
+                    this.m_thread.Abort();
+                }
+                this.m_thread = null;
+            }
+        }
+
+        public virtual void ThreadMonitor()
+        {
+            while (this.m_bRunThread)
+            {
+                Thread.Sleep(100);
+                break;
+            }
+        }
+    }
+}

+ 140 - 0
MainForm/ClassFile/FALibraryClass/SystemParameter.cs

@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using StandardLibrary;
+
+namespace StandardLibrary
+{
+    public enum User
+    {
+        NoLogin,    // 未登录
+        Operator,   // 操作员
+        Admin,      // 管理员
+        SuperAdmin  // 超管
+    }
+
+    public class UserAccount
+    {
+        private string filePath = AppDomain.CurrentDomain.BaseDirectory + "SystemParameter.ini";
+        
+        private Dictionary<User, string> userPassword = new Dictionary<User, string>();
+
+        private User _userPermission = User.NoLogin;
+
+        public delegate void UserChangedHandler(User user);
+        public  event UserChangedHandler UserChangedEvent;
+
+        public UserAccount()
+        {
+            GetUserPassword();
+        }
+
+        public User UserPermission
+        {
+            get { return _userPermission; }
+        }
+
+        /// <summary>
+        /// 获取用户密码
+        /// </summary>
+        private void GetUserPassword()
+        {
+            userPassword.Clear();
+            userPassword.Add(User.Operator, IniFile.INIGetStringValue(filePath, "Password", "Operator", ""));
+            userPassword.Add(User.Admin, IniFile.INIGetStringValue(filePath, "Password", "Admin", ""));
+            userPassword.Add(User.SuperAdmin, IniFile.INIGetStringValue(filePath, "Password", "SuperAdmin", ""));
+        }
+
+        /// <summary>
+        /// 保存用户密码
+        /// </summary>
+        private void SaveUserPassword()
+        {
+            IniFile.INIWriteValue(filePath, "Password", "Operator", userPassword[User.Operator]);
+            IniFile.INIWriteValue(filePath, "Password", "Admin", userPassword[User.Admin]);
+            IniFile.INIWriteValue(filePath, "Password", "SuperAdmin", userPassword[User.SuperAdmin]);
+        }
+
+        /// <summary>
+        /// 用户登录
+        /// </summary>
+        /// <param name="user">用户</param>
+        /// <param name="inputPassword">输入密码</param>
+        /// <returns></returns>
+        public bool UserLogin(User user, string inputPassword)
+        {
+            if (user == User.NoLogin) return false;
+            if (userPassword[user] == inputPassword)
+            {
+                _userPermission = user;
+                UserChangedEvent?.Invoke(_userPermission);
+                return true;
+            }
+            else return false;
+        }
+
+        /// <summary>
+        /// 用户登出
+        /// </summary>
+        public void UserLogout()
+        {
+            _userPermission = User.NoLogin;
+            UserChangedEvent?.Invoke(_userPermission);
+        }
+
+        public void UserSet(User user)
+        {
+            _userPermission = user;
+            UserChangedEvent?.Invoke(_userPermission);
+        }
+
+        /// <summary>
+        /// 密码修改
+        /// </summary>
+        /// <param name="user">用户</param>
+        /// <param name="oldpa">旧密码</param>
+        /// <param name="newpa1">新密码</param>
+        /// <param name="newpa2">新密码确认</param>
+        /// <returns></returns>
+        public bool UserChangePassword(User user, string oldpa, string newpa1, string newpa2)
+        {
+            if (user == User.NoLogin) return false;
+            if (userPassword[user] == oldpa)
+            {
+                if (newpa1 == newpa2)
+                {
+                    userPassword[user] = newpa1;
+                    _userPermission = User.NoLogin;
+                    UserChangedEvent?.Invoke(_userPermission);
+                    SaveUserPassword();
+                    return true;
+                }
+                else return false;
+            }
+            else return false;
+        }
+
+        public User GetUserName(string userText)
+        {
+            User user = new User();
+            switch (userText)
+            {
+                case "操作员":
+                    user = User.Operator;
+                    break;
+                case "管理员":
+                    user = User.Admin;
+                    break;
+                case "超级管理员":
+                    user = User.SuperAdmin;
+                    break;
+                default:
+                    user = User.NoLogin;
+                    break;
+            }
+            return user;
+        }
+    }
+}

+ 309 - 0
MainForm/ClassFile/FALibraryClass/TcpFunction.cs

@@ -0,0 +1,309 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace StandardLibrary
+{
+    /// <summary>
+    /// TCP服务器类
+    /// </summary>
+    class Tcp_Server
+    {
+        #region 字段声明
+        /// <summary>
+        /// TCP服务器接收到客户端连接请求事件
+        /// </summary>
+        public Action<string, bool> TcpConnectEvent;
+        /// <summary>
+        /// TCP服务器接收到客户端发送消息事件
+        /// </summary>
+        public Action<string, byte[]> TcpReceiveEvent;
+        /// <summary>
+        /// 负责监听客户端连接请求的线程
+        /// </summary>
+        private Thread threadWatch = null;
+        /// <summary>
+        /// //服务器套接字
+        /// </summary>
+        private Socket socketWatch = null;
+        /// <summary>
+        /// //客户端IP与套接字的集合
+        /// </summary>
+        private Dictionary<string, Socket> dictSocket = new Dictionary<string, Socket>();
+        /// <summary>
+        /// //客户端IP与线程的集合
+        /// </summary>
+        private Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
+
+        private string _serverIp = "127.0.0.1";
+        private int _serverPort = 1234;
+        #endregion
+
+        public string ServerIp
+        {
+            get { return _serverIp; }
+            set { _serverIp = value; }
+        }
+
+        public int ServerPort
+        {
+            get { return _serverPort; }
+            set { _serverPort = value; }
+        }
+
+        /// <summary>
+        /// 打开侦听
+        /// </summary>
+        /// <param name="listenIP">侦听的IP</param>
+        /// <param name="listenPort">侦听的端口号</param>
+        public bool OpenTcpListen()
+        {
+            try
+            {
+                socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建负责监听的套接字
+                IPAddress address = IPAddress.Parse(_serverIp);//获得IP地址
+                IPEndPoint endPoint = new IPEndPoint(address, _serverPort);//创建包含ip和端口号的网络节点对象
+                socketWatch.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+                socketWatch.Bind(endPoint);//将负责监听的套接字绑定到唯一的ip和端口上
+                socketWatch.Listen(16);//设置侦听队列的长度,开始侦听
+                threadWatch = new Thread(WatchConnecting);//创建负责侦听的线程
+                threadWatch.IsBackground = true;//设置为后台线程
+                threadWatch.Start();//启动线程
+                return true;
+            }
+            catch (Exception e)
+            {
+                MessageBox.Show("异常:" + e.Message, "服务器侦听", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
+                return false;
+            }
+        }
+
+        /// <summary> 
+        /// 侦听客户端请求
+        /// </summary> 
+        private void WatchConnecting()
+        {
+            while (true) //持续监听客户端的连接请求 
+            {
+                // 开始监听客户端连接请求,Accept方法会阻断当前的线程 
+                Socket sokConnection = socketWatch.Accept(); //一旦监听到一个客户端的请求,就返回一个与该客户端通信的套接字 
+                string ip = sokConnection.RemoteEndPoint.ToString().Split(':')[0];
+                if (!dictSocket.ContainsKey(ip)) dictSocket.Add(ip, sokConnection);//将客户端的IP对象添加到集合中 
+                else dictSocket[ip] = sokConnection;
+                Thread thr = new Thread(ReceiveMsg);//创建处理客户端连接线程
+                thr.IsBackground = true;//设置为后台线程
+                thr.Start(sokConnection);//启动线程
+                if (!dictThread.ContainsKey(ip)) dictThread.Add(ip, thr); //将新建的线程添加到线程的集合中
+                else dictThread[ip] = thr;
+                if (TcpConnectEvent != null) TcpConnectEvent(ip, true);//发布客户端连接成功消息
+            }
+        }
+
+        /// <summary>
+        /// 接收数据处理
+        /// </summary>
+        /// <param name="sokConnectionparn">客户端套接字</param>
+        private void ReceiveMsg(object sokConnectionparn)
+        {
+            Socket sokClient = sokConnectionparn as Socket;//客户端套接字
+            string ip = sokClient.RemoteEndPoint.ToString().Split(':')[0];
+            try
+            {
+                while (true)
+                {
+                    byte[] arrMsgRec = new byte[2048 * 1];//定义一个1k字节的接收缓存区 
+                    int length = sokClient.Receive(arrMsgRec);//接收数据将数据存入arrMsgRec,返回数据的长度,并阻挡当前线程
+                    if (length > 0)//判断接收到的数据长度,如果大于0则表示数据正常,如果小于或等于0则表示客户端断开连接
+                    {
+                        byte[] rec = new byte[length];
+                        Array.Copy(arrMsgRec, rec, length);
+                        if (TcpReceiveEvent != null) TcpReceiveEvent(ip, rec);//发布接收客户端消息
+                    }
+                    else dictThread[ip].Abort();//释放线程
+                }
+            }
+            catch (Exception)
+            {
+                if (dictSocket.ContainsKey(ip)) dictSocket.Remove(ip);//从通信套接字集合中删除被中断连接的通信套接字
+                if (dictThread.ContainsKey(ip)) dictThread.Remove(ip);//从通信线程集合中删除被中断连接的通信线程对象
+                if (TcpConnectEvent != null) TcpConnectEvent(ip, false);//发布客户端连接断开消息
+            }
+        }
+
+        public void CloseTcpConnect(string ip)
+        {
+            if (dictSocket.ContainsKey(ip))
+            {
+                dictThread[ip].Abort();
+                dictSocket[ip].Close();
+            }
+        }
+
+        public void CloseTcpListen()
+        {
+            //socketWatch.Close();
+            //socketWatch.Dispose();
+            //threadWatch.Abort();
+        }
+
+        /// <summary>
+        /// 发送消息
+        /// </summary>
+        /// <param name="IP">客户端IP地址</param>
+        /// <param name="SendData">数据</param>
+        public bool SendServerMsg(string IP, string SendData)
+        {
+            try
+            {
+                byte[] sendMsg = Encoding.ASCII.GetBytes(SendData);
+                if (dictSocket.ContainsKey(IP)) dictSocket[IP].Send(sendMsg);//发送数据
+                return true;
+            }
+            catch { return false; }
+        }
+
+        /// <summary>
+        /// 发送消息
+        /// </summary>
+        /// <param name="IP">客户端IP地址</param>
+        /// <param name="SendData">数据</param>
+        public bool SendServerMsg(string IP, byte[] SendData)
+        {
+            try
+            {
+                if (dictSocket.ContainsKey(IP)) dictSocket[IP].Send(SendData);//发送数据
+                return true;
+            }
+            catch { return false; }
+        }
+    }
+
+    /// <summary>
+    /// TCP客户端类
+    /// </summary>
+    class Tcp_Client
+    {        
+        /// <summary>
+        /// 接收消息事件
+        /// </summary>
+        public event Action<string> TcpReceiveEvent;
+        /// <summary>
+        /// 连接状态事件
+        /// </summary>
+        public event Action<bool> TcpConnectEvent;
+        /// <summary>
+        /// TCP客户端
+        /// </summary>
+        private Socket tcpClient;
+        /// <summary>
+        /// 接收消息线程
+        /// </summary>
+        private Thread receiveThread;
+
+        private string _ip = "127.0.0.1";
+        private int _port = 8500;
+
+        /// <summary>
+        /// 获取或设置远程服务端IP地址
+        /// </summary>
+        public string IP
+        {
+            get { return _ip; }
+            set { _ip = value; }
+        }
+
+        /// <summary>
+        /// 获取或设置远程服务端端口号
+        /// </summary>
+        public int Port
+        {
+            get { return _port; }
+            set { _port = value; }
+        }
+
+        /// <summary>
+        /// 打开连接
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <param name="port"></param>
+        public bool OpenTcpConnect()
+        {
+            IPEndPoint IpEnd = new IPEndPoint(IPAddress.Parse(_ip), _port);
+            tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+            try
+            {
+                tcpClient.Connect(IpEnd);//发起TCP连接
+                receiveThread = new Thread(ReceiveMsg);//实例化并启动接受消息线程 
+                receiveThread.IsBackground = true;//设置为后台线程
+                receiveThread.Start();//启动线程
+                if (TcpConnectEvent != null) TcpConnectEvent(true);//发布连接成功消息
+                return true;
+            }
+            catch (Exception e)
+            {
+                if (TcpConnectEvent != null) TcpConnectEvent(false);//发布连接失败消息
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 关闭连接
+        /// </summary>
+        public void CloseTcpConnect()
+        {
+            tcpClient.Close();//断开TCP连接 
+            receiveThread.Abort();//销毁接受消息的线程 
+        }
+
+        /// <summary>
+        /// 接收服务端发送的消息
+        /// </summary>
+        public void ReceiveMsg()
+        {
+            try
+            {
+                while (true)
+                {
+                    byte[] getData = new byte[2048];//创建接受数据的字节流
+                    int length = tcpClient.Receive(getData, getData.Length, 0);
+                    if (length > 0)
+                    {
+                        byte[] rec = new byte[length];
+                        Array.Copy(getData, rec, length);
+                        string getMsg = Encoding.ASCII.GetString(rec);//将字节数组转换成文本形式
+                        if (TcpReceiveEvent != null) TcpReceiveEvent(getMsg);
+                    }
+                    else receiveThread.Abort();//释放线程
+                }
+            }
+            catch (Exception e)//检测释放线程异常
+            {
+                if (TcpConnectEvent != null) TcpConnectEvent(false);//发布连接断开消息
+                CloseTcpConnect();
+            }
+        }
+        /// <summary>
+        /// 发送消息给服务端
+        /// </summary>
+        /// <param name="msg">数据</param>
+        public void SendMsg(string msg)
+        {
+            byte[] sendData = Encoding.ASCII.GetBytes(msg);//将要发送的文本转换为字符数组形式
+            tcpClient.Send(sendData, sendData.Length, 0);
+        }
+        /// <summary>
+        /// 发送消息给服务端
+        /// </summary>
+        /// <param name="msg">数据</param>
+        public void SendMsg(byte[] msg)
+        {
+            tcpClient.Send(msg);
+        }
+    }
+}

+ 230 - 0
MainForm/ClassFile/FALibraryClass/XmlHandle.cs

@@ -0,0 +1,230 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.IO;
+using System.Xml;
+
+namespace StandardLibrary
+{
+    /*************************************************************************
+    注:XML元素节点名称命名规则
+        1.名称的开头必须是字母、汉字或下划线“_”;
+        2.标记名称中不能有空格;
+        3.名称的字符串只能包含字母,数字,“_”,“-”,“.”;
+    **************************************************************************/
+
+    /// <summary>
+    /// XML操作类
+    /// </summary>
+    class XmlHandle
+    {
+        XmlDocument xmlDoc = new XmlDocument();
+
+        private string fileName;    //路径+XML文件名
+
+        public XmlHandle(string fileName)
+        {
+            this.fileName = fileName;
+        }
+
+        /// <summary>
+        /// 打开XML文件
+        /// </summary>
+        public string Open()
+        {
+            try
+            {
+                xmlDoc.Load(fileName);
+                return null;
+            }
+            catch (Exception ex) { return ex.Message; }
+        }
+
+        /// <summary>
+        /// 保存XML文件
+        /// </summary>
+        /// <returns></returns>
+        public string Save()
+        {
+            try
+            {
+                xmlDoc.Save(fileName);
+                return null;
+            }
+            catch (Exception ex) { return ex.Message; }
+        }
+
+
+        #region 写操作
+
+        /// <summary>
+        /// 添加根节点
+        /// </summary>
+        /// <param name="rootName">根节点名</param>
+        /// <returns></returns>
+        public XmlNode AddRootNode(string rootName)
+        {
+            XmlElement root = (XmlElement)GetRootNode();
+            if (xmlDoc.FirstChild == null)
+            {
+                XmlNode node = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "");//创建类型声明节点    
+                xmlDoc.AppendChild(node);
+            }
+            if (root == null)
+            {
+                root = xmlDoc.CreateElement(rootName);  //创建根节点
+                xmlDoc.AppendChild(root);
+            }
+            return (XmlNode)root;
+        }
+
+        /// <summary>
+        /// 添加节点
+        /// </summary>
+        /// <param name="parentNode">父节点</param>
+        /// <param name="name">节点名</param>
+        /// <param name="value">节点值</param>
+        /// <returns></returns>
+        public XmlNode AddChildNode(XmlNode parentNode, string name, string value = null)
+        {
+            XmlNode node = xmlDoc.CreateNode(XmlNodeType.Element, name, null);
+            node.InnerText = value;
+            parentNode.AppendChild(node);
+            return node;
+        }
+
+        /// <summary>
+        /// 删除节点
+        /// </summary>
+        /// <param name="node"></param>
+        public void RemoveNode(XmlNode node)
+        {
+            node.ParentNode.RemoveChild(node);
+        }
+
+        /// <summary>
+        /// 删除父节点下所有子节点
+        /// </summary>
+        public void RemoveAllNode(XmlNode parentNode)
+        {
+            parentNode.RemoveAll();
+        }
+
+        /// <summary>
+        /// 设置节点的属性
+        /// </summary>
+        /// <param name="node">节点</param>
+        /// <param name="name">属性名</param>
+        /// <param name="attribute">属性值</param>
+        public void SetNodeAttribute(XmlNode node, string name, string attribute)
+        {
+            XmlElement n = (XmlElement)node;
+            n.SetAttribute(name, attribute);
+        }
+
+        /// <summary>
+        /// 删除节点的属性
+        /// </summary>
+        /// <param name="node">节点</param>
+        /// <param name="name">属性名</param>
+        public void RemoveNoedAttribute(XmlNode node, string name)
+        {
+            XmlElement n = (XmlElement)node;
+            n.RemoveAttribute(name);
+        }
+
+        /// <summary>
+        /// 设置节点的值
+        /// </summary>
+        /// <param name="node">节点</param>
+        /// <param name="value">设置值</param>
+        public void SetNodeValue(XmlNode node, string value)
+        {
+            node.InnerText = value;
+        }
+
+        #endregion
+
+        #region 读操作
+
+        //public XmlDeclaration GetDeclarationNode()
+        //{
+        //    return xmlDoc.
+        //}
+
+        /// <summary>
+        /// 获取根节点
+        /// </summary>
+        /// <returns></returns>
+        public XmlNode GetRootNode()
+        {
+            return xmlDoc.DocumentElement;
+        }
+
+        /// <summary>
+        /// 获取父节点下指定的子节点
+        /// </summary>
+        /// <param name="parentNode">父节点</param>
+        /// <param name="nodeName">节点名</param>
+        /// <returns></returns>
+        public XmlNode GetCertainChildNode(XmlNode parentNode, string nodeName)
+        {
+            return parentNode.SelectSingleNode(nodeName);
+        }
+
+        /// <summary>
+        /// 获取父节点的第一个子节点
+        /// </summary>
+        /// <param name="parentNode">父节点</param>
+        /// <returns></returns>
+        public XmlNode GetFirstChildNode(XmlNode parentNode)
+        {
+            return parentNode.FirstChild;
+        }
+
+        /// <summary>
+        /// 获取父节点的所有子节点
+        /// </summary>
+        /// <param name="parentNode">父节点</param>
+        /// <returns></returns>
+        public XmlNodeList GetAllChildNode(XmlNode parentNode)
+        {
+            return parentNode.ChildNodes;
+        }
+
+        /// <summary>
+        /// 获取节点的属性
+        /// </summary>
+        /// <param name="node">节点</param>
+        /// <param name="name">属性名</param>
+        /// <returns></returns>
+        public string GetNodeAttribute(XmlNode node, string name)
+        {
+            XmlElement n = (XmlElement)node;
+            return n.GetAttribute(name);
+        }
+
+        /// <summary>
+        /// 获取节点的值
+        /// </summary>
+        /// <param name="node">节点</param>
+        /// <returns></returns>
+        public string GetNodeValue(XmlNode node)
+        {
+            return node.InnerText;
+        }
+
+        /// <summary>
+        /// 获取节点的名称
+        /// </summary>
+        /// <param name="node">节点</param>
+        /// <returns></returns>
+        public string GetNodeName(XmlNode node)
+        {
+            return node.Name;
+        }
+        #endregion
+    }
+}

+ 102 - 0
MainForm/ClassFile/FileIOHelper.cs

@@ -0,0 +1,102 @@
+/**
+*┌──────────────────────────────────────────────────────────────┐
+*│ 描    述:文件IO的工具类                                                   
+*│ 作    者:执笔小白                                              
+*│ 版    本:4.0                                       
+*│ 创建时间:2022-6-13 15:40:56                            
+*└──────────────────────────────────────────────────────────────┘
+*┌──────────────────────────────────────────────────────────────┐
+*│ 命名空间: ZhibiXiaobai.Uril.IOHelper                               
+*│ 类    名:FileIOHelper                                     
+*└──────────────────────────────────────────────────────────────┘
+*/
+using System.IO;
+using System.Windows.Forms;
+
+namespace MainForm.ClassFile
+{
+
+    public class FileIOHelper
+    {
+        /// <summary>
+        /// 判断文件存不存在
+        /// <param name="FilePath">文件路径</param>
+        /// <param name="IsCreate">不存在时是否创建文件</param>
+        /// <returns>返回判断的结果</returns>
+        public static bool ISExists_File(string FilePath, bool IsCreate = false)
+        {
+
+            if (File.Exists(FilePath))
+            {
+                return true;
+            }
+            else
+            {
+                if (IsCreate)  // 需不需要创建文件
+                {
+                    //检验目录不存在就创建
+                    //if (!System.IO.Directory.Exists(FilePath))
+                    //{
+                    //    System.IO.Directory.CreateDirectory(FilePath);
+                    //}
+
+                    FilePath = FilePath.Replace(@"\\", @"/");  // 格式化目录 '\\'变为'/'
+
+                    string[] ss = FilePath.Split(new char[] { '/' });
+                    string filePathP = ss[0];
+                    for (int i = 1; i < ss.Length - 1; i++)
+                    {
+                        filePathP += "/" + ss[i];
+                    }
+
+                    if (!System.IO.Directory.Exists(filePathP))
+                    {
+                        System.IO.Directory.CreateDirectory(filePathP);
+                    }
+                    File.Create(FilePath);
+                }
+                return false;
+            }
+        }
+
+        #region 通过路径取文件方法
+        /// <summary>
+        /// 通过文件对话框取文件路径
+        /// 使用 var filename = OpenfileDlg();
+        /// </summary>
+        /// <param name="Defaultpath">默认打开路径</param>
+        /// <param name="Fileter">文件类型</param>
+        /// <param name="Multiselect">是否支持选择多个文件</param>
+        /// <param name="DlgTitle">Dlg窗体的标题</param>
+        /// <param name="LimitSize">是否限制大小(单位为KB,0为不限制)</param>
+        /// <returns></returns>
+        public static string OpenfileDlg(string Defaultpath = null, string Fileter = ".jpeg|*.jpeg|.jpg|*.jpg|.png|*.png|.gif|*.gif|.bmp|*.bmp", bool Multiselect = false,
+            string DlgTitle = "请选择要打开的文件", long LimitSize = 0)
+        {
+            OpenFileDialog ofd = new OpenFileDialog();
+            ofd.Title = DlgTitle;                // 标题
+            ofd.Multiselect = Multiselect;       // 多选
+            ofd.InitialDirectory = Defaultpath;  // 初始目录
+            ofd.Filter = Fileter;                // 设定文件类型
+            ofd.ShowDialog().GetHashCode();
+
+            string path = ofd.FileName;  // 获得在打开文件对话框中选择的文件的路径
+            if (!string.IsNullOrEmpty(path) && LimitSize > 0 && ofd.OpenFile().Length > (LimitSize * 1024))
+            {
+                path = null;
+            }
+            return path;
+        }
+        #endregion
+
+        /// <summary>
+        /// 复制-不覆盖已有文件
+        /// </summary>
+        /// <param name="SourceFileUrl">源文件地址</param>
+        /// <param name="DistFileUrl">目标地址</param>
+        public static void CopyFile(string SourceFileUrl, string DistFileUrl)
+        {
+            File.Copy(SourceFileUrl, DistFileUrl);
+        }
+    }
+}

File diff suppressed because it is too large
+ 3101 - 0
MainForm/ClassFile/Inovance_EIP.cs


File diff suppressed because it is too large
+ 1058 - 0
MainForm/ClassFile/ModbusClientHelper.cs


+ 182 - 0
MainForm/ClassFile/NPOIHelper.cs

@@ -0,0 +1,182 @@
+using NPOI.HSSF.UserModel;
+using NPOI.XSSF.UserModel;
+using System;
+using System.Data;
+using System.IO;
+
+namespace MainForm.ClassFile
+{
+    /// <summary>
+    /// EXCEL操作类
+    /// </summary>
+    public class NPOIHelper
+    {
+        /// <summary>
+        /// 读取指定路径的Excel文件到DataTable
+        /// </summary>
+        /// <param name="filePath"></param>
+        /// <returns></returns>
+        public static DataTable ReadExcel(string filePath)
+        {
+            NPOI.SS.UserModel.ISheet sheet;
+            if (filePath.Contains(".xlsx"))  // 2007 xlsx
+            {
+                #region//初始化信息
+                XSSFWorkbook hssfworkbook;
+                try
+                {
+                    using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+                    {
+                        hssfworkbook = new XSSFWorkbook(file);
+                    }
+                }
+                catch (Exception e)
+                {
+                    throw e;
+                }
+                sheet = hssfworkbook.GetSheetAt(0);
+                #endregion
+                System.Collections.IEnumerator rows = sheet.GetRowEnumerator();
+                DataTable dt = new DataTable();
+                for (int j = 0; j < (sheet.GetRow(0).LastCellNum); j++)  // cell数
+                {
+                    dt.Columns.Add(Convert.ToChar(((int)'A') + j).ToString());
+                }
+                while (rows.MoveNext())
+                {
+                    XSSFRow row = (XSSFRow)rows.Current;
+                    DataRow dr = dt.NewRow();
+                    for (int i = 0; i < row.LastCellNum; i++)
+                    {
+                        NPOI.SS.UserModel.ICell cell = row.GetCell(i);
+                        if (cell == null)
+                        {
+                            dr[i] = null;
+                        }
+                        else
+                        {
+                            dr[i] = cell.ToString();
+                        }
+                    }
+                    dt.Rows.Add(dr);
+                }
+                return dt;
+            }
+            else  // 2003 xls
+            {
+                HSSFWorkbook hssfworkbook;
+                try
+                {
+                    using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+                    {
+                        hssfworkbook = new HSSFWorkbook(file);
+                    }
+                }
+                catch (Exception e)
+                {
+                    throw e;
+                }
+                sheet = hssfworkbook.GetSheetAt(0);
+                System.Collections.IEnumerator rows = sheet.GetRowEnumerator();
+                DataTable dt = new DataTable();
+                for (int j = 0; j < (sheet.GetRow(0).LastCellNum); j++)
+                {
+                    dt.Columns.Add(Convert.ToChar(((int)'A') + j).ToString());
+                }
+                while (rows.MoveNext())
+                {
+                    HSSFRow row = (HSSFRow)rows.Current;
+                    DataRow dr = dt.NewRow();
+                    for (int i = 0; i < row.LastCellNum; i++)
+                    {
+                        NPOI.SS.UserModel.ICell cell = row.GetCell(i);
+                        if (cell == null)
+                        {
+                            dr[i] = null;
+                        }
+                        else
+                        {
+                            dr[i] = cell.ToString();
+                        }
+                    }
+                    dt.Rows.Add(dr);
+                }
+                return dt;
+            }
+        }
+
+        /// <summary>
+        /// 将DataTable数据写入到指定路径的Excel文件
+        /// </summary>
+        /// <param name="dt"></param>
+        /// <param name="filePath"></param>
+        public static void WriteExcel(DataTable dt, string filePath)
+        {
+            if (!string.IsNullOrEmpty(filePath) && null != dt && dt.Rows.Count > 0)
+            {
+                if (filePath.Contains(".xlsx"))  //  2007 xlsx
+                {
+                    XSSFWorkbook book = new XSSFWorkbook();
+                    NPOI.SS.UserModel.ISheet sheet = book.CreateSheet(dt.TableName);
+
+                    NPOI.SS.UserModel.IRow row = sheet.CreateRow(0);
+                    for (int i = 0; i < dt.Columns.Count; i++)
+                    {
+                        row.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
+                    }
+                    for (int i = 0; i < dt.Rows.Count; i++)
+                    {
+                        NPOI.SS.UserModel.IRow row2 = sheet.CreateRow(i + 1);
+                        for (int j = 0; j < dt.Columns.Count; j++)
+                        {
+                            row2.CreateCell(j).SetCellValue(Convert.ToString(dt.Rows[i][j]));
+                        }
+                    }
+                    // 写入到客户端  
+                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
+                    {
+                        book.Write(ms);
+                        using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                        {
+                            byte[] data = ms.ToArray();
+                            fs.Write(data, 0, data.Length);
+                            fs.Flush();
+                        }
+                        book = null;
+                    }
+                }
+                else  // 2003 xls
+                {
+                    NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
+                    NPOI.SS.UserModel.ISheet sheet = book.CreateSheet(dt.TableName);
+
+                    NPOI.SS.UserModel.IRow row = sheet.CreateRow(0);
+                    for (int i = 0; i < dt.Columns.Count; i++)
+                    {
+                        row.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
+                    }
+                    for (int i = 0; i < dt.Rows.Count; i++)
+                    {
+                        NPOI.SS.UserModel.IRow row2 = sheet.CreateRow(i + 1);
+                        for (int j = 0; j < dt.Columns.Count; j++)
+                        {
+                            row2.CreateCell(j).SetCellValue(Convert.ToString(dt.Rows[i][j]));
+                        }
+                    }
+                    // 写入到客户端  
+                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
+                    {
+                        book.Write(ms);
+                        using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                        {
+                            byte[] data = ms.ToArray();
+                            fs.Write(data, 0, data.Length);
+                            fs.Flush();
+                        }
+                        book = null;
+                    }
+                }
+            }
+        }
+    }
+}

+ 88 - 0
MainForm/ClassFile/NPOIOperate.cs

@@ -0,0 +1,88 @@
+using NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MainForm.ClassFile
+{
+    public class NPOIOperate
+    {
+        private static Mutex mutex = new Mutex();
+        /// <summary>
+        /// 向已存在的excel写入数据
+        /// </summary>
+        /// <param name="fileName">excel路径</param>
+        /// <param name="headData">列索引<列索引,单元格值></param>
+        /// <param name="cellData">列索引<列索引,单元格值></param>
+        public static string AddExcelData(string fileName, IDictionary<int, string> headData, IDictionary<int, string> cellData)
+        {
+            mutex.WaitOne();
+            string ret = string.Empty;
+            FileStream fileRead = null;
+            FileStream fileWrite = null;
+            try
+            {
+                if (!File.Exists(fileName))
+                    CreateExcel(fileName, headData);
+                IWorkbook workbook = null;
+                //读
+                fileRead = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+
+                workbook = new HSSFWorkbook(fileRead);
+                ISheet sheet = workbook.GetSheetAt(0);
+                IRow row = sheet.CreateRow(sheet.LastRowNum + 1);
+                ICell cell = null;
+                foreach (KeyValuePair<int, string> keyValue in cellData)
+                {
+                    cell = row.CreateCell(keyValue.Key);
+                    cell.SetCellValue(keyValue.Value);
+                }                //写
+                fileWrite = new FileStream(fileName, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
+
+                workbook.Write(fileWrite);
+                workbook.Close();
+                ret = "写入成功";
+            }
+            catch(Exception ex)
+            {
+                ret = ex.Message.ToString();
+            }
+            finally
+            {
+                fileRead?.Close();
+                fileWrite?.Close();
+            }
+            mutex.ReleaseMutex();
+            return ret;
+        }
+        /// <summary>
+        /// 创建excel写入头
+        /// </summary>
+        /// <param name="fileName"></param>
+        /// <param name="headData"></param>
+        public static void CreateExcel(string fileName, IDictionary<int, string> headData)
+        {
+            using (FileStream fileWrite = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
+            {
+                IWorkbook workbook = new HSSFWorkbook();
+                ISheet sheet = workbook.CreateSheet("加工数据");//获取工作表
+                IRow row = sheet.CreateRow(0); //创建新行
+                ICell cell = null;
+                foreach (KeyValuePair<int, string> keyValue in headData)
+                {
+                    cell = row.CreateCell(keyValue.Key);
+                    cell.SetCellValue(keyValue.Value);
+                }
+                workbook.Write(fileWrite);
+                workbook.Close();
+            }
+        }
+    }
+}

+ 0 - 0
MainForm/ClassFile/ProcessHelper.cs


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