├── .gitattributes
├── .gitignore
├── Images
├── Common.png
├── MainContent.png
├── Step1.png
├── Step2.png
├── Step3.png
├── Step4.png
├── TestTool.png
├── UpdateFile.png
├── UpdaterClient.png
├── UpdaterRestart.png
├── UpdaterService.png
├── UpdaterWebServer.png
└── Workflow.png
├── README.md
├── Source
└── SocketUpdater
│ ├── SocketUpdater.sln
│ ├── TestTool
│ ├── App.config
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── Model
│ │ ├── ClientInfoModel.cs
│ │ ├── LinkInfos.cs
│ │ └── RegistryInfoModel.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ ├── Resources.resx
│ │ ├── Settings.Designer.cs
│ │ └── Settings.settings
│ ├── TestTool.csproj
│ ├── View
│ │ ├── ClientDownLoadPage.xaml
│ │ ├── ClientDownLoadPage.xaml.cs
│ │ ├── ClientRequestInfoPage.xaml
│ │ ├── ClientRequestInfoPage.xaml.cs
│ │ ├── RegistryInfoPage.xaml
│ │ ├── RegistryInfoPage.xaml.cs
│ │ ├── RestartPage.xaml
│ │ ├── RestartPage.xaml.cs
│ │ ├── ToolWindow.xaml
│ │ └── ToolWindow.xaml.cs
│ └── ViewModel
│ │ ├── ClientDownLoadViewModel.cs
│ │ ├── ClientRequestInfoViewModel.cs
│ │ ├── RegistryInfoViewModel.cs
│ │ └── RestartViewModel.cs
│ ├── UpdaterClient
│ ├── ClientSocket.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── UpdaterClient.csproj
│ └── Utility
│ │ ├── BootUtils.cs
│ │ ├── RegistryUtils.cs
│ │ └── RequestInfoUtils.cs
│ ├── UpdaterRestart
│ ├── App.config
│ ├── ExampleFile
│ │ ├── config.xml
│ │ └── updateInfo.xml
│ ├── ExecuteUpdate.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Restart.vbs
│ ├── UpdaterRestart.csproj
│ ├── Utility
│ │ ├── ProcessUtils.cs
│ │ ├── ReplaceFilesUtils.cs
│ │ └── ZipUtils.cs
│ └── app.manifest
│ ├── UpdaterService
│ ├── App.config
│ ├── ExampleFile
│ │ └── BIMProduct2018_Revit2016_18.1.4.0_18.1.5.0.zip
│ ├── ExecuteProgram.cs
│ ├── Install.bat
│ ├── ProjectInstaller.Designer.cs
│ ├── ProjectInstaller.cs
│ ├── ProjectInstaller.resx
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── ServerSocket.cs
│ ├── SocketService.Designer.cs
│ ├── SocketService.cs
│ ├── Uninstall.bat
│ └── UpdaterService.csproj
│ ├── UpdaterShare
│ ├── GlobalSetting
│ │ └── DownloadSetting.cs
│ ├── Model
│ │ ├── ClientBasicInfo.cs
│ │ ├── ClientLinkInfo.cs
│ │ ├── ComObject.cs
│ │ ├── DownloadFileInfo.cs
│ │ └── PacketDef.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── UpdaterShare.csproj
│ └── Utility
│ │ ├── Crc16Utils.cs
│ │ ├── FileUtils.cs
│ │ ├── LogUtils.cs
│ │ ├── Md5Utils.cs
│ │ ├── PacketUtils.cs
│ │ ├── ServerFileUtils.cs
│ │ └── XmlUtils.cs
│ └── UpdaterWebServer
│ ├── ApiController
│ ├── ConnectionController.cs
│ └── GetFileInfoController.cs
│ ├── App_Start
│ └── WebApiConfig.cs
│ ├── Global.asax
│ ├── Global.asax.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Startup.cs
│ ├── UpdaterWebServer.csproj
│ ├── Web.Debug.config
│ ├── Web.Release.config
│ ├── Web.config
│ ├── favicon.ico
│ └── packages.config
└── ThirdParty
├── DevExpress
├── DevExpress.Data.v15.2.dll
├── DevExpress.Mvvm.v15.2.dll
├── DevExpress.Xpf.Controls.v15.2.dll
└── DevExpress.Xpf.Core.v15.2.dll
├── ICSharpCode
├── ICSharpCode.SharpZipLib.dll
└── ICSharpCode.SharpZipLib.xml
├── Log4Net
├── log4net.dll
└── log4net.xml
└── Newtonsoft.Json
├── Newtonsoft.Json.dll
└── Newtonsoft.Json.xml
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | [Rr]eleases/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Bb]in_cscec8b/
18 | [Oo]bj/
19 |
20 | # Roslyn cache directories
21 | *.ide/
22 |
23 | # MSTest test Results
24 | [Tt]est[Rr]esult*/
25 | [Bb]uild[Ll]og.*
26 |
27 | #NUNIT
28 | *.VisualState.xml
29 | TestResult.xml
30 |
31 | # Build Results of an ATL Project
32 | [Dd]ebugPS/
33 | [Rr]eleasePS/
34 | dlldata.c
35 |
36 | *_i.c
37 | *_p.c
38 | *_i.h
39 | *.ilk
40 | *.meta
41 | *.obj
42 | *.pch
43 | *.pdb
44 | *.pgc
45 | *.pgd
46 | *.rsp
47 | *.sbr
48 | *.tlb
49 | *.tli
50 | *.tlh
51 | *.tmp
52 | *.tmp_proj
53 | *.log
54 | *.vspscc
55 | *.vssscc
56 | .builds
57 | *.pidb
58 | *.svclog
59 | *.scc
60 |
61 | # Chutzpah Test files
62 | _Chutzpah*
63 |
64 | # Visual C++ cache files
65 | ipch/
66 | *.aps
67 | *.ncb
68 | *.opensdf
69 | *.sdf
70 | *.cachefile
71 |
72 | # Visual Studio profiler
73 | *.psess
74 | *.vsp
75 | *.vspx
76 | .vs/
77 |
78 | # TFS 2012 Local Workspace
79 | $tf/
80 |
81 | # Guidance Automation Toolkit
82 | *.gpState
83 |
84 | # ReSharper is a .NET coding add-in
85 | _ReSharper*/
86 | *.[Rr]e[Ss]harper
87 | *.DotSettings.user
88 |
89 | # JustCode is a .NET coding addin-in
90 | .JustCode
91 |
92 | # TeamCity is a build add-in
93 | _TeamCity*
94 |
95 | # DotCover is a Code Coverage Tool
96 | *.dotCover
97 |
98 | # NCrunch
99 | _NCrunch_*
100 | .*crunch*.local.xml
101 |
102 | # MightyMoose
103 | *.mm.*
104 | AutoTest.Net/
105 |
106 | # Web workbench (sass)
107 | .sass-cache/
108 |
109 | # Installshield output folder
110 | [Ee]xpress/
111 |
112 | # DocProject is a documentation generator add-in
113 | DocProject/buildhelp/
114 | DocProject/Help/*.HxT
115 | DocProject/Help/*.HxC
116 | DocProject/Help/*.hhc
117 | DocProject/Help/*.hhk
118 | DocProject/Help/*.hhp
119 | DocProject/Help/Html2
120 | DocProject/Help/html
121 |
122 | # Click-Once directory
123 | publish/
124 |
125 | # Publish Web Output
126 | *.[Pp]ublish.xml
127 | *.azurePubxml
128 | ## TODO: Comment the next line if you want to checkin your
129 | ## web deploy settings but do note that will include unencrypted
130 | ## passwords
131 | *.pubxml
132 |
133 | # NuGet Packages
134 | packages/*
135 | *.nupkg
136 | ## TODO: If the tool you use requires repositories.config
137 | ## uncomment the next line
138 | #!packages/repositories.config
139 |
140 | # Enable "build/" folder in the NuGet Packages folder since
141 | # NuGet packages use it for MSBuild targets.
142 | # This line needs to be after the ignore of the build folder
143 | # (and the packages folder if the line above has been uncommented)
144 | !packages/build/
145 |
146 | # Windows Azure Build Output
147 | csx/
148 | *.build.csdef
149 |
150 | # Windows Store app package directory
151 | AppPackages/
152 |
153 | # Others
154 | sql/
155 | *.Cache
156 | ClientBin/
157 | [Ss]tyle[Cc]op.*
158 | ~$*
159 | *~
160 | *.dbmdl
161 | *.dbproj.schemaview
162 | *.pfx
163 | *.publishsettings
164 | node_modules/
165 |
166 | # RIA/Silverlight projects
167 | Generated_Code/
168 |
169 | # Backup & report files from converting an old project file
170 | # to a newer Visual Studio version. Backup files are not needed,
171 | # because we have git ;-)
172 | _UpgradeReport_Files/
173 | Backup*/
174 | UpgradeLog*.XML
175 | UpgradeLog*.htm
176 |
177 | # SQL Server files
178 | *.mdf
179 | *.ldf
180 |
181 | # Business Intelligence projects
182 | *.rdl.data
183 | *.bim.layout
184 | *.bim_*.settings
185 |
186 | # Microsoft Fakes
187 | FakesAssemblies/
188 | bin.zip
189 | *.orig
--------------------------------------------------------------------------------
/Images/Common.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/Common.png
--------------------------------------------------------------------------------
/Images/MainContent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/MainContent.png
--------------------------------------------------------------------------------
/Images/Step1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/Step1.png
--------------------------------------------------------------------------------
/Images/Step2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/Step2.png
--------------------------------------------------------------------------------
/Images/Step3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/Step3.png
--------------------------------------------------------------------------------
/Images/Step4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/Step4.png
--------------------------------------------------------------------------------
/Images/TestTool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/TestTool.png
--------------------------------------------------------------------------------
/Images/UpdateFile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/UpdateFile.png
--------------------------------------------------------------------------------
/Images/UpdaterClient.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/UpdaterClient.png
--------------------------------------------------------------------------------
/Images/UpdaterRestart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/UpdaterRestart.png
--------------------------------------------------------------------------------
/Images/UpdaterService.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/UpdaterService.png
--------------------------------------------------------------------------------
/Images/UpdaterWebServer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/UpdaterWebServer.png
--------------------------------------------------------------------------------
/Images/Workflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Images/Workflow.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## SocketUpdater ReadMe
2 |
3 | A Revit Plug-In Updater Project Based On Multi-Thread Task Socket
4 |
5 | * * *
6 |
7 | ### Project Source
8 |
9 | Most of clients don't want to uninstall the old,then install the new one when a revit plug-in releases very frequently. Therefore, I started this project and hope to solve this problem.
10 |
11 | * * *
12 |
13 | ### Main Content
14 |
15 | 
16 |
17 | * Client:
18 | A **dll** called **UpdaterClient** which used to be called in our plug-in.
19 | A **exe** called **UpdaterRestart** which is included in our plug-in and it used to replace old files with new ones and restart Autodesk Revit.
20 | * Common:
21 | A **dll** called **UpdaterShare** which is used to be called both in Client and Server.
22 | * Server:
23 | A **Windows service** called **UpdaterService** which runs Server Socket to send update files to Client.
24 | A **Webapi service** called **UpdaterWebServer** which returns some brief infos about update files (file latestversion, file length and file Md5 value) to Client.
25 | * Tool:
26 | A **exe** called **TestTool** which runs whole workflow.
27 |
28 | * * *
29 |
30 | ### WorkFlow
31 |
32 | 
33 |
34 | * * *
35 |
36 | ### Each Part
37 |
38 | 
39 |
40 | * **BootUtils**:
41 | this class is used to create .lnk in Startup folder which can makes **UpdaterRestart** runs when computer boots.
42 | * **RegistryUtils**:
43 | this class is used to Read, Write, Create and Delete product Registry info.
44 | * **RequestInfoUtils**:
45 | this class is used to send packed Registry info to Server and receive update file info, such as its version, length, Md5 value.
46 | * **ClientSocket**:
47 | this class is used to send download file request and receive data packets from Server, and finally combine data packets.
48 |
49 | 
50 |
51 | * * *
52 |
53 | 
54 |
55 | * **ExampleFile (Not be called in program)**
56 | **config.xml**: this xml file is inclueded in UpdateFile.zip which can determined the file location.
57 | **updateInfo.xml**: this xml file records the client decisions when he/she completes download files, whether restart revit now or next computer boot time.
58 | While it records product Registry info.
59 |
60 | * **ProcessUtils**:
61 | this class is used to kill Revit process and start **UpdaterRestart** exe.
62 |
63 | * **ReplaceFilesUtils**:
64 | this class is used to replace old files with new ones.
65 | * **ZipUtils**:
66 | this class is used to Zip files and Unzip .zip file.
67 | * **app.mainfest**:
68 | this file is used to get high control for Registry operations.
69 | * **ExecuteUpdate**:
70 | this console program is used to execute final update operations, such as unzip UpdateFile.zip, cover old files, update Registry info etc.
71 | * **Restart.vbs**:
72 | this vbs script is only used when Client chosen update next computer boots time.
73 |
74 | * * *
75 |
76 | 
77 |
78 | * **GlobalSetting Folder**:
79 | Define some shared parameters both in Client and Server.
80 | * **Model Folder**:
81 | Define some data types and socket packet.
82 | * **Utility Folder**:
83 | Some common functions which used in program.
84 |
85 | * * *
86 |
87 | 
88 |
89 | * **ExampleFile**:
90 | a example update file which is used to test update project.
91 | * **ExecuteProgram**:
92 | a Windows service main program.
93 | * **Install.bat**:
94 | a bat which starts SocketService.
95 | * **ServerSocket**:
96 | a class which runs Server Socket service.
97 | * **Uninstall.bat**:
98 | a bat which stops and deletes SocketService.
99 |
100 | * * *
101 |
102 | 
103 |
104 | * **ApiController Folder**:
105 | the controller returns update file info to Client.
106 |
107 | * * *
108 |
109 | 
110 |
111 | The TestTool completed with DevExpress MVVM Mode.
112 |
113 | * **Preparation: Please run Install.bat to start SocketService in UpdaterService before TestTool**
114 |
115 | * **Step1: Generate Local Registry Info**
116 |
117 | 
118 |
119 | * **Step2: Get Update File Info**
120 |
121 | 
122 |
123 | * **Step3: Download Update Zip File**
124 |
125 | 
126 |
127 | * **Step4: Restart Autodesk Revit**
128 |
129 | 
130 |
131 | * * *
132 |
133 | ### Contact Me
134 |
135 | **E-mail: bim.frankliang@foxmail.com**
136 |
137 | **QQ:1223475343**
138 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/SocketUpdater.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{0F8A1E9D-55CD-4DD2-9B5B-E064D1DCFA5E}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{018A42DE-FB87-4E93-8447-A4943FD74CF3}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{A808CC9E-1438-4C97-803B-62AF378869F9}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdaterClient", "UpdaterClient\UpdaterClient.csproj", "{AA9CA057-BDBC-4291-9CCC-D4B841650F09}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdaterShare", "UpdaterShare\UpdaterShare.csproj", "{0F89CC70-3ACA-4664-873B-B8A9F4D7CEE5}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdaterRestart", "UpdaterRestart\UpdaterRestart.csproj", "{AC48E620-0640-436F-A175-CB6AEE8DF609}"
17 | EndProject
18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tool", "Tool", "{E176292B-B2A6-4C23-8E77-18B22D2ECE48}"
19 | EndProject
20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdaterService", "UpdaterService\UpdaterService.csproj", "{DFD1D238-8962-45C2-B637-5DCD469730F0}"
21 | EndProject
22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdaterWebServer", "UpdaterWebServer\UpdaterWebServer.csproj", "{5441BC1A-9F11-4C61-B1EB-3476D5F1459B}"
23 | EndProject
24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestTool", "TestTool\TestTool.csproj", "{70388986-34DD-46F7-A8DC-50E486DD86BC}"
25 | EndProject
26 | Global
27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
28 | Debug|Any CPU = Debug|Any CPU
29 | Release|Any CPU = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
32 | {AA9CA057-BDBC-4291-9CCC-D4B841650F09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {AA9CA057-BDBC-4291-9CCC-D4B841650F09}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {AA9CA057-BDBC-4291-9CCC-D4B841650F09}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {AA9CA057-BDBC-4291-9CCC-D4B841650F09}.Release|Any CPU.Build.0 = Release|Any CPU
36 | {0F89CC70-3ACA-4664-873B-B8A9F4D7CEE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {0F89CC70-3ACA-4664-873B-B8A9F4D7CEE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {0F89CC70-3ACA-4664-873B-B8A9F4D7CEE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {0F89CC70-3ACA-4664-873B-B8A9F4D7CEE5}.Release|Any CPU.Build.0 = Release|Any CPU
40 | {AC48E620-0640-436F-A175-CB6AEE8DF609}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 | {AC48E620-0640-436F-A175-CB6AEE8DF609}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 | {AC48E620-0640-436F-A175-CB6AEE8DF609}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 | {AC48E620-0640-436F-A175-CB6AEE8DF609}.Release|Any CPU.Build.0 = Release|Any CPU
44 | {DFD1D238-8962-45C2-B637-5DCD469730F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45 | {DFD1D238-8962-45C2-B637-5DCD469730F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
46 | {DFD1D238-8962-45C2-B637-5DCD469730F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
47 | {DFD1D238-8962-45C2-B637-5DCD469730F0}.Release|Any CPU.Build.0 = Release|Any CPU
48 | {5441BC1A-9F11-4C61-B1EB-3476D5F1459B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49 | {5441BC1A-9F11-4C61-B1EB-3476D5F1459B}.Debug|Any CPU.Build.0 = Debug|Any CPU
50 | {5441BC1A-9F11-4C61-B1EB-3476D5F1459B}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {5441BC1A-9F11-4C61-B1EB-3476D5F1459B}.Release|Any CPU.Build.0 = Release|Any CPU
52 | {70388986-34DD-46F7-A8DC-50E486DD86BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
53 | {70388986-34DD-46F7-A8DC-50E486DD86BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
54 | {70388986-34DD-46F7-A8DC-50E486DD86BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
55 | {70388986-34DD-46F7-A8DC-50E486DD86BC}.Release|Any CPU.Build.0 = Release|Any CPU
56 | EndGlobalSection
57 | GlobalSection(SolutionProperties) = preSolution
58 | HideSolutionNode = FALSE
59 | EndGlobalSection
60 | GlobalSection(NestedProjects) = preSolution
61 | {AA9CA057-BDBC-4291-9CCC-D4B841650F09} = {0F8A1E9D-55CD-4DD2-9B5B-E064D1DCFA5E}
62 | {0F89CC70-3ACA-4664-873B-B8A9F4D7CEE5} = {A808CC9E-1438-4C97-803B-62AF378869F9}
63 | {AC48E620-0640-436F-A175-CB6AEE8DF609} = {0F8A1E9D-55CD-4DD2-9B5B-E064D1DCFA5E}
64 | {DFD1D238-8962-45C2-B637-5DCD469730F0} = {018A42DE-FB87-4E93-8447-A4943FD74CF3}
65 | {5441BC1A-9F11-4C61-B1EB-3476D5F1459B} = {018A42DE-FB87-4E93-8447-A4943FD74CF3}
66 | {70388986-34DD-46F7-A8DC-50E486DD86BC} = {E176292B-B2A6-4C23-8E77-18B22D2ECE48}
67 | EndGlobalSection
68 | EndGlobal
69 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace TestTool
10 | {
11 | ///
12 | /// App.xaml 的交互逻辑
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Model/ClientInfoModel.cs:
--------------------------------------------------------------------------------
1 | using DevExpress.Mvvm;
2 |
3 | namespace TestTool.Model
4 | {
5 | public class ClientInfoModel : BindableBase
6 | {
7 | public string RName { get; set; }
8 | public string RValue { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Model/LinkInfos.cs:
--------------------------------------------------------------------------------
1 | using DevExpress.Mvvm;
2 |
3 | namespace TestTool.Model
4 | {
5 | public class LinkInfo:BindableBase
6 | {
7 | public string LName { get; set; }
8 | public string LValue { get; set; }
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Model/RegistryInfoModel.cs:
--------------------------------------------------------------------------------
1 | using DevExpress.Mvvm;
2 |
3 | namespace TestTool.Model
4 | {
5 | public class RegistryInfoModel:BindableBase
6 | {
7 | public string RKey { get; set; }
8 | public string RValue { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // 有关程序集的一般信息由以下
8 | // 控制。更改这些特性值可修改
9 | // 与程序集关联的信息。
10 | [assembly: AssemblyTitle("TestTool")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("China")]
14 | [assembly: AssemblyProduct("TestTool")]
15 | [assembly: AssemblyCopyright("Copyright © China 2017")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | //将 ComVisible 设置为 false 将使此程序集中的类型
20 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
21 | //请将此类型的 ComVisible 特性设置为 true。
22 | [assembly: ComVisible(false)]
23 |
24 | //若要开始生成可本地化的应用程序,请
25 | // 中的 .csproj 文件中
26 | //例如,如果您在源文件中使用的是美国英语,
27 | //使用的是美国英语,请将 设置为 en-US。 然后取消
28 | //对以下 NeutralResourceLanguage 特性的注释。 更新
29 | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //主题特定资源词典所处位置
36 | //(当资源未在页面
37 | //或应用程序资源字典中找到时使用)
38 | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
39 | //(当资源未在页面
40 | //、应用程序或任何主题专用资源字典中找到时使用)
41 | )]
42 |
43 |
44 | // 程序集的版本信息由下列四个值组成:
45 | //
46 | // 主版本
47 | // 次版本
48 | // 生成号
49 | // 修订号
50 | //
51 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
52 | // 方法是按如下所示使用“*”: :
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace TestTool.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// 一个强类型的资源类,用于查找本地化的字符串等。
17 | ///
18 | // 此类是由 StronglyTypedResourceBuilder
19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
21 | // (以 /str 作为命令选项),或重新生成 VS 项目。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// 返回此类使用的缓存的 ResourceManager 实例。
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TestTool.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// 使用此强类型资源类,为所有资源查找
51 | /// 重写当前线程的 CurrentUICulture 属性。
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace TestTool.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/TestTool.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {70388986-34DD-46F7-A8DC-50E486DD86BC}
8 | WinExe
9 | Properties
10 | TestTool
11 | TestTool
12 | v4.5
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | true
17 |
18 |
19 |
20 | AnyCPU
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 | false
29 |
30 |
31 | AnyCPU
32 | pdbonly
33 | true
34 | bin\Release\
35 | TRACE
36 | prompt
37 | 4
38 | false
39 |
40 |
41 |
42 | False
43 | ..\..\..\ThirdParty\DevExpress\DevExpress.Data.v15.2.dll
44 |
45 |
46 | False
47 | ..\..\..\ThirdParty\DevExpress\DevExpress.Mvvm.v15.2.dll
48 |
49 |
50 | False
51 | ..\..\..\ThirdParty\DevExpress\DevExpress.Xpf.Controls.v15.2.dll
52 |
53 |
54 | False
55 | ..\..\..\ThirdParty\DevExpress\DevExpress.Xpf.Core.v15.2.dll
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 4.0
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | MSBuild:Compile
75 | Designer
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | ClientDownLoadPage.xaml
86 |
87 |
88 | ClientRequestInfoPage.xaml
89 |
90 |
91 | RegistryInfoPage.xaml
92 |
93 |
94 | RestartPage.xaml
95 |
96 |
97 | MSBuild:Compile
98 | Designer
99 |
100 |
101 | App.xaml
102 | Code
103 |
104 |
105 | ToolWindow.xaml
106 | Code
107 |
108 |
109 | Designer
110 | MSBuild:Compile
111 |
112 |
113 | Designer
114 | MSBuild:Compile
115 |
116 |
117 | Designer
118 | MSBuild:Compile
119 |
120 |
121 | Designer
122 | MSBuild:Compile
123 |
124 |
125 |
126 |
127 | Code
128 |
129 |
130 | True
131 | True
132 | Resources.resx
133 |
134 |
135 | True
136 | Settings.settings
137 | True
138 |
139 |
140 | ResXFileCodeGenerator
141 | Resources.Designer.cs
142 |
143 |
144 | SettingsSingleFileGenerator
145 | Settings.Designer.cs
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | {aa9ca057-bdbc-4291-9ccc-d4b841650f09}
155 | UpdaterClient
156 |
157 |
158 | {0f89cc70-3aca-4664-873b-b8a9f4d7cee5}
159 | UpdaterShare
160 |
161 |
162 |
163 |
164 |
171 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/ClientDownLoadPage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/ClientDownLoadPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace TestTool.View
17 | {
18 | ///
19 | /// ClientDownLoadPage.xaml 的交互逻辑
20 | ///
21 | public partial class ClientDownLoadPage : UserControl
22 | {
23 | public ClientDownLoadPage()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/ClientRequestInfoPage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/ClientRequestInfoPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace TestTool.View
17 | {
18 | ///
19 | /// ClientRequestInfoPage.xaml 的交互逻辑
20 | ///
21 | public partial class ClientRequestInfoPage : UserControl
22 | {
23 | public ClientRequestInfoPage()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/RegistryInfoPage.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/RegistryInfoPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace TestTool.View
17 | {
18 | ///
19 | /// RegistryInfoPage.xaml 的交互逻辑
20 | ///
21 | public partial class RegistryInfoPage : UserControl
22 | {
23 | public RegistryInfoPage()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/RestartPage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/RestartPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace TestTool.View
17 | {
18 | ///
19 | /// RestartPage.xaml 的交互逻辑
20 | ///
21 | public partial class RestartPage : UserControl
22 | {
23 | public RestartPage()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/ToolWindow.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/View/ToolWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using TestTool.View;
5 | using TestTool.ViewModel;
6 |
7 | namespace TestTool
8 | {
9 | ///
10 | /// MainWindow.xaml 的交互逻辑
11 | ///
12 | public partial class ToolWindow : Window
13 | {
14 | public RegistryInfoPage RegistryPage = null;
15 | public ClientRequestInfoPage RequestInfoPage = null;
16 | public ClientDownLoadPage DownLoadPage = null;
17 | public RestartPage RestartPage = null;
18 |
19 | public ToolWindow()
20 | {
21 | InitializeComponent();
22 | var mainFolder = Path.Combine(Path.GetTempPath(), "BIMProductUpdate");
23 | if (Directory.Exists(mainFolder))
24 | {
25 | Directory.Delete(mainFolder, true);
26 | }
27 |
28 | RegistryPage = new RegistryInfoPage();
29 | RegistryPage.DataContext = new RegistryInfoViewModel();
30 | StepGrid.Children.Add(RegistryPage);
31 | }
32 |
33 | private void CloseBtn_OnClick(object sender, RoutedEventArgs e)
34 | {
35 | Close();
36 | }
37 |
38 | private void Steps_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
39 | {
40 | if (StepGrid == null)
41 | {
42 | return;
43 | }
44 | if (Steplbx.SelectedIndex == 0)
45 | {
46 | if (null == RegistryPage)
47 | {
48 | RegistryPage = new RegistryInfoPage();
49 | RegistryPage.DataContext = new RegistryInfoViewModel();
50 | StepGrid.Children.Add(RegistryPage);
51 | }
52 | HideOtherControl(RegistryPage);
53 | }
54 | if (Steplbx.SelectedIndex == 1)
55 | {
56 | if (null == RequestInfoPage)
57 | {
58 | RequestInfoPage = new ClientRequestInfoPage();
59 | RequestInfoPage.DataContext = new ClientRequestInfoViewModel();
60 | StepGrid.Children.Add(RequestInfoPage);
61 | }
62 | HideOtherControl(RequestInfoPage);
63 | }
64 | if (Steplbx.SelectedIndex == 2)
65 | {
66 | if (null == DownLoadPage)
67 | {
68 | DownLoadPage = new ClientDownLoadPage();
69 | var vm = (ClientRequestInfoViewModel) RequestInfoPage.DataContext;
70 | DownLoadPage.DataContext = new ClientDownLoadViewModel(vm.ClientInfo, vm.DownloadInfo);
71 | StepGrid.Children.Add(DownLoadPage);
72 | }
73 | HideOtherControl(DownLoadPage);
74 | }
75 | if (Steplbx.SelectedIndex == 3)
76 | {
77 | if (null == RestartPage)
78 | {
79 | RestartPage = new RestartPage();
80 | var vm = (ClientRequestInfoViewModel)RequestInfoPage.DataContext;
81 | RestartPage.DataContext = new RestartViewModel(vm.DownloadInfo.LatestProductVersion);
82 | StepGrid.Children.Add(RestartPage);
83 | }
84 | HideOtherControl(RestartPage);
85 | }
86 | }
87 |
88 | private void HideOtherControl(UserControl userCtl)
89 | {
90 | foreach (UIElement child in StepGrid.Children)
91 | {
92 | child.Visibility = Visibility.Hidden;
93 | }
94 | userCtl.Visibility = Visibility.Visible;
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/ViewModel/ClientDownLoadViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Windows;
6 | using System.Windows.Input;
7 | using DevExpress.Mvvm;
8 | using TestTool.Model;
9 | using UpdaterClient;
10 | using UpdaterShare.Model;
11 |
12 | namespace TestTool.ViewModel
13 | {
14 | public class ClientDownLoadViewModel:BindableBase
15 | {
16 | public ObservableCollection LinkInfos { get; set; }
17 | public ICommand DownloadCmd { get; }
18 |
19 | private ClientBasicInfo ClientInfo { get; }
20 | private DownloadFileInfo DownloadInfo { get; }
21 | public ClientDownLoadViewModel(ClientBasicInfo cb, DownloadFileInfo dl)
22 | {
23 | ClientInfo = cb;
24 | DownloadInfo = dl;
25 |
26 | LinkInfos = new ObservableCollection();
27 | InitData();
28 |
29 | DownloadCmd = new DelegateCommand(StartDownload);
30 |
31 | }
32 |
33 | private void InitData()
34 | {
35 | var mainFolder = Path.Combine(Path.GetTempPath(), "BIMProductUpdate");
36 | LinkInfos.Clear();
37 | LinkInfo li1 = new LinkInfo() {LName = "IpString", LValue= "127.0.0.1"};
38 | LinkInfo li2 = new LinkInfo() { LName = "Port", LValue = "8885" };
39 | LinkInfo li3 = new LinkInfo() { LName = "LocalSavePath", LValue = Path.Combine(mainFolder, "downLoad") };
40 | LinkInfo li4 = new LinkInfo() { LName = "TempDirPath", LValue = Path.Combine(mainFolder, "temp") };
41 | LinkInfos.Add(li1);
42 | LinkInfos.Add(li2);
43 | LinkInfos.Add(li3);
44 | LinkInfos.Add(li4);
45 | }
46 |
47 | private void StartDownload()
48 | {
49 | try
50 | {
51 | ClientLinkInfo clInfo = new ClientLinkInfo()
52 | {
53 | IpString = LinkInfos.FirstOrDefault(x => string.Equals(x.LName,"IpString",StringComparison.OrdinalIgnoreCase))?.LValue,
54 | Port = Convert.ToInt32(LinkInfos.FirstOrDefault(x => string.Equals(x.LName, "Port", StringComparison.OrdinalIgnoreCase))?.LValue)
55 | };
56 |
57 | var localSavePath = LinkInfos.FirstOrDefault(x => string.Equals(x.LName,"LocalSavePath", StringComparison.OrdinalIgnoreCase))?.LValue;
58 | var tempDirPath = LinkInfos.FirstOrDefault(x => string.Equals(x.LName,"TempDirPath", StringComparison.OrdinalIgnoreCase))?.LValue;
59 |
60 | var clientSocket = new ClientSocket();
61 | var result = clientSocket.StartClient(ClientInfo, DownloadInfo,clInfo, localSavePath, tempDirPath);
62 | if (result)
63 | {
64 | MessageBox.Show("DownLoad File Success!");
65 | }
66 | else
67 | {
68 | MessageBox.Show("DownLoad File Failed!");
69 | }
70 | }
71 | catch
72 | {
73 | MessageBox.Show("DownLoad File Failed!");
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/ViewModel/ClientRequestInfoViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.Linq;
4 | using System.Windows;
5 | using System.Windows.Input;
6 | using DevExpress.Mvvm;
7 | using Microsoft.Win32;
8 | using TestTool.Model;
9 | using UpdaterClient.Utility;
10 | using UpdaterShare.Model;
11 |
12 | namespace TestTool.ViewModel
13 | {
14 | public class ClientRequestInfoViewModel:BindableBase
15 | {
16 | public ObservableCollection RequestInfos { get; set; }
17 | public ObservableCollection ReceiveInfos { get; set; }
18 | public ICommand ConnectCmd { get; }
19 |
20 | public ClientBasicInfo ClientInfo { get; set; }
21 | public DownloadFileInfo DownloadInfo { get; set; }
22 |
23 | public ClientRequestInfoViewModel()
24 | {
25 | RequestInfos = new ObservableCollection();
26 | ReceiveInfos = new ObservableCollection();
27 | InitData();
28 |
29 | ConnectCmd = new DelegateCommand(ConnectServer);
30 | }
31 |
32 |
33 | private void InitData()
34 | {
35 | RequestInfos.Clear();
36 | ReceiveInfos.Clear();
37 |
38 | var registryPath = @"SOFTWARE\BIMProduct\BIMProduct2018\Revit2016";
39 | var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);
40 |
41 | ClientInfoModel r1 = new ClientInfoModel()
42 | {
43 | RName = "ProductNameInEng",
44 | RValue = RegistryUtils.ReadRegistryInfo(localMachineRegistry, registryPath, "ProductNameInEng")
45 | };
46 |
47 | ClientInfoModel r2 = new ClientInfoModel()
48 | {
49 | RName = "RevitVersion",
50 | RValue = RegistryUtils.ReadRegistryInfo(localMachineRegistry, registryPath, "RevitVersion")
51 | };
52 |
53 |
54 | ClientInfoModel r3 = new ClientInfoModel()
55 | {
56 | RName = "ProductVersion",
57 | RValue = RegistryUtils.ReadRegistryInfo(localMachineRegistry, registryPath, "ProductVersion")
58 | };
59 |
60 | RequestInfos.Add(r1);
61 | RequestInfos.Add(r2);
62 | RequestInfos.Add(r3);
63 |
64 | }
65 |
66 | private void ConnectServer()
67 | {
68 | try
69 | {
70 | ClientBasicInfo cb = new ClientBasicInfo()
71 | {
72 | ProductName = RequestInfos.FirstOrDefault(x => string.Equals(x.RName,"ProductNameInEng", StringComparison.OrdinalIgnoreCase))?.RValue,
73 | RevitVersion = RequestInfos.FirstOrDefault(x => string.Equals(x.RName, "RevitVersion", StringComparison.OrdinalIgnoreCase))?.RValue,
74 | CurrentProductVersion = RequestInfos.FirstOrDefault(x => string.Equals(x.RName,"ProductVersion", StringComparison.OrdinalIgnoreCase))?.RValue
75 | };
76 | ClientInfo = cb;
77 | DownloadFileInfo df = new DownloadFileInfo();
78 |
79 | var result = RequestInfoUtils.RequestDownloadFileInfo(cb, "http://localhost:55756/", "GetFileInfo", "GetInfo", ref df);
80 | DownloadInfo = df;
81 | if (result)
82 | {
83 | ClientInfoModel r1 = new ClientInfoModel()
84 | {
85 | RName = "LatestProductVersion",
86 | RValue = df.LatestProductVersion
87 | };
88 | ClientInfoModel r2 = new ClientInfoModel()
89 | {
90 | RName = "DownloadFileMd5",
91 | RValue = df.DownloadFileMd5
92 | };
93 | ClientInfoModel r3 = new ClientInfoModel()
94 | {
95 | RName = "DownloadFileTotalSize",
96 | RValue = df.DownloadFileTotalSize.ToString()
97 | };
98 | ReceiveInfos.Add(r1);
99 | ReceiveInfos.Add(r2);
100 | ReceiveInfos.Add(r3);
101 | }
102 | else
103 | {
104 | MessageBox.Show("Get DownLoad File Failed!");
105 | }
106 | }
107 | catch
108 | {
109 | MessageBox.Show("Get DownLoad File Failed!");
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/ViewModel/RegistryInfoViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.Windows;
4 | using System.Windows.Input;
5 | using DevExpress.Mvvm;
6 | using Microsoft.Win32;
7 | using TestTool.Model;
8 | using UpdaterClient.Utility;
9 |
10 | namespace TestTool.ViewModel
11 | {
12 | public class RegistryInfoViewModel : BindableBase
13 | {
14 | public ObservableCollection RegistryInfos { get; set; }
15 | public ICommand GenerateCmd { get; }
16 | public ICommand DeleteCmd { get; }
17 | public RegistryInfoViewModel()
18 | {
19 | RegistryInfos = new ObservableCollection();
20 | InitData();
21 |
22 | GenerateCmd = new DelegateCommand(GenerateRegistryInfo);
23 | DeleteCmd = new DelegateCommand(DeleteRegistryInfo);
24 | }
25 |
26 | private void InitData()
27 | {
28 | RegistryInfos.Clear();
29 | RegistryInfoModel r1 = new RegistryInfoModel() { RKey = "InstallationDateTime", RValue = DateTime.Now.ToString()};
30 | RegistryInfoModel r2 = new RegistryInfoModel() { RKey = "InstallationLocation", RValue = @"C:\Program Files\BIMProduct\BIMProductUpdate For Revit 2016\" };
31 | RegistryInfoModel r3 = new RegistryInfoModel() { RKey = "ProductName", RValue = "BIMProduct" };
32 | RegistryInfoModel r4 = new RegistryInfoModel() { RKey = "ProductNameInEng", RValue = "BIMProduct2018" };
33 | RegistryInfoModel r5 = new RegistryInfoModel() { RKey = "ProductVersion", RValue = "18.1.4.0" };
34 | RegistryInfoModel r6 = new RegistryInfoModel() { RKey = "RevitVersion", RValue = "Revit2016" };
35 | RegistryInfos.Add(r1);
36 | RegistryInfos.Add(r2);
37 | RegistryInfos.Add(r3);
38 | RegistryInfos.Add(r4);
39 | RegistryInfos.Add(r5);
40 | RegistryInfos.Add(r6);
41 | }
42 |
43 | private void GenerateRegistryInfo()
44 | {
45 | try
46 | {
47 | var registryPath = @"SOFTWARE\BIMProduct\BIMProduct2018\Revit2016";
48 | var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);
49 | foreach (var r in RegistryInfos)
50 | {
51 | RegistryUtils.CreateRegistryInfo(localMachineRegistry, registryPath, r.RKey, r.RValue);
52 | }
53 | MessageBox.Show("Create Registry Info Success!");
54 | }
55 | catch
56 | {
57 | MessageBox.Show("Create Registry Info Failed!");
58 | }
59 |
60 | }
61 |
62 | private void DeleteRegistryInfo()
63 | {
64 | var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);
65 | var result = RegistryUtils.DeleteRegistryInfo(localMachineRegistry, @"SOFTWARE\BIMProduct");
66 | MessageBox.Show(result ? "Delete Registry Info Success!" : "Delete Registry Info Failed!");
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/TestTool/ViewModel/RestartViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Windows;
5 | using System.Windows.Input;
6 | using System.Xml;
7 | using DevExpress.Mvvm;
8 | using Microsoft.Win32;
9 | using UpdaterClient.Utility;
10 | using UpdaterShare.Utility;
11 |
12 | namespace TestTool.ViewModel
13 | {
14 | public class RestartViewModel:BindableBase
15 | {
16 | public ICommand RestartCmd { get; }
17 | private readonly string _latestVersion;
18 | private bool _isNow = true;
19 |
20 | public bool IsNow
21 | {
22 | get { return _isNow; }
23 | set
24 | {
25 | SetProperty(ref _isNow, value, () => IsNow);
26 | }
27 | }
28 | public RestartViewModel(string latestVersion)
29 | {
30 | _latestVersion = latestVersion;
31 | RestartCmd = new DelegateCommand(RestartRevit);
32 | }
33 |
34 | private void RestartRevit()
35 | {
36 | //Write xml (Temp\BIMProductUpdate\updateinfo.xml)
37 | XmlDocument xmlDoc = new XmlDocument();
38 | XmlNode header = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
39 | xmlDoc.AppendChild(header);
40 | XmlElement rootNode = xmlDoc.CreateElement("UpdateInfo");
41 |
42 | var mainFolder = Path.Combine(Path.GetTempPath(), "BIMProductUpdate");
43 | var updateInfoFile = Path.Combine(mainFolder, "updateinfo.xml");
44 | var registryPath = @"SOFTWARE\BIMProduct\BIMProduct2018\Revit2016";
45 | var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);
46 | RegistryKey rsg = localMachineRegistry.OpenSubKey(registryPath, false);
47 | if (rsg != null)
48 | {
49 | foreach (var kv in rsg.GetValueNames())
50 | {
51 | rootNode.AppendChild(XmlUtils.InsertNode(xmlDoc, "Node", kv,
52 | RegistryUtils.ReadRegistryInfo(Registry.LocalMachine, registryPath, kv)));
53 | }
54 | rootNode.AppendChild(XmlUtils.InsertNode(xmlDoc, "Node", "LatestVersion", _latestVersion));
55 | rootNode.AppendChild(XmlUtils.InsertNode(xmlDoc, "Node", "Status", IsNow ? "Now" : "Auto"));
56 | xmlDoc.AppendChild(rootNode);
57 | xmlDoc.Save(updateInfoFile);
58 |
59 | var updateExeFolderPath = AppDomain.CurrentDomain.BaseDirectory.Replace("TestTool", "UpdaterRestart");
60 | if (!IsNow)
61 | {
62 | BootUtils.CreateLnk("Restart", mainFolder, Path.Combine(updateExeFolderPath, "Restart.vbs"));
63 | }
64 |
65 | //Start Process (UpdaterRestart.exe)
66 | string restartExePath = Path.Combine(updateExeFolderPath, "UpdaterRestart.exe");
67 | Process.Start(restartExePath);
68 | }
69 | else
70 | {
71 | MessageBox.Show("Not Found Registry Info!");
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterClient/ClientSocket.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Net.Sockets;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using UpdaterShare.GlobalSetting;
11 | using UpdaterShare.Model;
12 | using UpdaterShare.Utility;
13 |
14 | namespace UpdaterClient
15 | {
16 | public class ClientSocket
17 | {
18 | private int _downloadChannelsCount;
19 | private bool _isPacketsComplete;
20 | private long _packSize;
21 | private string _updateFileName;
22 | private readonly ManualResetEvent ReceiveDone = new ManualResetEvent(false);
23 | private readonly Dictionary TempReceivePacketDict = new Dictionary();
24 | private readonly Dictionary ResultPacketDict = new Dictionary();
25 |
26 | public bool StartClient(ClientBasicInfo basicInfo, DownloadFileInfo dlInfo, ClientLinkInfo clInfo,
27 | string localSaveFolderPath, string tempFilesDir)
28 | {
29 | if (basicInfo == null || dlInfo == null || clInfo == null ||
30 | string.IsNullOrEmpty(localSaveFolderPath) || string.IsNullOrEmpty(tempFilesDir))
31 | return false;
32 | if (!Directory.Exists(localSaveFolderPath))
33 | {
34 | Directory.CreateDirectory(localSaveFolderPath);
35 | }
36 | if (!Directory.Exists(tempFilesDir))
37 | {
38 | Directory.CreateDirectory(tempFilesDir);
39 | }
40 | else
41 | {
42 | DirectoryInfo di = new DirectoryInfo(tempFilesDir);
43 | di.Delete(true);
44 | Directory.CreateDirectory(tempFilesDir);
45 | }
46 |
47 |
48 | var updateFileName = $"{basicInfo.ProductName}_{basicInfo.RevitVersion}_{basicInfo.CurrentProductVersion}_{dlInfo.LatestProductVersion}";
49 | _updateFileName = updateFileName;
50 |
51 | var localSavePath = Path.Combine(localSaveFolderPath,$"{updateFileName}.zip");
52 | var downloadChannelsCount = DownloadSetting.DownloadChannelsCount;
53 | _downloadChannelsCount = downloadChannelsCount;
54 |
55 | try
56 | {
57 | IPAddress ipAddress = IPAddress.Parse(clInfo.IpString);
58 | IPEndPoint remoteEp = new IPEndPoint(ipAddress, clInfo.Port);
59 |
60 | int packetCount = downloadChannelsCount;
61 | long packetSize = dlInfo.DownloadFileTotalSize / packetCount;
62 | _packSize = packetSize;
63 |
64 |
65 | var tasks = new Task[packetCount];
66 | for (int index = 0; index < packetCount; index++)
67 | {
68 | int packetNumber = index;
69 | var task = new Task(() =>
70 | {
71 | Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
72 | ComObject state = new ComObject { WorkSocket = client, PacketNumber = packetNumber };
73 | client.BeginConnect(remoteEp, ConnectCallback, state);
74 | });
75 | tasks[packetNumber] = task;
76 | task.Start();
77 | }
78 | Task.WaitAll(tasks);
79 | ReceiveDone.WaitOne();
80 |
81 |
82 | _isPacketsComplete = CheckPackets(TempReceivePacketDict, _downloadChannelsCount);
83 | CloseSockets(TempReceivePacketDict);
84 | if (_isPacketsComplete)
85 | {
86 | GenerateTempFiles(ResultPacketDict, downloadChannelsCount, tempFilesDir);
87 | FileUtils.CombineTempFiles(localSavePath, tempFilesDir);
88 | return Md5Utils.IsMd5Equal(dlInfo.DownloadFileMd5, Md5Utils.GetFileMd5(localSavePath));
89 | }
90 | return false;
91 | }
92 | catch(Exception ex)
93 | {
94 | return false;
95 | }
96 | }
97 |
98 | #region Step1:Connection
99 | private void ConnectCallback(IAsyncResult ar)
100 | {
101 | try
102 | {
103 | ComObject state = (ComObject)ar.AsyncState;
104 | Socket client = state.WorkSocket;
105 | client.EndConnect(ar);
106 | FindUpdateFileInfo(client, state.PacketNumber);
107 | }
108 | catch
109 | {
110 |
111 | }
112 | }
113 | #endregion
114 |
115 |
116 | #region Step2:Find Update File According to ProductName and Latest Version
117 | private void FindUpdateFileInfo(Socket client, int packetNumber)
118 | {
119 | ComObject state = new ComObject { WorkSocket = client, PacketNumber = packetNumber };
120 | byte[] byteData = PacketUtils.PacketData(PacketUtils.ClientFindFileInfoTag(), Encoding.UTF8.GetBytes(_updateFileName));
121 | client.BeginSend(byteData, 0, byteData.Length, 0, FindUpdateFileCallback, state);
122 | }
123 | private void FindUpdateFileCallback(IAsyncResult ar)
124 | {
125 | try
126 | {
127 | ComObject state = (ComObject)ar.AsyncState;
128 | Socket client = state.WorkSocket;
129 | client.EndSend(ar);
130 | client.BeginReceive(state.Buffer, 0, ComObject.BufferSize, 0, FoundFileCallback, state);
131 | }
132 | catch
133 | {
134 |
135 | }
136 | }
137 | private void FoundFileCallback(IAsyncResult ar)
138 | {
139 | try
140 | {
141 | ComObject state = (ComObject)ar.AsyncState;
142 | Socket client = state.WorkSocket;
143 | int packetNumber = state.PacketNumber;
144 | int bytesRead = client.EndReceive(ar);
145 | if (bytesRead > 0)
146 | {
147 | var receiveData = state.Buffer.Take(bytesRead).ToArray();
148 | var dataList = PacketUtils.SplitBytes(receiveData, PacketUtils.ServerFoundFileInfoTag());
149 | if (dataList != null && dataList.Any())
150 | {
151 | SendFileStartPositionInfo(client, packetNumber, _packSize);
152 | }
153 | }
154 | }
155 | catch
156 | {
157 |
158 | }
159 | }
160 | #endregion
161 |
162 |
163 | #region Step3:Request Packets of UpdateFile and Ready to Receive File
164 | private void SendFileStartPositionInfo(Socket client, int packetNumber, long packSize)
165 | {
166 | ComObject state = new ComObject { WorkSocket = client };
167 | byte[] byteData = PacketUtils.PacketData(PacketUtils.ClientRequestFileTag(), BitConverter.GetBytes(packetNumber * packSize));
168 | client.BeginSend(byteData, 0, byteData.Length, 0, SendFileRequestCallback, state);
169 | }
170 | private void SendFileRequestCallback(IAsyncResult ar)
171 | {
172 | try
173 | {
174 | ComObject state = (ComObject)ar.AsyncState;
175 | Socket client = state.WorkSocket;
176 | client.EndSend(ar);
177 | client.BeginReceive(state.Buffer, 0, ComObject.BufferSize, 0, ReceiveFileCallback, state);
178 | }
179 | catch
180 | {
181 |
182 | }
183 | }
184 |
185 |
186 | private void ReceiveFileCallback(IAsyncResult ar)
187 | {
188 | try
189 | {
190 | ComObject state = (ComObject)ar.AsyncState;
191 | Socket client = state.WorkSocket;
192 | int bytesRead = client.EndReceive(ar);
193 | Console.WriteLine(bytesRead);
194 |
195 | if (bytesRead > 0)
196 | {
197 | if (TempReceivePacketDict.ContainsKey(client))
198 | {
199 | TempReceivePacketDict[client] =
200 | TempReceivePacketDict[client].Concat(state.Buffer.Take(bytesRead)).ToArray();
201 | }
202 | else
203 | {
204 | TempReceivePacketDict.Add(client, state.Buffer.Take(bytesRead).ToArray());
205 | }
206 | client.BeginReceive(state.Buffer, 0, ComObject.BufferSize, 0, ReceiveFileCallback, state);
207 | }
208 | else
209 | {
210 | if (TempReceivePacketDict.Count == _downloadChannelsCount)
211 | {
212 | ReceiveDone.Set();
213 | }
214 | }
215 | }
216 | catch
217 | {
218 |
219 | }
220 | }
221 | #endregion
222 |
223 |
224 | #region Step4:Check Packets
225 | private bool CheckPackets(Dictionary dictionary, int downloadChannelsCount)
226 | {
227 | foreach (var socket in dictionary.Keys)
228 | {
229 | var response = dictionary[socket];
230 | var packets = PacketUtils.SplitBytes(response, PacketUtils.ServerResponseFileTag());
231 | if (packets != null && packets.Any())
232 | {
233 | var result = packets.FirstOrDefault();
234 | if (Crc16Utils.CheckCrcCode(result) && PacketUtils.IsPacketComplete(result))
235 | {
236 | var packetNumber = PacketUtils.GetResponsePacketNumber(result);
237 | var data = PacketUtils.GetData(PacketUtils.ServerResponseFileTag(), result);
238 | if (!ResultPacketDict.ContainsKey(packetNumber))
239 | {
240 | ResultPacketDict.Add(packetNumber, data);
241 | }
242 | }
243 | }
244 | }
245 | return ResultPacketDict.Count == downloadChannelsCount;
246 | }
247 | #endregion
248 |
249 |
250 | #region Step5:Close Sockets
251 | private void CloseSockets(Dictionary tempReceivePacketDict)
252 | {
253 | foreach (var socket in tempReceivePacketDict.Keys)
254 | {
255 | socket.Shutdown(SocketShutdown.Both);
256 | socket.Close();
257 | }
258 | }
259 | #endregion
260 |
261 |
262 | #region Step6:Generate Temp Flies
263 | private void GenerateTempFiles(Dictionary dictionary, int downloadChannelsCount, string tempFilesDir)
264 | {
265 | dictionary = dictionary.OrderBy(x => x.Key).ToDictionary(x => x.Key, y => y.Value);
266 | foreach (var packetNumber in dictionary.Keys)
267 | {
268 | var data = ResultPacketDict[packetNumber];
269 | string tempfilepath = Path.Combine(tempFilesDir, $"{packetNumber}_{downloadChannelsCount}");
270 | FileUtils.GenerateTempFile(tempfilepath, data);
271 | }
272 | }
273 | #endregion
274 | }
275 | }
276 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterClient/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("UpdaterClient")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("China")]
12 | [assembly: AssemblyProduct("UpdaterClient")]
13 | [assembly: AssemblyCopyright("Copyright © China 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | //将 ComVisible 设置为 false 将使此程序集中的类型
18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("aa9ca057-bdbc-4291-9ccc-d4b841650f09")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterClient/UpdaterClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {AA9CA057-BDBC-4291-9CCC-D4B841650F09}
8 | Library
9 | Properties
10 | UpdaterClient
11 | UpdaterClient
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 | ..\..\..\ThirdParty\Newtonsoft.Json\Newtonsoft.Json.dll
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | {0f89cc70-3aca-4664-873b-b8a9f4d7cee5}
57 | UpdaterShare
58 |
59 |
60 |
61 |
62 | {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}
63 | 1
64 | 0
65 | 0
66 | tlbimp
67 | False
68 | True
69 |
70 |
71 |
72 |
79 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterClient/Utility/BootUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using IWshRuntimeLibrary;
4 | using File = System.IO.File;
5 |
6 | namespace UpdaterClient.Utility
7 | {
8 | public static class BootUtils
9 | {
10 | ///
11 | /// Create lnk for Restart.vbs in Startup Folder
12 | ///
13 | ///
14 | /// Some dirs can't create lnk!
15 | /// path must with extenstion!
16 | ///
17 | public static bool CreateLnk(string lnkNameWithoutExt, string lnkTempDirPath, string vbScriptPath)
18 | {
19 | if (string.IsNullOrEmpty(lnkNameWithoutExt) || string.IsNullOrEmpty(lnkTempDirPath) ||
20 | string.IsNullOrEmpty(vbScriptPath)) return false;
21 | if (!Directory.Exists(lnkTempDirPath))
22 | {
23 | Directory.CreateDirectory(lnkTempDirPath);
24 | }
25 | try
26 | {
27 | if (!File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + $"\\{lnkNameWithoutExt}.lnk"))
28 | {
29 | var shell = new WshShell();
30 | var shortcut = (IWshShortcut)shell.CreateShortcut(Path.Combine(lnkTempDirPath, $"{lnkNameWithoutExt}.lnk"));
31 | shortcut.WorkingDirectory = Path.GetDirectoryName(vbScriptPath);
32 | shortcut.TargetPath = vbScriptPath;
33 | shortcut.WindowStyle = 7;
34 | shortcut.Save();
35 | var sourcePath = Path.Combine(lnkTempDirPath, $"{lnkNameWithoutExt}.lnk");
36 | var destPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup) +$"\\{lnkNameWithoutExt}.lnk";
37 | File.Copy(sourcePath, destPath);
38 | return File.Exists(destPath);
39 | }
40 | }
41 | catch
42 | {
43 | return false;
44 | }
45 | return false;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterClient/Utility/RegistryUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.AccessControl;
3 | using Microsoft.Win32;
4 |
5 | namespace UpdaterClient.Utility
6 | {
7 | public static class RegistryUtils
8 | {
9 | ///
10 | /// Read Registry Info
11 | ///
12 | ///
13 | ///
14 | ///
15 | ///
16 | public static string ReadRegistryInfo(RegistryKey registryKey, string registryInfoPath, string keyName)
17 | {
18 | if (registryKey == null ||string.IsNullOrEmpty(registryInfoPath) || string.IsNullOrEmpty(keyName)) return null;
19 | try
20 | {
21 | RegistryKey rsg = registryKey.OpenSubKey(registryInfoPath, false);
22 | if (rsg != null)
23 | {
24 | var result = rsg?.GetValue(keyName).ToString();
25 | rsg.Close();
26 | return result;
27 | }
28 | return null;
29 | }
30 | catch
31 | {
32 | return null;
33 | }
34 | }
35 |
36 |
37 | ///
38 | /// Write Registry Info
39 | ///
40 | ///
41 | ///
42 | ///
43 | ///
44 | ///
45 | public static bool WriteRegistryInfo(RegistryKey registryKey, string registryInfoPath, string keyName, string value)
46 | {
47 | if (registryKey == null || string.IsNullOrEmpty(registryInfoPath) || string.IsNullOrEmpty(keyName) || string.IsNullOrEmpty(value)) return false;
48 | try
49 | {
50 | RegistryKey rsg = registryKey.OpenSubKey(registryInfoPath,
51 | RegistryKeyPermissionCheck.ReadWriteSubTree,
52 | RegistryRights.FullControl);
53 | if (rsg != null)
54 | {
55 | rsg.SetValue(keyName, value);
56 | rsg.Close();
57 | return true;
58 | }
59 | return false;
60 | }
61 | catch
62 | {
63 | return false;
64 | }
65 | }
66 |
67 |
68 | ///
69 | /// Create Registry Info
70 | ///
71 | ///
72 | ///
73 | ///
74 | ///
75 | ///
76 | public static bool CreateRegistryInfo(RegistryKey registryKey, string registryInfoPath, string keyName, string value)
77 | {
78 | if (registryKey == null || string.IsNullOrEmpty(registryInfoPath) || string.IsNullOrEmpty(keyName) || string.IsNullOrEmpty(value)) return false;
79 | try
80 | {
81 | RegistryKey rsg = registryKey.CreateSubKey(registryInfoPath);
82 | if (rsg != null)
83 | {
84 | WriteRegistryInfo(registryKey, registryInfoPath, keyName, value);
85 | rsg.Close();
86 | return true;
87 | }
88 | return false;
89 | }
90 | catch
91 | {
92 | return false;
93 | }
94 | }
95 |
96 |
97 | ///
98 | /// Delete Registry Info
99 | ///
100 | ///
101 | ///
102 | ///
103 | public static bool DeleteRegistryInfo(RegistryKey registryKey, string registryInfoPath)
104 | {
105 | if (registryKey == null || string.IsNullOrEmpty(registryInfoPath)) return false;
106 | try
107 | {
108 | registryKey.DeleteSubKeyTree(registryInfoPath, true);
109 | return true;
110 | }
111 | catch(Exception e)
112 | {
113 | Console.WriteLine(e.Message);
114 | return false;
115 | }
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterClient/Utility/RequestInfoUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 | using Newtonsoft.Json;
6 | using UpdaterShare.Model;
7 |
8 | namespace UpdaterClient.Utility
9 | {
10 | public static class RequestInfoUtils
11 | {
12 | ///
13 | /// Get Download File Info
14 | ///
15 | ///
16 | ///
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static bool RequestDownloadFileInfo(ClientBasicInfo basicInfo,
22 | string serverAddress,
23 | string controllerName,
24 | string actionName,
25 | ref DownloadFileInfo serverResult)
26 | {
27 | var packageInfo = JsonConvert.SerializeObject(basicInfo);
28 |
29 | try
30 | {
31 | HttpClient httpClient = new HttpClient
32 | {
33 | BaseAddress = new Uri(serverAddress),
34 | Timeout = TimeSpan.FromMinutes(20)
35 | };
36 |
37 | if (ConnectionTest(serverAddress))
38 | {
39 | StringContent strData = new StringContent(packageInfo, Encoding.UTF8, "application/json");
40 | string postUrl = httpClient.BaseAddress + $"api/{controllerName}/{actionName}";
41 | Uri address = new Uri(postUrl);
42 | Task task = httpClient.PostAsync(address, strData);
43 | try
44 | {
45 | task.Wait();
46 | }
47 | catch
48 | {
49 | return false;
50 | }
51 | HttpResponseMessage response = task.Result;
52 | if (!response.IsSuccessStatusCode)
53 | return false;
54 |
55 | try
56 | {
57 | string jsonResult = response.Content.ReadAsStringAsync().Result;
58 | serverResult = JsonConvert.DeserializeObject(jsonResult);
59 | if (serverResult != null)
60 | {
61 | return true;
62 | }
63 | }
64 | catch(Exception ex)
65 | {
66 | return false;
67 | }
68 | }
69 | }
70 | catch
71 | {
72 | return false;
73 | }
74 | return false;
75 | }
76 |
77 |
78 | ///
79 | /// Connection Test
80 | ///
81 | ///
82 | ///
83 | private static bool ConnectionTest(string serverAddress)
84 | {
85 | if (string.IsNullOrEmpty(serverAddress)) return false;
86 | HttpClient httpClient = new HttpClient
87 | {
88 | BaseAddress = new Uri(serverAddress),
89 | Timeout = TimeSpan.FromSeconds(30)
90 | };
91 |
92 | Uri address = new Uri(httpClient.BaseAddress + "api/Connection/ConnectionTest");
93 | Task task = httpClient.GetAsync(address);
94 | try
95 | {
96 | task.Wait();
97 | }
98 | catch
99 | {
100 | return false;
101 | }
102 |
103 |
104 | HttpResponseMessage response = task.Result;
105 | if (!response.IsSuccessStatusCode)
106 | return false;
107 |
108 | string connectionResult;
109 | try
110 | {
111 | var result = response.Content.ReadAsStringAsync().Result;
112 | connectionResult = JsonConvert.DeserializeObject(result);
113 | }
114 | catch
115 | {
116 | return false;
117 | }
118 | return connectionResult.Equals("connected_success");
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/ExampleFile/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ex1.dll
4 | ex2.xml
5 | ex3.ico
6 | ex4.ttf
7 | ex5.dll
8 |
9 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/ExampleFile/updateInfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/ExecuteUpdate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using Microsoft.Win32;
5 | using UpdaterClient.Utility;
6 | using UpdaterRestart.Utility;
7 | using UpdaterShare.Utility;
8 |
9 | namespace UpdaterRestart
10 | {
11 | public class ExecuteUpdate
12 | {
13 | static void Main(string[] args)
14 | {
15 | var mainFolder = Path.Combine(Path.GetTempPath(), "BIMProductUpdate");
16 | //Temp\BIMProductUpdate\updateinfo.xml
17 | var updateInfoFile = Path.Combine(mainFolder, "updateinfo.xml");
18 | if (!File.Exists(updateInfoFile)) return;
19 |
20 | //Temp\BIMProductUpdate\downLoad
21 | var zipFolder = Path.Combine(mainFolder, "downLoad");
22 | if (!Directory.Exists(zipFolder)) return;
23 | var zipFile = Directory.GetFiles(zipFolder).FirstOrDefault(x => x.Contains(".zip"));
24 | if (string.IsNullOrEmpty(zipFile)) return;
25 |
26 | //Temp\BIMProductUpdate\updateFiles
27 | var unzipFolder = Path.Combine(mainFolder, "updateFiles");
28 | if (!Directory.Exists(unzipFolder))
29 | {
30 | Directory.CreateDirectory(unzipFolder);
31 | }
32 |
33 | //Unzip
34 | using (FileStream zipReadStream = new FileStream(zipFile, FileMode.Open, FileAccess.Read))
35 | {
36 | ZipUtils.UnZip(zipReadStream, unzipFolder);
37 | }
38 | var unzipFilesFolder = Path.Combine(unzipFolder, Path.GetFileNameWithoutExtension(zipFile));
39 | if (!Directory.Exists(unzipFilesFolder)) return;
40 | var unzipFiles = Directory.GetFiles(unzipFilesFolder);
41 | foreach (var file in unzipFiles)
42 | {
43 | File.Copy(file, Path.Combine(unzipFolder, Path.GetFileName(file)),true);
44 | }
45 | Directory.Delete(unzipFilesFolder, true);
46 |
47 |
48 |
49 | //See ExampleFile/updateInfo.xml
50 | var installationLocation = XmlUtils.GetValueByKey(updateInfoFile, "UpdateInfo", "InstallationLocation");
51 | var revitVersion = XmlUtils.GetValueByKey(updateInfoFile, "UpdateInfo", "RevitVersion");
52 | var latestVersion = XmlUtils.GetValueByKey(updateInfoFile, "UpdateInfo", "LatestVersion");
53 | var status = XmlUtils.GetValueByKey(updateInfoFile, "UpdateInfo", "Status");
54 |
55 | var registryPath = $"SOFTWARE\\BIMProduct\\BIMProduct2018\\{revitVersion}";
56 | var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);
57 | if (string.Equals(status, "Now", StringComparison.CurrentCultureIgnoreCase))
58 | {
59 | string revitExePath = string.Empty;
60 | var isKilled = ProcessUtils.KillProcess("Revit", ref revitExePath);
61 | if (!isKilled) return;
62 | var isCovered = ReplaceFilesUtils.CoverFiles(installationLocation, unzipFolder);
63 | if (!isCovered) return;
64 | try
65 | {
66 | Directory.Delete(mainFolder);
67 | RegistryUtils.WriteRegistryInfo(localMachineRegistry, registryPath, "ProductVersion", latestVersion);
68 | RegistryUtils.WriteRegistryInfo(localMachineRegistry, registryPath, "InstallationDateTime",
69 | DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
70 | ProcessUtils.StartProcess(revitExePath);
71 | }
72 | catch
73 | {
74 |
75 | }
76 | }
77 |
78 | else if (string.Equals(status, "Auto", StringComparison.CurrentCultureIgnoreCase))
79 | {
80 | var isCovered = ReplaceFilesUtils.CoverFiles(installationLocation, unzipFolder);
81 | if (!isCovered) return;
82 | try
83 | {
84 | Directory.Delete(mainFolder,true);
85 | RegistryUtils.WriteRegistryInfo(Registry.LocalMachine, registryPath, "ProductVersion", latestVersion);
86 | RegistryUtils.WriteRegistryInfo(Registry.LocalMachine, registryPath, "InstallationDateTime",
87 | DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
88 | File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.Startup)+ "\\Restart.lnk");
89 | }
90 | catch
91 | {
92 |
93 | }
94 | }
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("UpdaterRestart")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("China")]
12 | [assembly: AssemblyProduct("UpdaterRestart")]
13 | [assembly: AssemblyCopyright("Copyright © China 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | //将 ComVisible 设置为 false 将使此程序集中的类型
18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("ac48e620-0640-436f-a175-cb6aee8df609")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/Restart.vbs:
--------------------------------------------------------------------------------
1 | Set shell = Wscript.createobject("WScript.Shell")
2 | shell.Run "UpdaterRestart.exe",0,False
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/UpdaterRestart.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {AC48E620-0640-436F-A175-CB6AEE8DF609}
8 | Exe
9 | Properties
10 | UpdaterRestart
11 | UpdaterRestart
12 | v4.5
13 | 512
14 | true
15 |
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 | false
27 |
28 |
29 | AnyCPU
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 | false
37 |
38 |
39 | app.manifest
40 |
41 |
42 |
43 | ..\..\..\ThirdParty\ICSharpCode\ICSharpCode.SharpZipLib.dll
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | {aa9ca057-bdbc-4291-9ccc-d4b841650f09}
67 | UpdaterClient
68 |
69 |
70 | {0f89cc70-3aca-4664-873b-b8a9f4d7cee5}
71 | UpdaterShare
72 |
73 |
74 |
75 |
76 |
77 |
78 | PreserveNewest
79 |
80 |
81 |
82 |
89 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/Utility/ProcessUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace UpdaterRestart.Utility
4 | {
5 | public static class ProcessUtils
6 | {
7 | ///
8 | /// Kill Process by Process Name
9 | ///
10 | ///
11 | ///
12 | ///
13 | public static bool KillProcess(string processName, ref string processPath)
14 | {
15 | if (string.IsNullOrEmpty(processName)) return false;
16 | try
17 | {
18 | Process[] ps = Process.GetProcessesByName("Revit");
19 | foreach (Process p in ps)
20 | {
21 | processPath = p.MainModule.FileName;
22 | p.Kill();
23 | }
24 | return true;
25 | }
26 | catch
27 | {
28 | return false;
29 | }
30 | }
31 |
32 |
33 | ///
34 | /// Start Process by its Path
35 | ///
36 | ///
37 | public static void StartProcess(string processPath)
38 | {
39 | try
40 | {
41 | Process.Start(processPath);
42 | }
43 | catch
44 | {
45 |
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/Utility/ReplaceFilesUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Xml;
5 |
6 | namespace UpdaterRestart.Utility
7 | {
8 | public static class ReplaceFilesUtils
9 | {
10 | ///
11 | /// Replace Old Files With New Ones
12 | /// See ...\ExampleFile\config.xml
13 | ///
14 | ///
15 | ///
16 | ///
17 | public static bool CoverFiles(string installLocation, string unzipFolder)
18 | {
19 | if (string.IsNullOrEmpty(installLocation) || string.IsNullOrEmpty(unzipFolder)) return false;
20 | if (!Directory.Exists(unzipFolder)) return false;
21 | try
22 | {
23 | string[] xmlFiles = Directory.GetFiles(unzipFolder, "*.xml");
24 | var configFile = xmlFiles.FirstOrDefault(x => x.Contains("config.xml"));
25 | if (configFile != null)
26 | {
27 | XmlDocument xmlDoc = new XmlDocument();
28 | xmlDoc.Load(configFile);
29 | XmlNode xmlRootNode = xmlDoc.SelectSingleNode("UpdateLocation");
30 | if (xmlRootNode != null)
31 | {
32 | XmlNodeList xnl = xmlRootNode.ChildNodes;
33 | if (xnl.Count > 0)
34 | {
35 | foreach (XmlNode xn in xnl)
36 | {
37 | XmlElement xe = (XmlElement) xn;
38 | string dirName = xe.GetAttribute("FilePath");
39 | string fileName = xn.InnerText;
40 |
41 | string mainDir = dirName.Substring(0, dirName.IndexOf('\\'));
42 | string restDir = dirName.Substring(dirName.IndexOf('\\') + 1);
43 | mainDir = GetFolderPath(mainDir, installLocation);
44 |
45 | string updateDir = Path.Combine(mainDir, restDir);
46 | if (!string.IsNullOrEmpty(fileName))
47 | {
48 | string sourceFileName = Path.Combine(unzipFolder, fileName);
49 | string destFileName = Path.Combine(updateDir, fileName);
50 | if (!Directory.Exists(updateDir))
51 | {
52 | Directory.CreateDirectory(updateDir);
53 | }
54 | File.Copy(sourceFileName, destFileName, true);
55 | }
56 | else
57 | {
58 | //if InnerText is null, delete this file or folder
59 | string deleteFileOrFolderPath = updateDir;
60 | if (File.Exists(deleteFileOrFolderPath))
61 | {
62 | File.Delete(deleteFileOrFolderPath);
63 | }
64 | else if (Directory.Exists(deleteFileOrFolderPath))
65 | {
66 | Directory.Delete(deleteFileOrFolderPath,true);
67 | }
68 | }
69 | }
70 | return true;
71 | }
72 | return false;
73 | }
74 | return false;
75 | }
76 | return false;
77 | }
78 | catch
79 | {
80 | return false;
81 | }
82 | }
83 |
84 |
85 | ///
86 | /// Get Special Folder From config.xml
87 | ///
88 | ///
89 | ///
90 | ///
91 | private static string GetFolderPath(string mainFolderName, string installLocation)
92 | {
93 | switch (mainFolderName)
94 | {
95 | //C:\Windows\Fonts
96 | case "Fonts":
97 | return Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
98 |
99 | //C:\Program Files
100 | case "ProgramFiles":
101 | return Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
102 |
103 | //C:\Program Files(x86)
104 | case "ProgramFilesX86":
105 | return Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
106 |
107 | //C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
108 | case "Startup":
109 | return Environment.GetFolderPath(Environment.SpecialFolder.Startup);
110 |
111 | // ProgramData
112 | case "CommonApplicationData":
113 | return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
114 |
115 | // C:\Users\\AppData\Local
116 | case "LocalApplicationData":
117 | return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
118 |
119 | // Default Install Location
120 | default:
121 | return installLocation;
122 | }
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/Utility/ZipUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using ICSharpCode.SharpZipLib.Checksums;
4 | using ICSharpCode.SharpZipLib.Zip;
5 |
6 | namespace UpdaterRestart.Utility
7 | {
8 | public static class ZipUtils
9 | {
10 | #region Zip
11 | ///
12 | /// Zip File
13 | ///
14 | ///
15 | ///
16 | public static bool CreateZip(string sourceFilePath, string destinationZipFilePath)
17 | {
18 | if (string.IsNullOrEmpty(sourceFilePath) || string.IsNullOrEmpty(destinationZipFilePath)) return false;
19 | try
20 | {
21 | if (sourceFilePath[sourceFilePath.Length - 1] != Path.DirectorySeparatorChar)
22 | sourceFilePath += Path.DirectorySeparatorChar;
23 | ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationZipFilePath));
24 | zipStream.SetLevel(6); // 压缩级别 0-9
25 | var isCreateSuccess = CreateZipFiles(sourceFilePath, zipStream);
26 | if (isCreateSuccess)
27 | {
28 | zipStream.Finish();
29 | zipStream.Close();
30 | return true;
31 | }
32 | return false;
33 | }
34 | catch
35 | {
36 | return false;
37 | }
38 | }
39 |
40 |
41 | ///
42 | /// Create Zip File
43 | ///
44 | ///
45 | ///
46 | private static bool CreateZipFiles(string sourceFilePath, ZipOutputStream zipStream)
47 | {
48 | try
49 | {
50 | Crc32 crc = new Crc32();
51 | string[] filesArray = Directory.GetFileSystemEntries(sourceFilePath);
52 | foreach (string file in filesArray)
53 | {
54 | if (Directory.Exists(file))
55 | {
56 | CreateZipFiles(file, zipStream);
57 | }
58 | else
59 | {
60 | FileStream fileStream = File.OpenRead(file);
61 | byte[] buffer = new byte[fileStream.Length];
62 | fileStream.Read(buffer, 0, buffer.Length);
63 | string tempFile = file.Substring(sourceFilePath.LastIndexOf("\\", StringComparison.Ordinal) + 1);
64 | ZipEntry entry = new ZipEntry(tempFile)
65 | {
66 | DateTime = DateTime.Now,
67 | Size = fileStream.Length
68 | };
69 | fileStream.Close();
70 | crc.Reset();
71 | crc.Update(buffer);
72 | entry.Crc = crc.Value;
73 | zipStream.PutNextEntry(entry);
74 | zipStream.Write(buffer, 0, buffer.Length);
75 | }
76 | }
77 | return true;
78 | }
79 | catch
80 | {
81 | return false;
82 | }
83 | }
84 | #endregion
85 |
86 |
87 |
88 | #region Unzip
89 | public static bool UnZip(Stream stream, string targetPath)
90 | {
91 | try
92 | {
93 | using (ZipInputStream zipInStream = new ZipInputStream(stream))
94 | {
95 | ZipEntry entry;
96 | while ((entry = zipInStream.GetNextEntry()) != null)
97 | {
98 | string directorName = Path.Combine(targetPath, Path.GetDirectoryName(entry.Name));
99 | string fileName = Path.Combine(directorName, Path.GetFileName(entry.Name));
100 | if (directorName.Length > 0)
101 | {
102 | Directory.CreateDirectory(directorName);
103 | }
104 | if (fileName != string.Empty && !entry.IsDirectory)
105 | {
106 | using (FileStream streamWriter = File.Create(fileName))
107 | {
108 | byte[] data = new byte[4 * 1024];
109 | while (true)
110 | {
111 | var size = zipInStream.Read(data, 0, data.Length);
112 | if (size > 0)
113 | {
114 | streamWriter.Write(data, 0, size);
115 | }
116 | else break;
117 | }
118 | }
119 | }
120 | }
121 | return true;
122 | }
123 | }
124 | catch
125 | {
126 | return false;
127 | }
128 | }
129 | #endregion
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterRestart/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
51 |
58 |
59 |
60 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/ExampleFile/BIMProduct2018_Revit2016_18.1.4.0_18.1.5.0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Source/SocketUpdater/UpdaterService/ExampleFile/BIMProduct2018_Revit2016_18.1.4.0_18.1.5.0.zip
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/ExecuteProgram.cs:
--------------------------------------------------------------------------------
1 | using System.ServiceProcess;
2 |
3 | namespace UpdaterService
4 | {
5 | static class ExecuteProgram
6 | {
7 | static void Main()
8 | {
9 | var servicesToRun = new ServiceBase[]
10 | {
11 | new SocketService()
12 | };
13 | ServiceBase.Run(servicesToRun);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/Install.bat:
--------------------------------------------------------------------------------
1 | %SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe UpdaterService.exe
2 | Net Start SocketService
3 | sc config SocketService start= auto
4 | pause
5 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/ProjectInstaller.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace UpdaterService
2 | {
3 | partial class ProjectInstaller
4 | {
5 | ///
6 | /// 必需的设计器变量。
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// 清理所有正在使用的资源。
12 | ///
13 | /// 如果应释放托管资源,为 true;否则为 false。
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region 组件设计器生成的代码
24 |
25 | ///
26 | /// 设计器支持所需的方法 - 不要修改
27 | /// 使用代码编辑器修改此方法的内容。
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
32 | this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
33 | //
34 | // serviceProcessInstaller1
35 | //
36 | this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
37 | this.serviceProcessInstaller1.Password = null;
38 | this.serviceProcessInstaller1.Username = null;
39 | //
40 | // serviceInstaller1
41 | //
42 | this.serviceInstaller1.Description = "Airforce094_Updater";
43 | this.serviceInstaller1.DisplayName = "SocketService";
44 | this.serviceInstaller1.ServiceName = "SocketService";
45 | //
46 | // ProjectInstaller
47 | //
48 | this.Installers.AddRange(new System.Configuration.Install.Installer[] {
49 | this.serviceProcessInstaller1,
50 | this.serviceInstaller1});
51 |
52 | }
53 |
54 | #endregion
55 |
56 | private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
57 | private System.ServiceProcess.ServiceInstaller serviceInstaller1;
58 | }
59 | }
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/ProjectInstaller.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Configuration.Install;
3 |
4 | namespace UpdaterService
5 | {
6 | [RunInstaller(true)]
7 | public partial class ProjectInstaller : Installer
8 | {
9 | public ProjectInstaller()
10 | {
11 | InitializeComponent();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/ProjectInstaller.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 56
122 |
123 |
124 | 208, 17
125 |
126 |
127 | False
128 |
129 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("UpdaterService")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("China")]
12 | [assembly: AssemblyProduct("UpdaterService")]
13 | [assembly: AssemblyCopyright("Copyright © China 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | //将 ComVisible 设置为 false 将使此程序集中的类型
18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("dfd1d238-8962-45c2-b637-5dcd469730f0")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/ServerSocket.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Sockets;
6 | using System.Threading;
7 | using UpdaterShare.GlobalSetting;
8 | using UpdaterShare.Model;
9 | using UpdaterShare.Utility;
10 |
11 | namespace UpdaterService
12 | {
13 | public static class ServerSocket
14 | {
15 | private static int _downloadChannelsCount;
16 | private static string _serverPath;
17 | private static readonly ManualResetEvent AllDone = new ManualResetEvent(false);
18 |
19 | public static void StartServer(int port, int backlog)
20 | {
21 | _downloadChannelsCount = DownloadSetting.DownloadChannelsCount;
22 | try
23 | {
24 | IPAddress ipAddress = IPAddress.Any;
25 | IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
26 | Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
27 | listener.Bind(localEndPoint);
28 | listener.Listen(backlog);
29 |
30 | while (true)
31 | {
32 | AllDone.Reset();
33 | listener.BeginAccept(AcceptCallback, listener);
34 | AllDone.WaitOne();
35 | }
36 | }
37 | catch (Exception ex)
38 | {
39 | var path = $"{AppDomain.CurrentDomain.BaseDirectory}\\RunLog.txt";
40 | File.AppendAllText(path, ex.Message);
41 | }
42 | }
43 |
44 |
45 | private static void AcceptCallback(IAsyncResult ar)
46 | {
47 | AllDone.Set();
48 | Socket listener = (Socket)ar.AsyncState;
49 | Socket handler = listener.EndAccept(ar);
50 | ComObject state = new ComObject { WorkSocket = handler };
51 | handler.BeginReceive(state.Buffer, 0, ComObject.BufferSize, 0, FindUpdateFileCallback, state);
52 | }
53 |
54 |
55 | private static void FindUpdateFileCallback(IAsyncResult ar)
56 | {
57 | ComObject state = (ComObject)ar.AsyncState;
58 | Socket handler = state.WorkSocket;
59 | int bytesRead = handler.EndReceive(ar);
60 | if (bytesRead > 0)
61 | {
62 | var receiveData = state.Buffer.Take(bytesRead).ToArray();
63 | var dataList = PacketUtils.SplitBytes(receiveData, PacketUtils.ClientFindFileInfoTag());
64 | if (dataList != null && dataList.Any())
65 | {
66 | var request = PacketUtils.GetData(PacketUtils.ClientFindFileInfoTag(), dataList.FirstOrDefault());
67 | string str = System.Text.Encoding.UTF8.GetString(request);
68 | var infos = str.Split('_');
69 | var productName = infos[0];
70 | var revitVersion = infos[1];
71 | var currentVersion = infos[2];
72 |
73 | var updatefile = ServerFileUtils.GetLatestFilePath(productName, revitVersion, currentVersion);
74 | if (string.IsNullOrEmpty(updatefile) || !File.Exists(updatefile)) return;
75 | _serverPath = updatefile;
76 | FoundUpdateFileResponse(handler);
77 | }
78 | }
79 | }
80 |
81 |
82 | private static void FoundUpdateFileResponse(Socket handler)
83 | {
84 | byte[] foundUpdateFileData = PacketUtils.PacketData(PacketUtils.ServerFoundFileInfoTag(),null);
85 | ComObject state = new ComObject { WorkSocket = handler };
86 | handler.BeginSend(foundUpdateFileData, 0, foundUpdateFileData.Length, 0, HasFoundUpdateFileCallback, state);
87 | }
88 |
89 |
90 | private static void HasFoundUpdateFileCallback(IAsyncResult ar)
91 | {
92 | ComObject state = (ComObject)ar.AsyncState;
93 | Socket handler = state.WorkSocket;
94 | handler.EndSend(ar);
95 | handler.BeginReceive(state.Buffer, 0, ComObject.BufferSize, 0, ReadFilePositionRequestCallback, state);
96 | }
97 |
98 |
99 | private static void ReadFilePositionRequestCallback(IAsyncResult ar)
100 | {
101 | ComObject state = (ComObject)ar.AsyncState;
102 | Socket handler = state.WorkSocket;
103 | int bytesRead = handler.EndReceive(ar);
104 | if (bytesRead > 0)
105 | {
106 | var receiveData = state.Buffer.Take(bytesRead).ToArray();
107 | var dataList = PacketUtils.SplitBytes(receiveData, PacketUtils.ClientRequestFileTag());
108 | if (dataList != null)
109 | {
110 | foreach (var request in dataList)
111 | {
112 | if (PacketUtils.IsPacketComplete(request))
113 | {
114 | int startPosition = PacketUtils.GetRequestFileStartPosition(request);
115 | SendFileResponse(handler, startPosition);
116 | }
117 | }
118 | }
119 | }
120 | }
121 |
122 | private static void SendFileResponse(Socket handler, int startPosition)
123 | {
124 | var packetSize = PacketUtils.GetPacketSize(_serverPath, _downloadChannelsCount);
125 | if (packetSize != 0)
126 | {
127 | byte[] filedata = FileUtils.GetFile(_serverPath, startPosition, packetSize);
128 | byte[] packetNumber = BitConverter.GetBytes(startPosition/packetSize);
129 | if (filedata != null)
130 | {
131 | byte[] segmentedFileResponseData = PacketUtils.PacketData(PacketUtils.ServerResponseFileTag(), filedata, packetNumber);
132 | ComObject state = new ComObject {WorkSocket = handler};
133 | handler.BeginSend(segmentedFileResponseData, 0, segmentedFileResponseData.Length, 0, SendFileResponseCallback, state);
134 | }
135 | }
136 | else
137 | {
138 | handler.Shutdown(SocketShutdown.Both);
139 | handler.Close();
140 | }
141 | }
142 |
143 |
144 | private static void SendFileResponseCallback(IAsyncResult ar)
145 | {
146 | try
147 | {
148 | ComObject state = (ComObject)ar.AsyncState;
149 | Socket handler = state.WorkSocket;
150 | handler.EndSend(ar);
151 | handler.Shutdown(SocketShutdown.Both);
152 | handler.Close();
153 | }
154 | catch (Exception e)
155 | {
156 |
157 | }
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/SocketService.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace UpdaterService
2 | {
3 | partial class SocketService
4 | {
5 | ///
6 | /// 必需的设计器变量。
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// 清理所有正在使用的资源。
12 | ///
13 | /// 如果应释放托管资源,为 true;否则为 false。
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region 组件设计器生成的代码
24 |
25 | ///
26 | /// 设计器支持所需的方法 - 不要修改
27 | /// 使用代码编辑器修改此方法的内容。
28 | ///
29 | private void InitializeComponent()
30 | {
31 | components = new System.ComponentModel.Container();
32 | this.ServiceName = "Service1";
33 | }
34 |
35 | #endregion
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/SocketService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.ServiceProcess;
4 | using System.Threading;
5 |
6 | namespace UpdaterService
7 | {
8 | public partial class SocketService : ServiceBase
9 | {
10 | Thread threadforwork = null;
11 |
12 | public SocketService()
13 | {
14 | InitializeComponent();
15 | }
16 |
17 | protected override void OnStart(string[] args)
18 | {
19 | if (threadforwork == null)
20 | {
21 | threadforwork = new Thread(p =>
22 | {
23 | try
24 | {
25 | ServerSocket.StartServer(8885, 100);
26 | }
27 | catch (Exception ex)
28 | {
29 | var path = $"{AppDomain.CurrentDomain.BaseDirectory}\\ServiceStartLog.txt";
30 | File.AppendAllText(path, ex.Message);
31 | }
32 | });
33 | threadforwork.IsBackground = true;
34 | threadforwork.Start();
35 | }
36 | }
37 |
38 | protected override void OnStop()
39 | {
40 | if (threadforwork?.ThreadState == ThreadState.Running)
41 | {
42 | threadforwork.Abort();
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/Uninstall.bat:
--------------------------------------------------------------------------------
1 | net stop SocketService
2 | %SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u UpdaterService.exe
3 | pause
4 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterService/UpdaterService.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {DFD1D238-8962-45C2-B637-5DCD469730F0}
8 | WinExe
9 | Properties
10 | UpdaterService
11 | UpdaterService
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Component
51 |
52 |
53 | ProjectInstaller.cs
54 |
55 |
56 |
57 | Component
58 |
59 |
60 | SocketService.cs
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Always
69 |
70 |
71 | Always
72 |
73 |
74 | Always
75 |
76 |
77 |
78 |
79 | {0f89cc70-3aca-4664-873b-b8a9f4d7cee5}
80 | UpdaterShare
81 |
82 |
83 |
84 |
85 | ProjectInstaller.cs
86 |
87 |
88 |
89 |
90 |
97 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/GlobalSetting/DownloadSetting.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace UpdaterShare.GlobalSetting
3 | {
4 | public static class DownloadSetting
5 | {
6 | public static int DownloadChannelsCount = 5;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Model/ClientBasicInfo.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace UpdaterShare.Model
3 | {
4 | public class ClientBasicInfo
5 | {
6 | public string ProductName { get; set; }
7 | public string RevitVersion { get; set; }
8 | public string CurrentProductVersion { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Model/ClientLinkInfo.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace UpdaterShare.Model
3 | {
4 | public class ClientLinkInfo
5 | {
6 | public string IpString { get; set; }
7 | public int Port { get; set; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Model/ComObject.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Sockets;
2 |
3 | namespace UpdaterShare.Model
4 | {
5 | public class ComObject
6 | {
7 | public Socket WorkSocket = null;
8 | // Why the BufferSize is Set 1024*80
9 | // https://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write
10 | public const int BufferSize = 1024 * 80;
11 | public byte[] Buffer = new byte[BufferSize];
12 | public int PacketNumber;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Model/DownloadFileInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace UpdaterShare.Model
4 | {
5 | [Serializable]
6 | public class DownloadFileInfo
7 | {
8 | public string LatestProductVersion { get; set; }
9 | public string DownloadFileMd5 { get; set; }
10 | public long DownloadFileTotalSize { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Model/PacketDef.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace UpdaterShare.Model
3 | {
4 | public static class PacketDef
5 | {
6 | #region 数据包标识字节定义
7 | ///
8 | /// Packet Start Tag
9 | ///
10 | public static readonly byte[] Packet_Start = { 0xAA, 0x55 };
11 | ///
12 | /// Packet Version Tag
13 | ///
14 | public static readonly byte[] Packet_Version = { 0x01 };
15 | ///
16 | /// Client Request File Packet Tag
17 | ///
18 | public static readonly byte[] Packet_Client_RequestFile = { 0x01 };
19 | ///
20 | /// Server Response File Packet Tag
21 | ///
22 | public static readonly byte[] Packet_Server_ResponseFile = { 0x02 };
23 | ///
24 | /// Client Send Basic Info Tag
25 | ///
26 | public static readonly byte[] Packet_Client_FindUpdateFile = {0x03};
27 | ///
28 | /// Server Receivce Basic Into Tag
29 | ///
30 | public static readonly byte[] Packet_Server_FoundUpdateFile = {0x04};
31 | ///
32 | /// Client Send HeartBeat Tag
33 | ///
34 | public static readonly byte[] Packet_Client_RequestHeartBeat = { 0x05 };
35 | ///
36 | /// Server Response HeartBeat Tag
37 | ///
38 | public static readonly byte[] Packet_Server_ResponseHeartBeat = { 0x06 };
39 | #endregion
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("UpdaterShare")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("China")]
12 | [assembly: AssemblyProduct("UpdaterShare")]
13 | [assembly: AssemblyCopyright("Copyright © China 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | //将 ComVisible 设置为 false 将使此程序集中的类型
18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("0f89cc70-3aca-4664-873b-b8a9f4d7cee5")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/UpdaterShare.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {0F89CC70-3ACA-4664-873B-B8A9F4D7CEE5}
8 | Library
9 | Properties
10 | UpdaterShare
11 | UpdaterShare
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 | ..\..\..\ThirdParty\Log4Net\log4net.dll
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
71 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Utility/Crc16Utils.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 |
3 | namespace UpdaterShare.Utility
4 | {
5 | public static class Crc16Utils
6 | {
7 | ///
8 | /// Get Crc16 value From byte[]
9 | ///
10 | /// import data
11 | ///
12 | public static ushort GetCrc16Code(byte[] data)
13 | {
14 | ushort crc = 0;
15 | foreach (var bt in data)
16 | {
17 | crc ^= (ushort)(bt << 8);
18 | for (int j = 0; j < 8; j++)
19 | {
20 | if ((crc & 0x8000) != 0)
21 | crc = (ushort)((crc << 1) ^ 0x1021);
22 | else
23 | crc <<= 1;
24 | }
25 | }
26 | return crc;
27 | }
28 |
29 |
30 | ///
31 | /// Ckeck CrcCode of packet byte[]
32 | ///
33 | ///
34 | ///
35 | public static bool CheckCrcCode(byte[] importData)
36 | {
37 | byte[] receivedata = importData;
38 | byte[] packetInfoWithoutCrc = receivedata.Take(receivedata.Length - PacketUtils.Packet_Crc16Code_Length).ToArray();
39 | byte[] localCalcCrc = PacketUtils.GetPacketCrc(packetInfoWithoutCrc);
40 | byte[] serverCrc = receivedata.Skip(receivedata.Length - PacketUtils.Packet_Crc16Code_Length).ToArray();
41 | var compareCrc = PacketUtils.BytesCompare(localCalcCrc, serverCrc);
42 | if (compareCrc == 0)
43 | {
44 | return true;
45 | }
46 | return false;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Utility/FileUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace UpdaterShare.Utility
5 | {
6 | public static class FileUtils
7 | {
8 | ///
9 | /// Combine Temp Files
10 | ///
11 | ///
12 | /// temp files Directory
13 | ///
14 | public static void CombineTempFiles(string localSavePath, string tempFilesDirectory)
15 | {
16 | if (!string.IsNullOrEmpty(localSavePath) && !string.IsNullOrEmpty(tempFilesDirectory))
17 | {
18 | try
19 | {
20 | var tempFilesDir = new DirectoryInfo(tempFilesDirectory);
21 | using (FileStream writestream = new FileStream(localSavePath, FileMode.Create, FileAccess.Write,FileShare.Write))
22 | {
23 | foreach (FileInfo tempfile in tempFilesDir.GetFiles())
24 | {
25 | using (FileStream readTempStream = new FileStream(tempfile.FullName, FileMode.Open,FileAccess.Read, FileShare.ReadWrite))
26 | {
27 | long onefileLength = tempfile.Length;
28 | byte[] buffer = new byte[Convert.ToInt32(onefileLength)];
29 | readTempStream.Read(buffer, 0, Convert.ToInt32(onefileLength));
30 | writestream.Write(buffer, 0, Convert.ToInt32(onefileLength));
31 | }
32 | }
33 | writestream.Flush();
34 | writestream.Close();
35 | writestream.Dispose();
36 | }
37 | }
38 | catch(Exception ex)
39 | {
40 | Console.WriteLine(ex.Message);
41 | }
42 | }
43 | }
44 |
45 |
46 | ///
47 | /// Get File by Start Index and Length
48 | ///
49 | ///
50 | ///
51 | ///
52 | ///
53 | public static byte[] GetFile(string serverFilePath, int start, int length)
54 | {
55 | if (!string.IsNullOrEmpty(serverFilePath) && length != 0)
56 | {
57 | try
58 | {
59 | using (FileStream serverStream = new FileStream(serverFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 1024 * 80, true))
60 | {
61 | byte[] buffer = new byte[length];
62 | serverStream.Position = start;
63 | serverStream.Read(buffer, 0, length);
64 | return buffer;
65 | }
66 | }
67 | catch
68 | {
69 | return null;
70 | }
71 | }
72 | return null;
73 | }
74 |
75 |
76 | ///
77 | /// Generate Temp File
78 | ///
79 | ///
80 | ///
81 | public static void GenerateTempFile(string tempFilePath, byte[] importBytes)
82 | {
83 | if (!string.IsNullOrEmpty(tempFilePath))
84 | {
85 | try
86 | {
87 | using (FileStream tempstream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.Write))
88 | {
89 | tempstream.Write(importBytes, 0, importBytes.Length);
90 | tempstream.Flush();
91 | tempstream.Close();
92 | tempstream.Dispose();
93 | }
94 | }
95 | catch (Exception ex)
96 | {
97 | Console.WriteLine(ex.Message);
98 | }
99 | }
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Utility/LogUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using log4net;
4 | using log4net.Appender;
5 | using log4net.Layout;
6 | using log4net.Repository.Hierarchy;
7 |
8 | namespace UpdaterShare.Utility
9 | {
10 | public static class LogUtils
11 | {
12 | //logFileName = $"{productName}{productVersion}-{revitVersion}";
13 | public static void Init(string productName, string logFileName, string logFolderPath)
14 | {
15 | if (string.IsNullOrEmpty(logFileName))
16 | {
17 | logFileName = productName;
18 | }
19 |
20 | // Begin Config
21 | string finalLogFolderPath = null;
22 | if (ValidOrCreateLogFolderPath(logFolderPath))
23 | {
24 | finalLogFolderPath = logFolderPath;
25 | }
26 | else
27 | {
28 | string userLocalPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
29 | string defaultLogFolderPath = Path.Combine(userLocalPath, $"{productName}\\Logs\\");
30 | if (ValidOrCreateLogFolderPath(defaultLogFolderPath))
31 | {
32 | finalLogFolderPath = defaultLogFolderPath;
33 | }
34 | }
35 |
36 | // Creat Pattern layout for outputed string in log file
37 | PatternLayout patternLayout = new PatternLayout { ConversionPattern = "%d [%t] %-5p %m%n" };
38 | patternLayout.ActivateOptions();
39 |
40 | // Create rolling file appender
41 | RollingFileAppender roller = new RollingFileAppender { AppendToFile = false };
42 | string nowDateString = DateTime.Now.ToString("yyyy-MM-dd");
43 | string finalLogFileName = $@"{logFileName}-{nowDateString}.log";
44 | if (finalLogFolderPath != null) roller.File = Path.Combine(finalLogFolderPath, finalLogFileName);
45 | roller.Layout = patternLayout;
46 | roller.RollingStyle = RollingFileAppender.RollingMode.Once;
47 | roller.MaxSizeRollBackups = 1000;
48 | roller.StaticLogFileName = true;
49 | roller.ActivateOptions();
50 |
51 | #if DEBUG
52 | ConsoleAppender consoleAppender = new ConsoleAppender {Layout = new SimpleLayout()};
53 | consoleAppender.ActivateOptions();
54 | #endif
55 |
56 | // Get Hierarchy
57 | Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
58 | Logger logger = hierarchy.GetLogger(logFileName) as Logger;
59 |
60 | hierarchy.Configured = true;
61 | logger.Additivity = false;
62 | logger.Level = log4net.Core.Level.All;
63 |
64 | // Must clear previous appenders, otherwise may output previous log folder !!!
65 | logger.RemoveAllAppenders();
66 | logger.AddAppender(roller);
67 | }
68 |
69 | private static bool ValidOrCreateLogFolderPath(string logFolderPath)
70 | {
71 | try
72 | {
73 | if (!string.IsNullOrEmpty(logFolderPath))
74 | {
75 | if (!Directory.Exists(logFolderPath))
76 | {
77 | Directory.CreateDirectory(logFolderPath);
78 | }
79 | return true;
80 | }
81 | return false;
82 | }
83 | catch (Exception)
84 | {
85 | return false;
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Utility/Md5Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 |
6 | namespace UpdaterShare.Utility
7 | {
8 | public static class Md5Utils
9 | {
10 | ///
11 | /// Get Md5 value of certain flie
12 | ///
13 | /// file path
14 | ///
15 | public static string GetFileMd5(string filePath)
16 | {
17 | if (string.IsNullOrEmpty(filePath)) return null;
18 | try
19 | {
20 | using (FileStream filestream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
21 | {
22 | MD5 md5 = new MD5CryptoServiceProvider();
23 | byte[] file = md5.ComputeHash(filestream);
24 | filestream.Close();
25 | StringBuilder fileMd5 = new StringBuilder();
26 | for (int i = 0; i < file.Length; i++)
27 | {
28 | fileMd5.Append(i.ToString("x2"));
29 | }
30 | return fileMd5.ToString();
31 | }
32 | }
33 | catch
34 | {
35 | return null;
36 | }
37 | }
38 |
39 |
40 | ///
41 | /// Whether two md5 values are the same value
42 | ///
43 | /// first Md5 value
44 | /// second Md5 value
45 | ///
46 | public static bool IsMd5Equal(string md5One, string md5Two)
47 | {
48 | return string.Compare(md5One, md5Two, StringComparison.OrdinalIgnoreCase) == 0;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Utility/PacketUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices;
6 | using UpdaterShare.Model;
7 |
8 | namespace UpdaterShare.Utility
9 | {
10 | public static class PacketUtils
11 | {
12 | #region Tag Length
13 | ///
14 | /// Packet Start_Tag Length
15 | ///
16 | public static readonly int Packet_Start_Length = PacketDef.Packet_Start.Length;
17 | ///
18 | /// Packet Version_Tag Length
19 | ///
20 | public static readonly int Packet_Version_Length = PacketDef.Packet_Version.Length;
21 | ///
22 | /// Packet Length_Tag Length
23 | ///
24 | public static readonly int Packet_LengthTag_Length = 4;
25 | ///
26 | /// Packet Number_Tag Length
27 | ///
28 | public static readonly int Packet_PacketNumber_Length = 4;
29 | ///
30 | /// Packet Crc16_Tag Length
31 | ///
32 | public static readonly int Packet_Crc16Code_Length = 2;
33 | #endregion
34 |
35 | #region Tag Convert To Byte[]
36 | ///
37 | /// Client Requst File Tag
38 | ///
39 | ///
40 | public static byte[] ClientRequestFileTag()
41 | {
42 | return PacketDef.Packet_Start.Concat(PacketDef.Packet_Version).Concat(PacketDef.Packet_Client_RequestFile).ToArray();
43 | }
44 |
45 |
46 | ///
47 | /// Server Response File Tag
48 | ///
49 | ///
50 | public static byte[] ServerResponseFileTag()
51 | {
52 | return PacketDef.Packet_Start.Concat(PacketDef.Packet_Version).Concat(PacketDef.Packet_Server_ResponseFile).ToArray();
53 | }
54 |
55 |
56 | ///
57 | /// Client Send Find Udpate File Tag
58 | ///
59 | ///
60 | public static byte[] ClientFindFileInfoTag()
61 | {
62 | return PacketDef.Packet_Start.Concat(PacketDef.Packet_Version).Concat(PacketDef.Packet_Client_FindUpdateFile).ToArray();
63 | }
64 |
65 |
66 | ///
67 | /// Server Response Has Found Update File Tag
68 | ///
69 | ///
70 | public static byte[] ServerFoundFileInfoTag()
71 | {
72 | return PacketDef.Packet_Start.Concat(PacketDef.Packet_Version).Concat(PacketDef.Packet_Server_FoundUpdateFile).ToArray();
73 | }
74 |
75 |
76 | ///
77 | /// Client Send HeartBeat Tag
78 | ///
79 | ///
80 | public static byte[] ClientRequestHeartBeatTag()
81 | {
82 | return PacketDef.Packet_Start.Concat(PacketDef.Packet_Version).Concat(PacketDef.Packet_Client_RequestHeartBeat).ToArray();
83 | }
84 |
85 |
86 | ///
87 | /// Server Response HeartBeat Tag
88 | ///
89 | ///
90 | public static byte[] ServerResponseHeartBeatTag()
91 | {
92 | return PacketDef.Packet_Start.Concat(PacketDef.Packet_Version).Concat(PacketDef.Packet_Server_ResponseHeartBeat).ToArray();
93 | }
94 | #endregion
95 |
96 |
97 |
98 | ///
99 | /// Packet Data
100 | ///
101 | ///
102 | ///
103 | ///
104 | ///
105 | public static byte[] PacketData(byte[] tag, byte[] data, byte[] packetNumber = null)
106 | {
107 | // A Packet = tag(start_tag + version_tag + request/response_tag) + length_tag + data + crc16_tag
108 |
109 | int startTagLength = tag.Length;
110 | int dataLenght = 0;
111 | if (data != null)
112 | {
113 | if (packetNumber == null)
114 | {
115 | dataLenght = data.Length;
116 | }
117 | else
118 | {
119 | dataLenght = packetNumber.Length + data.Length;
120 | data = packetNumber.Concat(data).ToArray();
121 | }
122 | }
123 |
124 | int crcLength = Packet_Crc16Code_Length;
125 | byte[] packetLengthWithoutself = BitConverter.GetBytes(startTagLength + dataLenght + crcLength);
126 | byte[] packetLength = BitConverter.GetBytes(startTagLength + packetLengthWithoutself.Length + dataLenght + crcLength);
127 | byte[] packetWithoutcrc = data == null
128 | ? tag.Concat(packetLength).ToArray()
129 | : tag.Concat(packetLength).Concat(data).ToArray();
130 | byte[] crcCode = GetPacketCrc(packetWithoutcrc);
131 | byte[] packetInfo = packetWithoutcrc.Concat(crcCode).ToArray();
132 | return packetInfo;
133 | }
134 |
135 |
136 |
137 | ///
138 | /// Get Crc16 Code From Packet
139 | ///
140 | ///
141 | ///
142 | public static byte[] GetPacketCrc(byte[] packet)
143 | {
144 | return BitConverter.GetBytes(Crc16Utils.GetCrc16Code(packet));
145 | }
146 |
147 |
148 |
149 | ///
150 | /// Byte[] Compare
151 | ///
152 | /// first byte[]
153 | /// second byte[]
154 | /// same return 0; first>second return negative; first > second return positive;
155 | ///
156 | [DllImport("msvcrt.dll", EntryPoint = "memcmp", CallingConvention = CallingConvention.Cdecl)]
157 | private static extern IntPtr memcmp(byte[] b1, byte[] b2, IntPtr result);
158 | public static int BytesCompare(byte[] b1, byte[] b2)
159 | {
160 | IntPtr retval = memcmp(b1, b2, new IntPtr(b1.Length));
161 | return retval.ToInt32();
162 | }
163 |
164 |
165 |
166 | ///
167 | /// Check Packet Receive Competely
168 | ///
169 | ///
170 | ///
171 | public static bool IsPacketComplete(byte[] packet)
172 | {
173 | var receiveLength = packet.Length;
174 | var theoryLength = GetPacketLength(packet);
175 | if (receiveLength == theoryLength)
176 | {
177 | return true;
178 | }
179 | return false;
180 | }
181 |
182 |
183 |
184 | ///
185 | /// Get Packet Length
186 | ///
187 | ///
188 | ///
189 | public static int GetPacketLength(byte[] packet)
190 | {
191 | return BitConverter.ToInt32(packet
192 | .Take(ClientRequestFileTag().Length + Packet_LengthTag_Length)
193 | .Skip(ClientRequestFileTag().Length).ToArray(), 0);
194 | }
195 |
196 |
197 |
198 |
199 |
200 | ///
201 | /// Client Get Packet Number From Response
202 | ///
203 | ///
204 | ///
205 | public static int GetResponsePacketNumber(byte[] packet)
206 | {
207 | var tempData = packet.Skip(ClientRequestFileTag().Length + Packet_LengthTag_Length).ToArray();
208 | var resultData = tempData.Take(Packet_PacketNumber_Length).ToArray();
209 | var packetNumber = BitConverter.ToInt32(resultData, 0);
210 | return packetNumber;
211 | }
212 |
213 |
214 | ///
215 | /// Get Data Part in Packet
216 | ///
217 | ///
218 | ///
219 | public static byte[] GetData(byte[] tag, byte[] packet)
220 | {
221 | if (BytesCompare(tag, ServerResponseFileTag()) == 0)
222 | {
223 | var tempData = packet.Skip(tag.Length + Packet_LengthTag_Length + Packet_PacketNumber_Length).ToArray();
224 | return tempData.Take(tempData.Length - Packet_Crc16Code_Length).ToArray();
225 | }
226 | else
227 | {
228 | var tempData = packet.Skip(tag.Length + Packet_LengthTag_Length).ToArray();
229 | return tempData.Take(tempData.Length - Packet_Crc16Code_Length).ToArray();
230 | }
231 | }
232 |
233 |
234 | ///
235 | /// Get Download Packet Size according to server file and channels count
236 | ///
237 | ///
238 | ///
239 | ///
240 | public static int GetPacketSize(string filePath, int downloadChannelsCount)
241 | {
242 | if (!string.IsNullOrEmpty(filePath))
243 | {
244 | FileInfo severFileInfo = new FileInfo(filePath);
245 | return (int)(severFileInfo.Length / downloadChannelsCount);
246 | }
247 | return 0;
248 | }
249 |
250 |
251 | ///
252 | /// Server Get Request File Start Position
253 | ///
254 | ///
255 | ///
256 | public static int GetRequestFileStartPosition(byte[] packet)
257 | {
258 | var tempData = packet.Skip(ClientRequestFileTag().Length + Packet_LengthTag_Length).ToArray();
259 | var resultData = tempData.Take(tempData.Length - Packet_Crc16Code_Length).ToArray();
260 | var start = BitConverter.ToInt32(resultData, 0);
261 | return start;
262 | }
263 |
264 |
265 |
266 | ///
267 | /// Split Packets According to Tag
268 | ///
269 | ///
270 | ///
271 | ///
272 | public static List SplitBytes(byte[] receivedata, byte[] tag)
273 | {
274 | //match tag
275 | var packetStartIndexList = new List();
276 | for (var i = 0; i < receivedata.Length; i++)
277 | {
278 | if (i == receivedata.Length - 3) break;
279 | packetStartIndexList.AddRange(tag.TakeWhile((t, j) => j != tag.Length - 3)
280 | .Where((t, j) => receivedata[i] == t &&
281 | receivedata[i + 1] == tag[j + 1] &&
282 | receivedata[i + 2] == tag[j + 2] &&
283 | receivedata[i + 3] == tag[j + 3])
284 | .Select(t => i));
285 | }
286 |
287 |
288 | switch (packetStartIndexList.Count)
289 | {
290 | //0 match
291 | case 0:
292 | return null;
293 |
294 | //1 match
295 | case 1:
296 | try
297 | {
298 | var index = packetStartIndexList.FirstOrDefault();
299 | var packetLength = GetPacketLength(receivedata.Skip(index).ToArray());
300 | return new List { receivedata.Skip(index).Take(packetLength).ToArray() };
301 | }
302 | catch
303 | {
304 | return null;
305 | }
306 |
307 | //>1 matches
308 | default:
309 | var result = new List();
310 | var packLength = packetStartIndexList[1] - packetStartIndexList[0];
311 | for (var index = 0; index < packetStartIndexList.Count; index++)
312 | {
313 | var packetIndex = packetStartIndexList[index];
314 | var destbyte = new byte[packLength];
315 |
316 | if (index == packetStartIndexList.LastOrDefault())
317 | {
318 | try
319 | {
320 | Array.Copy(receivedata, packetIndex, destbyte, 0, packLength);
321 | result.Add(destbyte);
322 | }
323 | catch
324 | {
325 | break;
326 | }
327 | }
328 | else
329 | {
330 |
331 | Array.Copy(receivedata, packetIndex, destbyte, 0, packLength);
332 | result.Add(destbyte);
333 | }
334 | }
335 | return result;
336 | }
337 | }
338 | }
339 | }
340 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Utility/ServerFileUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.ServiceProcess;
5 | using Microsoft.Win32;
6 |
7 | namespace UpdaterShare.Utility
8 | {
9 | public static class ServerFileUtils
10 | {
11 | ///
12 | /// Get Latest File Path
13 | ///
14 | ///
15 | ///
16 | ///
17 | ///
18 | public static string GetLatestFilePath(string productName, string revitVersion, string currentProductVersion)
19 | {
20 | try
21 | {
22 | var mainFolderPath = Path.Combine(GetFilePathFromService("SocketService"),"ExampleFile");
23 | var updateFilesList = Directory.GetFiles(mainFolderPath);
24 | if (updateFilesList.Any())
25 | {
26 | foreach (var file in updateFilesList)
27 | {
28 | var fileName = Path.GetFileNameWithoutExtension(file);
29 | var paras = fileName.Split('_');
30 | if (paras[0] == productName && paras[1] == revitVersion && paras[2] == currentProductVersion)
31 | {
32 | return Path.GetFullPath(file);
33 | }
34 | }
35 | }
36 | }
37 | catch
38 | {
39 | return null;
40 | }
41 | return null;
42 | }
43 |
44 | //ProductName_RevitVersion_OldProductVersion_NewProductVersion
45 | public static string GetLatestVersion(string fileName)
46 | {
47 | return fileName.Split('_').LastOrDefault();
48 | }
49 |
50 |
51 | ///
52 | /// Get Latest File From Windows Service by Registry
53 | ///
54 | ///
55 | ///
56 | public static string GetFilePathFromService(string serviceName)
57 | {
58 | try
59 | {
60 | ServiceController[] services = ServiceController.GetServices();
61 | var socketService = services.FirstOrDefault(x => String.Equals(x.ServiceName, "SocketService"));
62 | if (socketService != null)
63 | {
64 | var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ?
65 | RegistryView.Registry64 : RegistryView.Registry32);
66 | var key = localMachineRegistry.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\" + serviceName);
67 | if (key != null)
68 | {
69 | var serviceExePath = GetString(key.GetValue("ImagePath").ToString());
70 | var folderPath = Path.GetDirectoryName(serviceExePath);
71 | if (!String.IsNullOrEmpty(folderPath) && Directory.Exists(folderPath))
72 | {
73 | return folderPath;
74 | }
75 | }
76 | }
77 | }
78 | catch(Exception ex)
79 | {
80 | return null;
81 | }
82 | return null;
83 | }
84 |
85 | ///
86 | /// Remove "\"
87 | ///
88 | ///
89 | ///
90 | private static string GetString(string str)
91 | {
92 | if (str.Contains("\""))
93 | {
94 | str = str.Substring(1, str.Length - 2);
95 | }
96 | return str;
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterShare/Utility/XmlUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 |
3 | namespace UpdaterShare.Utility
4 | {
5 | public static class XmlUtils
6 | {
7 | ///
8 | /// Get Value By Key
9 | ///
10 | ///
11 | ///
12 | ///
13 | ///
14 | public static string GetValueByKey(string xmlFilePath, string rootNodeName, string keyName)
15 | {
16 | XmlDocument xmlDoc = new XmlDocument();
17 | xmlDoc.Load(xmlFilePath);
18 | XmlNode xmlRootNode = xmlDoc.SelectSingleNode(rootNodeName);
19 | XmlNodeList xnl = xmlRootNode?.ChildNodes;
20 | if (xnl?.Count > 0)
21 | {
22 | foreach (XmlElement xe in xnl)
23 | {
24 | foreach (XmlAttribute attr in xe.Attributes)
25 | {
26 | if (attr.Name.Equals(keyName))
27 | {
28 | return attr.InnerXml;
29 | }
30 | }
31 | }
32 | }
33 | return null;
34 | }
35 |
36 |
37 | ///
38 | /// Insert Node
39 | ///
40 | ///
41 | ///
42 | ///
43 | ///
44 | ///
45 | public static XmlElement InsertNode(XmlDocument xmlDoc, string nodeName, string keyName, string value)
46 | {
47 | XmlElement xn = xmlDoc.CreateElement(nodeName);
48 | xn.SetAttribute(keyName, value);
49 | return xn;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/ApiController/ConnectionController.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Http;
2 |
3 | namespace UpdaterWebServer.ApiController
4 | {
5 | public class ConnectionController : System.Web.Http.ApiController
6 | {
7 | [HttpGet]
8 | [ActionName("ConnectionTest")]
9 | public string ConnectionTest()
10 | {
11 | return "connected_success";
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/ApiController/GetFileInfoController.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Net;
3 | using System.Net.Http;
4 | using System.Text;
5 | using System.Web.Http;
6 | using Newtonsoft.Json;
7 | using UpdaterShare.Model;
8 | using UpdaterShare.Utility;
9 |
10 | namespace UpdaterWebServer.ApiController
11 | {
12 |
13 | public class GetFileInfoController : System.Web.Http.ApiController
14 | {
15 | [HttpPost]
16 | public HttpResponseMessage GetInfo(ClientBasicInfo clientBasicInfo)
17 | {
18 | var productName = clientBasicInfo.ProductName;
19 | var revitVersion = clientBasicInfo.RevitVersion;
20 | var currentProductVersion = clientBasicInfo.CurrentProductVersion;
21 |
22 | //ProductName_RevitVersion_OldProductVersion_NewProductVersion
23 | var latestFilePath = ServerFileUtils.GetLatestFilePath(productName, revitVersion, currentProductVersion);
24 | if (string.IsNullOrEmpty(latestFilePath) || !File.Exists(latestFilePath)) return null;
25 |
26 | var latestFile = new FileInfo(latestFilePath);
27 | var downloadInfo = new DownloadFileInfo()
28 | {
29 | LatestProductVersion = ServerFileUtils.GetLatestVersion(Path.GetFileNameWithoutExtension(latestFilePath)),
30 | DownloadFileMd5 = Md5Utils.GetFileMd5(latestFilePath),
31 | DownloadFileTotalSize = latestFile.Length
32 | };
33 | HttpResponseMessage response = new HttpResponseMessage
34 | {
35 | StatusCode = HttpStatusCode.OK,
36 | Content = new StringContent(JsonConvert.SerializeObject(downloadInfo), Encoding.GetEncoding("UTF-8"),"application/json")
37 | };
38 | return response;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/App_Start/WebApiConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Http;
2 |
3 | namespace UpdaterWebServer
4 | {
5 | public static class WebApiConfig
6 | {
7 | public static void Register(HttpConfiguration config)
8 | {
9 |
10 | // Web API 路由
11 | config.MapHttpAttributeRoutes();
12 |
13 | config.Routes.MapHttpRoute(
14 | name: "DefaultApi",
15 | routeTemplate: "api/{controller}/{action}/{id}",
16 | defaults: new { id = RouteParameter.Optional }
17 | );
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="UpdaterWebServer.WebApiApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/Global.asax.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Http;
2 |
3 | namespace UpdaterWebServer
4 | {
5 | public class WebApiApplication : System.Web.HttpApplication
6 | {
7 | protected void Application_Start()
8 | {
9 | GlobalConfiguration.Configure(WebApiConfig.Register);
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的常规信息是通过以下项进行控制的
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("UpdaterWebServer")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("China")]
12 | [assembly: AssemblyProduct("UpdaterWebServer")]
13 | [assembly: AssemblyCopyright("版权所有(C) China 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 将使此程序集中的类型
18 | // 对 COM 组件不可见。如果需要
19 | // 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
23 | [assembly: Guid("7be75d61-c874-4170-9a54-29d38b262666")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 内部版本号
30 | // 修订版本
31 | //
32 | // 你可以指定所有值,也可以让修订版本和内部版本号采用默认值,
33 | // 方法是按如下所示使用 "*":
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Owin;
2 | using Owin;
3 |
4 | [assembly: OwinStartup(typeof(UpdaterWebServer.Startup))]
5 |
6 | namespace UpdaterWebServer
7 | {
8 | public partial class Startup
9 | {
10 | public void Configuration(IAppBuilder app)
11 | {
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/Source/SocketUpdater/UpdaterWebServer/favicon.ico
--------------------------------------------------------------------------------
/Source/SocketUpdater/UpdaterWebServer/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/ThirdParty/DevExpress/DevExpress.Data.v15.2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/ThirdParty/DevExpress/DevExpress.Data.v15.2.dll
--------------------------------------------------------------------------------
/ThirdParty/DevExpress/DevExpress.Mvvm.v15.2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/ThirdParty/DevExpress/DevExpress.Mvvm.v15.2.dll
--------------------------------------------------------------------------------
/ThirdParty/DevExpress/DevExpress.Xpf.Controls.v15.2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/ThirdParty/DevExpress/DevExpress.Xpf.Controls.v15.2.dll
--------------------------------------------------------------------------------
/ThirdParty/DevExpress/DevExpress.Xpf.Core.v15.2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/ThirdParty/DevExpress/DevExpress.Xpf.Core.v15.2.dll
--------------------------------------------------------------------------------
/ThirdParty/ICSharpCode/ICSharpCode.SharpZipLib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/ThirdParty/ICSharpCode/ICSharpCode.SharpZipLib.dll
--------------------------------------------------------------------------------
/ThirdParty/Log4Net/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/ThirdParty/Log4Net/log4net.dll
--------------------------------------------------------------------------------
/ThirdParty/Newtonsoft.Json/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BIMCoderLiang/SocketUpdater/d91998c74b1f525495768ee98fb0a914c3c234cf/ThirdParty/Newtonsoft.Json/Newtonsoft.Json.dll
--------------------------------------------------------------------------------