├── .gitattributes
├── .gitignore
├── AddDeviceWindow.xaml
├── AddDeviceWindow.xaml.cs
├── AddWindow.xaml
├── AddWindow.xaml.cs
├── Allocation.xaml
├── Allocation.xaml.cs
├── App.config
├── App.xaml
├── App.xaml.cs
├── DataBrige.cs
├── DatabaseOperation
└── DbClass.cs
├── DevicePage
├── GeneralNetworkDevice.xaml
└── GeneralNetworkDevice.xaml.cs
├── GitHubVersionChecker.cs
├── IPAM-NOTE.csproj
├── IPAM-NOTE.sln
├── IPAddressCalculations.cs
├── ImportWindow.xaml
├── ImportWindow.xaml.cs
├── LICENSE.txt
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── PortAllocation.xaml
├── PortAllocation.xaml.cs
├── PresetWindow
├── AddPreset.xaml
└── AddPreset.xaml.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── README.md
├── Resources
├── ADD.png
├── ALLOCATION.png
├── DATAHELP.png
├── DONATION.png
├── Devices
│ └── SWITCH1.png
├── HumanGreeting.png
├── IMPORT.png
├── LOGIN.png
└── UI.png
├── UserControls
├── GridCanvas.xaml
└── GridCanvas.xaml.cs
├── UserPages
├── About.xaml
├── About.xaml.cs
├── CabinetManage.xaml
├── CabinetManage.xaml.cs
├── DataPreset.xaml
├── DataPreset.xaml.cs
├── DatabaseBackup.xaml
├── DatabaseBackup.xaml.cs
├── DevicesPage.xaml
├── DevicesPage.xaml.cs
├── DonationPage.xaml
├── DonationPage.xaml.cs
├── HelpPage.xaml
├── HelpPage.xaml.cs
├── HumanGreeting.xaml
├── HumanGreeting.xaml.cs
├── IndexPage.xaml
├── IndexPage.xaml.cs
├── ModelPreset.xaml
├── ModelPreset.xaml.cs
├── NetworkManage.xaml
├── NetworkManage.xaml.cs
├── PeoplePreset.xaml
└── PeoplePreset.xaml.cs
├── UserWindows
├── AddIndexWindow.xaml
├── AddIndexWindow.xaml.cs
├── DeviceImportWindow.xaml
├── DeviceImportWindow.xaml.cs
├── SetPasswordWindow.xaml
├── SetPasswordWindow.xaml.cs
├── TESTWindow.xaml
├── TESTWindow.xaml.cs
├── VerifyPasswordWindow.xaml
└── VerifyPasswordWindow.xaml.cs
├── VersionCheck.cs
├── ViewMode.cs
├── ipam.ico
└── packages.config
/.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 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # ASP.NET Scaffolding
67 | ScaffoldingReadMe.txt
68 |
69 | # StyleCop
70 | StyleCopReport.xml
71 |
72 | # Files built by Visual Studio
73 | *_i.c
74 | *_p.c
75 | *_h.h
76 | *.ilk
77 | *.meta
78 | *.obj
79 | *.iobj
80 | *.pch
81 | *.pdb
82 | *.ipdb
83 | *.pgc
84 | *.pgd
85 | *.rsp
86 | *.sbr
87 | *.tlb
88 | *.tli
89 | *.tlh
90 | *.tmp
91 | *.tmp_proj
92 | *_wpftmp.csproj
93 | *.log
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | # Fody - auto-generated XML schema
363 | FodyWeavers.xsd
364 | /Resources/UI.psd
365 |
--------------------------------------------------------------------------------
/AddDeviceWindow.xaml:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
51 |
52 |
53 |
57 |
58 |
59 |
62 |
67 |
70 |
71 |
72 |
73 |
76 |
77 |
80 |
85 |
88 |
89 |
90 |
91 |
92 |
96 |
97 |
100 |
105 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/AddDeviceWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Shapes;
15 | using IPAM_NOTE.DevicePage;
16 |
17 | namespace IPAM_NOTE
18 | {
19 | ///
20 | /// AddDeviceWindow.xaml 的交互逻辑
21 | ///
22 | public partial class AddDeviceWindow : Window
23 | {
24 | public AddDeviceWindow()
25 | {
26 | InitializeComponent();
27 | GeneralNetworkDevice.CloseParentWindowRequested += GeneralNetworkDevice_CloseParentWindowRequested; ;
28 | }
29 |
30 | private void GeneralNetworkDevice_CloseParentWindowRequested(object sender, EventArgs e) =>Close();
31 |
32 |
33 |
34 | private void TopControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
35 | {
36 | int index = TopControl.SelectedIndex;
37 |
38 |
39 |
40 | switch (index)
41 | {
42 | case 0:
43 | DevicePanel.Children.Clear();
44 | GeneralNetworkDevice generalNetworkDevice = new GeneralNetworkDevice();
45 | DevicePanel.Children.Add(generalNetworkDevice);
46 |
47 |
48 | break;
49 |
50 | case 1:
51 |
52 | break;
53 | }
54 | }
55 |
56 | private void AddDeviceWindow_OnClosing(object sender, CancelEventArgs e)
57 | {
58 | this.DialogResult = true;
59 | }
60 |
61 |
62 | private void AddDeviceWindow_OnLoaded(object sender, RoutedEventArgs e)
63 | {
64 | DevicePanel.Children.Clear();
65 | GeneralNetworkDevice generalNetworkDevice = new GeneralNetworkDevice();
66 | DevicePanel.Children.Add(generalNetworkDevice);
67 |
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/AddWindow.xaml:
--------------------------------------------------------------------------------
1 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
37 |
38 |
45 |
46 |
54 |
55 |
56 |
57 |
58 |
69 |
70 |
71 |
72 |
73 |
74 |
80 |
81 |
89 |
90 |
93 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
123 |
124 |
125 |
126 |
133 |
134 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
174 |
175 |
183 |
184 |
185 |
186 |
187 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
234 |
235 |
243 |
244 |
251 |
252 |
253 |
260 |
261 |
262 |
263 |
270 |
271 |
278 |
279 |
280 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
--------------------------------------------------------------------------------
/AddWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using IPAM_NOTE.DatabaseOperation;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Data.SqlClient;
6 | using System.Data.SQLite;
7 | using System.Linq;
8 | using System.Net;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using System.Web.Hosting;
12 | using System.Windows;
13 | using System.Windows.Controls;
14 | using System.Windows.Data;
15 | using System.Windows.Documents;
16 | using System.Windows.Input;
17 | using System.Windows.Media;
18 | using System.Windows.Media.Imaging;
19 | using System.Windows.Shapes;
20 |
21 | namespace IPAM_NOTE
22 | {
23 | ///
24 | /// AddWindow.xaml 的交互逻辑
25 | ///
26 | public partial class AddWindow : Window
27 | {
28 | public AddWindow()
29 | {
30 | InitializeComponent();
31 | }
32 |
33 | private DbClass dbClass;
34 |
35 |
36 |
37 | private void AddWindow_OnLoaded(object sender, RoutedEventArgs e)
38 | {
39 | LoadStatus=true;
40 |
41 | if (DataBrige.AddStatus==0)
42 | {
43 | this.Title = "添加网段";
44 |
45 |
46 | }
47 | else
48 | {
49 | this.Title = "编辑网段信息";
50 | IpTextBox.Text = DataBrige.TempAddress.Network;
51 | MaskText.Text = DataBrige.TempAddress.NetMask;
52 | IpDescription.Text = DataBrige.TempAddress.Description;
53 |
54 | CalculateNetMaskLocated();
55 |
56 | IpTextBox.IsEnabled = false;
57 | MaskText.IsEnabled = false;
58 | MaskSlider.IsEnabled=false;
59 | UpdateIPCalculations();
60 | }
61 |
62 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
63 | string dbName = "Address_database.db";
64 |
65 | dbFilePath = dbFilePath + dbName;
66 |
67 | dbClass = new DbClass(dbFilePath);
68 | dbClass.OpenConnection();
69 |
70 |
71 | }
72 |
73 | ///
74 | /// 保存新建的网段
75 | ///
76 | ///
77 | ///
78 | private void SaveButton_Click(object sender, RoutedEventArgs e)
79 | {
80 | //添加网段
81 | if (DataBrige.AddStatus == 0)
82 | {
83 |
84 | //判断是不是瞎几把写的IP地址
85 | if (IsValidIp(IpTextBox.Text) == true)
86 | {
87 | //计算IP
88 | UpdateIPCalculations();
89 |
90 | //网段地址
91 | string ip = Network.Text;
92 | string netMask = MaskText.Text;
93 |
94 | if (IpDescription.Text != "")
95 | {
96 | string tableName;
97 |
98 | string sqlTemp = string.Format("SELECT COUNT(*) FROM Network WHERE `Network` = '{0}' AND `Netmask` = '{1}'", ip, netMask);
99 |
100 |
101 |
102 | int num = dbClass.ExecuteScalarTableNum(sqlTemp, dbClass.connection);
103 |
104 | //IP地址段已存在
105 | if (num > 0)
106 | {
107 | string msg = string.Format("已存在同配置网段{0}个,是否继续添加同配置网段?", num.ToString());
108 |
109 | MessageBoxResult result = MessageBox.Show(msg, "确认", MessageBoxButton.YesNo,
110 | MessageBoxImage.Information);
111 |
112 | if (result == MessageBoxResult.Yes)
113 | {
114 | // 用户点击了"是"按钮,执行相关操作
115 | tableName = CreateTableName(ip,netMask) + "_" + (num + 1).ToString();
116 |
117 | Console.WriteLine(tableName);
118 |
119 | //插入网段信息总表的数据
120 | string sql = string.Format(
121 | "INSERT INTO Network (TableName,Network,Netmask,Description,Del) VALUES ('{0}','{1}','{2}','{3}','{4}')",
122 | tableName, ip, netMask, IpDescription.Text, 0);
123 |
124 | dbClass.ExecuteQuery(sql);
125 |
126 | //创建表
127 | CreateTable(tableName);
128 |
129 | //装载初始化数据
130 | InitializedData(tableName);
131 |
132 |
133 | this.DialogResult = true;
134 | this.Close();
135 |
136 |
137 |
138 | }
139 | else if (result == MessageBoxResult.No)
140 | {
141 | // 用户点击了"否"按钮,取消操作或进行其他处理
142 |
143 |
144 | }
145 |
146 |
147 | }
148 | else
149 | {
150 |
151 | tableName = CreateTableName(ip, netMask) + "_1";
152 |
153 | Console.WriteLine(tableName);
154 |
155 | //插入网段信息总表的数据
156 | string sql = string.Format(
157 | "INSERT INTO Network (TableName,Network,Netmask,Description,Del) VALUES ('{0}','{1}','{2}','{3}','{4}')",
158 | tableName, ip, netMask, IpDescription.Text, 0);
159 |
160 | dbClass.ExecuteQuery(sql);
161 |
162 | //插入网段信息总表的数据
163 |
164 | //创建表
165 | CreateTable(tableName);
166 |
167 | //装载初始化数据
168 | InitializedData(tableName);
169 |
170 |
171 | this.DialogResult = true;
172 | this.Close();
173 |
174 |
175 |
176 | }
177 |
178 |
179 | }
180 | else
181 | {
182 |
183 | MessageBox.Show("为了便于后期管理,必须填写网段说明!", "确定", MessageBoxButton.OK, MessageBoxImage.Information);
184 |
185 |
186 | }
187 |
188 | }
189 | else
190 | {
191 | MessageBox.Show("IP地址不合法,请检查IP地址是否正确!", "确定", MessageBoxButton.OK, MessageBoxImage.Information);
192 | }
193 |
194 | }
195 | else//编辑网段
196 | {
197 |
198 |
199 | if (IpDescription.Text!="")
200 | {
201 | string tableName = DataBrige.TempAddress.TableName;
202 |
203 | string sqlTemp = string.Format("UPDATE \"Network\" SET \"Description\" = '{0}' WHERE TableName = '{1}'", IpDescription.Text, tableName);
204 |
205 | Console.WriteLine(sqlTemp);
206 |
207 | dbClass.ExecuteQuery(sqlTemp);
208 |
209 |
210 |
211 | this.Close();
212 | }
213 |
214 |
215 |
216 |
217 |
218 | }
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 | }
227 |
228 | ///
229 | /// 判断是否是合法IP
230 | ///
231 | ///
232 | ///
233 | static bool IsValidIp(string ipAddress)
234 | {
235 | IPAddress address;
236 | return IPAddress.TryParse(ipAddress, out address);
237 | }
238 |
239 | ///
240 | /// 生成表名
241 | ///
242 | ///
243 | private string CreateTableName(string address,string netmask)
244 | {
245 | string name = Network.Text + "_" + MaskText.Text;
246 | name = "tb_" + name.Replace(".", "_");
247 |
248 | return name;
249 | }
250 |
251 | ///
252 | /// 创建一张数据表
253 | ///
254 | ///
255 | ///
256 | private void CreateTable(string tableName)
257 | {
258 | string sql = string.Format(
259 | "CREATE TABLE IF NOT EXISTS {0} (Address INTEGER NOT NULL ,AddressStatus INTEGER , User VARCHAR ( 16 ),Description VARCHAR ( 80 ),HostName VARCHAR ( 64 ),MacAddress VARCHAR ( 20 ))",
260 | tableName);
261 |
262 | dbClass.ExecuteQuery(sql);
263 |
264 |
265 | }
266 |
267 | ///
268 | /// 填充网段表单初始数据
269 | ///
270 | private void InitializedData(string tableName)
271 | {
272 | string[] parts = Network.Text.Split('.');
273 |
274 | //取出第一个IP
275 | int firstIp =Convert.ToInt32( parts[3]);
276 |
277 |
278 | parts = Broadcast.Text.Split('.');
279 |
280 | //取出最后一个IP,广播IP
281 | int LastIp = Convert.ToInt32(parts[3]);
282 |
283 |
284 |
285 | int x = Convert.ToInt32(NumBox.Text);
286 |
287 | for (int i = 0; i < x; i++)
288 | {
289 | //IP地址锁定状态:0不可用IP,1可用IP
290 | int addressStatus = 0;
291 |
292 | int ip = firstIp + i;
293 |
294 |
295 |
296 | List lockip = new List();
297 |
298 | if (ip == firstIp)
299 | {
300 | addressStatus = 0;
301 |
302 | }
303 | else
304 | {
305 | if (ip == LastIp )
306 | {
307 |
308 | addressStatus = 3;
309 | }
310 | else
311 | {
312 | addressStatus = 1;
313 | }
314 | }
315 |
316 | string sql = string.Format("INSERT INTO `{0}` (`Address`, `AddressStatus`) VALUES ({1}, {2})",
317 | tableName, ip, addressStatus);
318 |
319 |
320 | //Console.WriteLine(sql);
321 | //异步执行
322 | dbClass.ExecuteQuery(sql);
323 | }
324 |
325 |
326 | }
327 |
328 |
329 | ///
330 | /// 传递窗口关闭信息
331 | ///
332 | ///
333 | ///
334 | private void AddWindow_OnClosing(object sender, CancelEventArgs e)
335 | {
336 | this.DialogResult = true;
337 | }
338 |
339 |
340 | ///
341 | /// 页面加载状态(页面未完成加载时不计算IP)
342 | ///
343 | public bool LoadStatus = false;
344 |
345 |
346 |
347 | ///
348 | /// 拖动滑条调整子网掩码
349 | ///
350 | ///
351 | ///
352 | private void MaskSlider_OnValueChanged(object sender, RoutedPropertyChangedEventArgs e)
353 | {
354 | if (LoadStatus == true)
355 | {
356 | //判断是不是瞎几把写的IP地址
357 | if (IsValidIp(IpTextBox.Text) == true)
358 | {
359 | UpdateIPCalculations();
360 | }
361 | else
362 | {
363 | IpTextBox.Text = "";
364 | MessageBox.Show("IP地址不合法,请检查IP地址是否正确!", "确定", MessageBoxButton.OK, MessageBoxImage.Information);
365 | }
366 |
367 |
368 | }
369 |
370 |
371 | }
372 |
373 |
374 |
375 | ///
376 | /// 计算子网掩码位数
377 | ///
378 | ///
379 | private void CalculateNetMaskLocated()
380 | {
381 | string ipStr = MaskText.Text;
382 | int index = ipStr.LastIndexOf(".") + 1;
383 |
384 | string strTemp = ipStr.Substring(index, ipStr.Length - index);
385 |
386 | if (strTemp == "0")
387 | {
388 | strTemp = "256";
389 | }
390 |
391 | string str = Convert.ToString(Convert.ToInt32(strTemp), 2);
392 |
393 |
394 |
395 | index = str.IndexOf("0");
396 |
397 |
398 | string str2 = str.Substring(index, str.Length - index);
399 |
400 | // MessageBox.Show(str2);
401 |
402 |
403 |
404 | MaskSlider.Value = 32 - str2.Length;
405 | }
406 |
407 |
408 | ///
409 | /// IP地址计算
410 | ///
411 | private void UpdateIPCalculations()
412 | {
413 | try
414 | {
415 | IPAddress ip;
416 | if (IPAddress.TryParse(IpTextBox.Text, out ip))
417 | {
418 | int maskLength = (int)MaskSlider.Value;
419 | IPAddress mask = IPAddressCalculations.SubnetMaskFromPrefixLength(maskLength);
420 | MaskText.Text = mask.ToString();
421 |
422 | IPAddress networkAddress = ip.GetNetworkAddress(mask);
423 | Network.Text = networkAddress.ToString();
424 |
425 | IPAddress firstAddress = networkAddress.GetFirstUsable(ip.AddressFamily);
426 | First.Text = firstAddress.ToString();
427 |
428 | IPAddress lastAddress = networkAddress.GetLastUsable(ip.AddressFamily, maskLength);
429 |
430 | Last.Text = lastAddress.ToString();
431 |
432 | IPAddress broadcastAddress = networkAddress.GetBroadcastAddress(maskLength);
433 | Broadcast.Text = broadcastAddress.ToString();
434 |
435 |
436 | long addressCount = IPAddressCalculations.AddressCount(maskLength);
437 | NumBox.Text = addressCount.ToString();
438 | }
439 | }
440 | catch (Exception ex)
441 | {
442 | MessageBox.Show($"An error occurred: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
443 | }
444 | }
445 |
446 |
447 | }
448 |
449 | }
450 |
451 |
452 |
453 |
454 |
455 |
--------------------------------------------------------------------------------
/App.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 |
--------------------------------------------------------------------------------
/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using IPAM_NOTE.DatabaseOperation;
2 | using IPAM_NOTE.UserWindows;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Configuration;
6 | using System.Data;
7 | using System.Data.SQLite;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Threading.Tasks;
11 | using System.Windows;
12 | using System.Windows.Threading;
13 |
14 | namespace IPAM_NOTE
15 | {
16 | ///
17 | /// App.xaml 的交互逻辑
18 | ///
19 | public partial class App : Application
20 | {
21 |
22 |
23 |
24 |
25 | protected override void OnStartup(StartupEventArgs e)
26 | {
27 |
28 |
29 | base.OnStartup(e);
30 |
31 | //订阅全局异常信息
32 | this.DispatcherUnhandledException += App_DispatcherUnhandledException;
33 |
34 |
35 | // 检查 SQLite 数据库文件是否存在
36 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
37 | string dbName = "Address_database.db";
38 |
39 | if (!Directory.Exists(dbFilePath))
40 | {
41 | Directory.CreateDirectory(dbFilePath);
42 | }
43 |
44 | dbFilePath = Path.Combine(dbFilePath, dbName);
45 |
46 |
47 | if (!File.Exists(dbFilePath))
48 | {
49 | // 如果数据库文件不存在,则创建一个新的数据库文件
50 | SQLiteConnection.CreateFile(dbFilePath);
51 |
52 | // 创建数据库表
53 | using (SQLiteConnection connection = new SQLiteConnection($"Data Source={dbFilePath};Version=3;"))
54 | {
55 | connection.Open();
56 | using (SQLiteCommand command = new SQLiteCommand(connection))
57 | {
58 | // 创建表的 SQL 语句
59 | command.CommandText = $"CREATE TABLE \"Devices\" (\r\n \"Id\" INTEGER PRIMARY KEY AUTOINCREMENT,\r\n \"TableName\" TEXT,\r\n \"Name\" TEXT,\r\n \"Model\" TEXT,\r\n \"Number\" TEXT,\r\n \"People\" TEXT,\r\n \"Date\" TEXT,\r\n \"Description\" TEXT,\r\n \"Eport\" integer,\r\n \"EportTag\" TEXT,\r\n \"Fport\" integer,\r\n \"FportTag\" TEXT,\r\n \"Mport\" integer,\r\n \"MportTag\" TEXT,\r\n \"Dport\" integer,\r\n \"DportTag\" TEXT\r\n);";
60 | command.ExecuteNonQuery();
61 | command.CommandText = "CREATE TABLE \"Network\" (\r\n \"Id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\r\n \"TableName\" TEXT,\r\n \"Network\" TEXT,\r\n \"Netmask\" TEXT,\r\n \"Description\" TEXT,\r\n \"Del\" TEXT\r\n)";
62 | command.ExecuteNonQuery();
63 | command.CommandText = $"CREATE TABLE \"User\" (\r\n \"Id\" INTEGER PRIMARY KEY AUTOINCREMENT,\r\n \"Password\" TEXT);";
64 | command.ExecuteNonQuery();
65 | command.CommandText = $"CREATE TABLE \"ModelPreset\" (\r\n \"Id\" INTEGER PRIMARY KEY AUTOINCREMENT, \r\n \"ModelType\" TEXT, \r\n \"Brand\" TEXT,\r\n \"Model\" TEXT,\r\n \"Ethernet\" TEXT,\r\n \"Fiber\" TEXT,\r\n \"Disk\" TEXT\r\n,,\r\n \"Manage\" TEXT\r\n);";
66 | command.ExecuteNonQuery();
67 | }
68 | }
69 | }
70 |
71 |
72 |
73 | }
74 |
75 |
76 |
77 | ///
78 | /// 全局异常处理
79 | ///
80 | ///
81 | ///
82 | private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
83 | {
84 | // 处理异常
85 | // 记录异常信息、显示友好的错误提示框等
86 | Console.WriteLine(e.Exception);
87 | e.Handled = true; // 标记为已处理,防止应用程序终止
88 | }
89 |
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/DataBrige.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using static IPAM_NOTE.ViewMode;
9 |
10 | namespace IPAM_NOTE
11 | {
12 | internal class DataBrige
13 | {
14 | public static ViewMode.AddressInfo TempAddress = new ViewMode.AddressInfo(0, "", "", "", "", "");
15 |
16 | public static string SelectIp;
17 |
18 | public static ViewMode.IpAddressInfo IpAddress = new ViewMode.IpAddressInfo(0, 0, "", "", System.Net.NetworkInformation.IPStatus.Unknown, -1, "", "", "", "");
19 |
20 | public static List ipAddressInfos = new List();
21 |
22 | ///
23 | /// 当前软件版本号
24 | ///
25 | public static string Ver = "1.24";
26 |
27 | ///
28 | /// 最新版本号
29 | ///
30 | public static string LatestVersion = "0";
31 |
32 | ///
33 | /// 最新下载地址
34 | ///
35 | public static String DownloadUrl = "";
36 |
37 | ///
38 | /// 0为新建网段,1为编辑网段
39 | ///
40 | public static int AddStatus = 0;
41 |
42 | ///
43 | /// 搜索框搜索后被选中的IP地址索引
44 | ///
45 | public static int SelectIndex;
46 |
47 | ///
48 | /// 搜索框搜索的网段INDEX
49 | ///
50 | public static int SelectNetwork;
51 |
52 | ///
53 | /// 正常加载=0,搜索加载=1
54 | ///
55 | public static int LoadType;
56 |
57 | ///
58 | /// 搜索时所选表格名字
59 | ///
60 | public static string SelectTableName;
61 |
62 |
63 | //public static List ipAddressInfos = new List();
64 |
65 |
66 |
67 |
68 | //搜索区网段列表
69 | public static ObservableCollection ComBoxAddressInfos = new ObservableCollection();
70 |
71 | ///
72 | /// 数据导入界面,网段ComboBox数据源
73 | ///
74 | public static List ComboBoxAddressList = new List();
75 |
76 | ///
77 | /// 被选择的按钮的标记
78 | ///
79 | public static int SelectButtonTag;
80 |
81 | ///
82 | /// 搜索的类型,0为全局搜索,1为指定搜索
83 | ///
84 | public static int SearchType;
85 |
86 |
87 | ///
88 | /// 全局搜索时点击搜索结果被选中的表项
89 | ///
90 | public static ViewMode.SearchInfo SelectSearchInfo = new ViewMode.SearchInfo();
91 |
92 |
93 | ///
94 | /// 全局搜索时候获取的结果列表
95 | ///
96 | public static List searchInfos = new List();
97 |
98 |
99 | ///
100 | /// 分配或者释放模式,0为未选择状态、1为选择未分配地址准备分配,2为选择已分配地址准备释放
101 | ///
102 | public static int SelectMode = 0;
103 |
104 |
105 | ///
106 | /// 多选模式下一并被选择的IP
107 | ///
108 | public static List SelectedIpAddress = new List();
109 |
110 |
111 | ///
112 | /// 更新信息
113 | ///
114 | public static string UpdateInfos = "";
115 |
116 |
117 | //----------------------------DevicesPage-----------------------------------
118 |
119 | //获取到的设备信息列表
120 | public static List DeviceInfos = new List();
121 |
122 |
123 | ///
124 | /// 从数据库获取到的设备端口信息列表
125 | ///
126 | public static List DevicePortInfos = new List();
127 |
128 | ///
129 | /// 所选设备端口的标签
130 | ///
131 | public static string SelectDeviceButtonTag;
132 |
133 |
134 |
135 | ///
136 | /// 点击设备列表时临时存储当前所选设备的对应信息
137 | ///
138 | public static ViewMode.DeviceInfo SelectDeviceInfo;
139 |
140 |
141 | ///
142 | /// 点击端口按钮后临时存储所选端口对应的信息
143 | ///
144 | public static ViewMode.DevicePortInfo SelectDevicePortInfo;
145 |
146 |
147 | ///
148 | /// 0为添加设备,1为编辑设备
149 | ///
150 | public static int DeviceAddStatus = 0;
151 |
152 |
153 | ///
154 | /// 设备端口的选择模式,0为未选择状态,1为已选择未分配端口准备分配,2为已选择已分配端口准备释放
155 | ///
156 | public static int SelectDevicePortMode = 0;
157 |
158 | ///
159 | /// 多选模式下首次选择的端口类型,E,F,M,D
160 | ///
161 | public static string SelectDevicePortType = "";
162 |
163 |
164 | ///
165 | /// 多选模式下首次选择的端口状态,0未分配,1已分配
166 | ///
167 | public static string SelectDevicePortStatus = "-1";
168 |
169 | ///
170 | /// 多选模式下,一次选择的多个端口清单
171 | ///
172 | public static List portList = new List();//批量选择的端口号
173 |
174 | ///
175 | /// 设备端口列表显示还是图形显示,0为图形,1为列表
176 | ///
177 | public static int GraphicsMode = 0;
178 |
179 |
180 | ///
181 | /// 搜索的设备表名
182 | ///
183 | public static string SearchDeviceTableName;
184 |
185 | ///
186 | /// 点击设备列表时候的设备表名
187 | ///
188 | public static string SelectDeviceTableName;
189 |
190 |
191 | ///
192 | /// 全局搜索到的设备信息清单
193 | ///
194 | public static List SearchDeviceInfos = new List();
195 |
196 |
197 | ///
198 | /// 设备信息加载方式,0为正常加载,1为搜索加载
199 | ///
200 | public static int DeviceLoadType;
201 |
202 |
203 | ///
204 | /// 设备端口信息搜索方式,0为全局搜索,1为指定搜索
205 | ///
206 | public static int DeviceSearchType = -1;
207 |
208 |
209 |
210 | ///
211 | /// 设备列表,显示在搜索筛选框
212 | ///
213 | public static List DevicesList = new List();
214 |
215 |
216 | ///
217 | /// 表示点击标签是编辑还是访问,0为访问,1为编辑
218 | ///
219 | public static int EditMode = 0;
220 |
221 |
222 | ///
223 | /// 表示当前选中的导航标签,-1为未选择
224 | ///
225 | public static int SelectIndexTag = -1;
226 |
227 | //----------------------------ModelPreset-----------------------------------
228 |
229 | ///
230 | /// 型号预设列表
231 | ///
232 | public static List ModelPresetInfos = new List();
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/DatabaseOperation/DbClass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Common;
4 | using System.Data.SqlClient;
5 | using System.Data.SQLite;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows;
11 | using MaterialDesignThemes.Wpf.Transitions;
12 |
13 | namespace IPAM_NOTE.DatabaseOperation
14 | {
15 | internal class DbClass
16 | {
17 |
18 |
19 | public SQLiteConnection connection;
20 |
21 |
22 | public DbClass(string dbPath)
23 | {
24 |
25 | connection = new SQLiteConnection($"Data Source={dbPath};Version=3;");
26 |
27 |
28 | }
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | public void OpenConnection()
37 | {
38 | if (connection.State != System.Data.ConnectionState.Open)
39 | {
40 | connection.Open();
41 | }
42 | }
43 |
44 |
45 | public void CloseConnection()
46 | {
47 | if (connection.State != System.Data.ConnectionState.Closed)
48 | {
49 | connection.Close();
50 | }
51 | }
52 |
53 | public void CreateTable(string query)
54 | {
55 | SQLiteCommand command = new SQLiteCommand(query, connection);
56 | command.ExecuteNonQuery();
57 | }
58 |
59 |
60 | public SQLiteDataReader ExecuteQuery(string query)
61 | {
62 |
63 | Console.WriteLine(query);
64 | using (SQLiteCommand command = new SQLiteCommand(query, connection))
65 | {
66 | using (SQLiteDataReader reader = command.ExecuteReader())
67 | {
68 | return reader;
69 | }
70 | }
71 | }
72 |
73 |
74 |
75 |
76 | // 执行 SQL 查询函数
77 | static void ExecuteSql(SQLiteConnection connection, string sqlQuery)
78 | {
79 | // 创建命令对象
80 | using (SQLiteCommand command = new SQLiteCommand(sqlQuery, connection))
81 | {
82 | try
83 | {
84 | // 执行 SQL 命令
85 | int rowsAffected = command.ExecuteNonQuery();
86 |
87 | // 输出受影响的行数
88 | Console.WriteLine($"Rows Affected: {rowsAffected}");
89 | }
90 | catch (Exception ex)
91 | {
92 | // 处理异常
93 | Console.WriteLine($"Error executing SQL query: {ex.Message}");
94 | }
95 | }
96 | }
97 |
98 |
99 |
100 | ///
101 | /// 查询表中的数据数量,返回数据条数
102 | ///
103 | ///
104 | ///
105 | public int ExecuteScalarTableNum(string sql,SQLiteConnection connection)
106 | {
107 |
108 |
109 |
110 | using (SQLiteCommand command = new SQLiteCommand(sql,connection))
111 | {
112 | // 使用 ExecuteScalar 获取总行数
113 | int rowCount = Convert.ToInt32(command.ExecuteScalar());
114 |
115 | return rowCount;
116 |
117 | //MessageBox.Show( GlobalFunction.IpAddressConvert.IpToDecimal(IpTextBox.Text).ToString());
118 |
119 | }
120 |
121 |
122 |
123 |
124 | }
125 |
126 |
127 | ///
128 | /// 异步插入数据
129 | ///
130 | ///
131 | ///
132 | public async Task InsertDataAsync(string sql)
133 | {
134 | using (connection)
135 | {
136 | await connection.OpenAsync();
137 |
138 | using (SQLiteCommand command = connection.CreateCommand())
139 | {
140 |
141 | command.CommandText = sql;
142 |
143 | // 异步执行插入操作
144 | await command.ExecuteNonQueryAsync();
145 | }
146 | }
147 | }
148 |
149 |
150 | // 检测表是否存在
151 | public bool IsTableExists(string tableName)
152 | {
153 |
154 |
155 | using (SQLiteCommand command = new SQLiteCommand(connection))
156 | {
157 | command.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}';";
158 | using (SQLiteDataReader reader = command.ExecuteReader())
159 | {
160 | return reader.HasRows; // 如果有行,则表存在,否则不存在
161 | }
162 | }
163 |
164 | }
165 |
166 |
167 | ///
168 | /// 创建设备表
169 | ///
170 | ///
171 | public void CreateTableIfNotExists(string tableName)
172 | {
173 | if (!IsTableExists(tableName))
174 | {
175 |
176 | using (SQLiteCommand command = new SQLiteCommand(connection))
177 | {
178 | // 创建表的 SQL 语句
179 | command.CommandText = $"CREATE TABLE \"Devices\" (\r\n \"Id\" INTEGER PRIMARY KEY AUTOINCREMENT,\r\n \"TableName\" TEXT,\r\n \"Name\" TEXT,\r\n \"Model\" TEXT,\r\n \"Number\" TEXT,\r\n \"People\" TEXT,\r\n \"Date\" TEXT,\r\n \"Description\" TEXT,\r\n \"Eport\" integer,\r\n \"EportTag\" TEXT,\r\n \"Fport\" integer,\r\n \"FportTag\" TEXT,\r\n \"Mport\" integer,\r\n \"MportTag\" TEXT,\r\n \"Dport\" integer,\r\n \"DportTag\" TEXT\r\n);";
180 | command.ExecuteNonQuery();
181 | }
182 |
183 | }
184 | }
185 |
186 |
187 | ///
188 | /// 创建用户表
189 | ///
190 | ///
191 | public void CreateTableIfNotExistsUser(string tableName)
192 | {
193 | if (!IsTableExists(tableName))
194 | {
195 |
196 | using (SQLiteCommand command = new SQLiteCommand(connection))
197 | {
198 | // 创建表的 SQL 语句
199 | command.CommandText = $"CREATE TABLE \"{tableName}\" (\r\n \"Id\" INTEGER PRIMARY KEY AUTOINCREMENT,\r\n \"Password\" TEXT);";
200 | command.ExecuteNonQuery();
201 |
202 | }
203 |
204 | }
205 | }
206 |
207 |
208 |
209 | ///
210 | /// 创建设备型号预设表
211 | ///
212 | ///
213 | public void CreateModelPresetIfNotExists(string tableName)
214 | {
215 | if (!IsTableExists(tableName))
216 | {
217 |
218 | using (SQLiteCommand command = new SQLiteCommand(connection))
219 | {
220 | // 创建表的 SQL 语句
221 | command.CommandText = $"CREATE TABLE \"ModelPreset\" (\r\n \"Id\" INTEGER PRIMARY KEY AUTOINCREMENT, \r\n \"ModelType\" TEXT, \r\n \"Brand\" TEXT,\r\n \"Model\" TEXT,\r\n \"Ethernet\" TEXT,\r\n \"Fiber\" TEXT,\r\n \"Disk\" TEXT\r\n,,\r\n \"Manage\" TEXT\r\n);";
222 |
223 | command.ExecuteNonQuery();
224 | }
225 |
226 | }
227 | }
228 |
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/GitHubVersionChecker.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows;
9 |
10 | namespace IPAM_NOTE
11 | {
12 | public class GitHubVersionChecker
13 | {
14 | private readonly string _repositoryOwner;
15 | private readonly string _repositoryName;
16 |
17 | public GitHubVersionChecker(string repositoryOwner, string repositoryName)
18 | {
19 | _repositoryOwner = repositoryOwner;
20 | _repositoryName = repositoryName;
21 | }
22 |
23 | public async Task GetLatestVersionAsync()
24 | {
25 | try
26 | {
27 | string apiUrl = $"https://api.github.com/repos/{_repositoryOwner}/{_repositoryName}/releases/latest";
28 |
29 | using (HttpClient client = new HttpClient())
30 | {
31 | client.DefaultRequestHeaders.Add("User-Agent", "YourAppName");
32 | HttpResponseMessage response = await client.GetAsync(apiUrl);
33 | response.EnsureSuccessStatusCode();
34 |
35 | string json = await response.Content.ReadAsStringAsync();
36 | var release = JsonConvert.DeserializeObject(json);
37 |
38 | return release.TagName;
39 | }
40 | }
41 | catch (Exception ex)
42 | {
43 | // 处理异常
44 | Console.WriteLine($"An error occurred: {ex.Message}");
45 | return null;
46 | }
47 | }
48 |
49 | public async Task GetDownloadUrlAsync()
50 | {
51 | try
52 | {
53 | string apiUrl = $"https://api.github.com/repos/{_repositoryOwner}/{_repositoryName}/releases/latest";
54 |
55 | using (HttpClient client = new HttpClient())
56 | {
57 | client.DefaultRequestHeaders.Add("User-Agent", @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.53");
58 | HttpResponseMessage response = await client.GetAsync(apiUrl);
59 | response.EnsureSuccessStatusCode();
60 |
61 | string json = await response.Content.ReadAsStringAsync();
62 | var release = JsonConvert.DeserializeObject(json);
63 |
64 | // 遍历附件列表,找到下载链接
65 | foreach (var asset in release.Assets)
66 | {
67 | if (!string.IsNullOrEmpty(asset.DownloadUrl))
68 | {
69 | return asset.DownloadUrl;
70 | }
71 | }
72 |
73 | // 如果找不到下载链接,返回 null
74 | return null;
75 | }
76 | }
77 | catch (Exception ex)
78 | {
79 | // 处理异常
80 | Console.WriteLine($"An error occurred: {ex.Message}");
81 | return null;
82 | }
83 | }
84 |
85 | public async Task GetReleaseBodyAsync()
86 | {
87 | try
88 | {
89 | string apiUrl = $"https://api.github.com/repos/{_repositoryOwner}/{_repositoryName}/releases/latest";
90 |
91 | using (HttpClient client = new HttpClient())
92 | {
93 | client.DefaultRequestHeaders.Add("User-Agent", @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.53");
94 | HttpResponseMessage response = await client.GetAsync(apiUrl);
95 | response.EnsureSuccessStatusCode();
96 |
97 | string json = await response.Content.ReadAsStringAsync();
98 | var release = JsonConvert.DeserializeObject(json);
99 |
100 | return release.Body;
101 | }
102 | }
103 | catch (Exception ex)
104 | {
105 | // 处理异常
106 | Console.WriteLine($"An error occurred: {ex.Message}");
107 | return "";
108 | }
109 | }
110 |
111 |
112 | private class GitHubRelease
113 | {
114 | [JsonProperty("tag_name")]
115 | public string TagName { get; set; }
116 |
117 | [JsonProperty("assets")]
118 | public List Assets { get; set; }
119 |
120 | [JsonProperty("body")]
121 | public string Body { get; set; }
122 | }
123 |
124 | private class GitHubAsset
125 | {
126 | [JsonProperty("browser_download_url")]
127 | public string DownloadUrl { get; set; }
128 | }
129 |
130 |
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/IPAM-NOTE.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.9.34622.214
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPAM-NOTE", "IPAM-NOTE.csproj", "{89472C4D-6B61-46F3-A976-6F78F15A06FF}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {89472C4D-6B61-46F3-A976-6F78F15A06FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {89472C4D-6B61-46F3-A976-6F78F15A06FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {89472C4D-6B61-46F3-A976-6F78F15A06FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {89472C4D-6B61-46F3-A976-6F78F15A06FF}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {3ABE76A3-E3B6-41E5-A538-994CD6D02E3D}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/IPAddressCalculations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace IPAM_NOTE
9 | {
10 | public static class IPAddressCalculations
11 | {
12 |
13 | public static long AddressCount(int maskLength)
14 | {
15 | return (long)Math.Pow(2, 32 - maskLength);
16 | }
17 |
18 | public static IPAddress SubnetMaskFromPrefixLength(int prefixLength)
19 | {
20 | uint subnet = 0xffffffff;
21 | subnet <<= (32 - prefixLength);
22 | byte[] bytes = BitConverter.GetBytes(subnet);
23 | Array.Reverse(bytes);
24 | return new IPAddress(bytes);
25 | }
26 |
27 | public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask)
28 | {
29 | byte[] ipBytes = address.GetAddressBytes();
30 | byte[] maskBytes = subnetMask.GetAddressBytes();
31 |
32 | byte[] result = new byte[ipBytes.Length];
33 | for (int i = 0; i < ipBytes.Length; i++)
34 | {
35 | result[i] = (byte)(ipBytes[i] & maskBytes[i]);
36 | }
37 |
38 | return new IPAddress(result);
39 | }
40 |
41 | public static IPAddress GetFirstUsable(this IPAddress networkAddress, System.Net.Sockets.AddressFamily addressFamily)
42 | {
43 | byte[] bytes = networkAddress.GetAddressBytes();
44 | bytes[bytes.Length - 1] += 1; // Increment last byte
45 | return new IPAddress(bytes);
46 | }
47 |
48 | public static IPAddress GetLastUsable(this IPAddress networkAddress, System.Net.Sockets.AddressFamily addressFamily, int maskLength)
49 | {
50 | byte[] bytes = networkAddress.GetAddressBytes();
51 | int usableAddresses = (int)Math.Pow(2, 32 - maskLength) - 2; // Calculate the number of usable addresses
52 | int lastByteIndex = bytes.Length - 1;
53 | int carry = usableAddresses / 256;
54 | bytes[lastByteIndex] += (byte)(usableAddresses % 256); // Add remainder to last byte
55 | for (int i = lastByteIndex - 1; i >= 0 && carry > 0; i--)
56 | {
57 | int sum = bytes[i] + carry;
58 | bytes[i] = (byte)(sum % 256);
59 | carry = sum / 256;
60 | }
61 | return new IPAddress(bytes);
62 | }
63 |
64 |
65 | public static IPAddress GetBroadcastAddress(this IPAddress networkAddress, int maskLength)
66 | {
67 | byte[] bytes = networkAddress.GetAddressBytes();
68 | int lastByteIndex = bytes.Length - 1;
69 | int subnetBits = 32 - maskLength;
70 |
71 | for (int i = 0; i < subnetBits; i++)
72 | {
73 | int byteIndex = i / 8;
74 | int bitOffset = i % 8;
75 | bytes[lastByteIndex - byteIndex] |= (byte)(1 << bitOffset);
76 | }
77 |
78 | return new IPAddress(bytes);
79 | }
80 |
81 |
82 | public static int CalculateSubnetMaskLength(IPAddress subnetMask)
83 | {
84 | byte[] bytes = subnetMask.GetAddressBytes();
85 | uint mask = BitConverter.ToUInt32(bytes.Reverse().ToArray(), 0);
86 | int maskLength = 0;
87 | while (mask != 0)
88 | {
89 | maskLength++;
90 | mask <<= 1;
91 | }
92 | return maskLength;
93 | }
94 |
95 |
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/ImportWindow.xaml:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
36 |
37 |
44 |
45 |
51 |
52 |
53 |
62 |
63 |
64 |
65 |
66 |
67 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
107 |
113 |
114 |
115 |
116 |
117 |
128 |
129 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
166 |
167 |
173 |
174 |
175 |
176 |
182 |
183 |
184 |
185 |
186 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [year] [fullname]
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/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("IPAM-NOTE")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("IPAM-NOTE")]
15 | [assembly: AssemblyCopyright("Copyright © 2024")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // 将 ComVisible 设置为 false 会使此程序集中的类型
20 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
21 | //请将此类型的 ComVisible 特性设置为 true。
22 | [assembly: ComVisible(false)]
23 |
24 | //若要开始生成可本地化的应用程序,请设置
25 | //.csproj 文件中的 CultureYouAreCodingWith
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 |
--------------------------------------------------------------------------------
/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本: 4.0.30319.42000
5 | //
6 | // 对此文件的更改可能导致不正确的行为,如果
7 | // 重新生成代码,则所做更改将丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace IPAM_NOTE.Properties
12 | {
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 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// 返回此类使用的缓存 ResourceManager 实例。
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("IPAM_NOTE.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// 重写当前线程的 CurrentUICulture 属性,对
56 | /// 使用此强类型资源类的所有资源查找执行重写。
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace IPAM_NOTE.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IPAM-NOTE
2 | 需要多用户版本的请查看我的另一项目 SIPAM https://github.com/yaobus/SIPAM.git
3 |
4 |
5 | 鉴于在论坛有不少网友没有多用户的IP地址分配记录需求
6 |
7 | 只需要一个本地运行的单用户IP地址分配记录功能
8 |
9 | 于是就有了这个项目IPAM-NOTE(IP地址分配记录本)
10 |
11 | 功能纯粹、界面简洁、无广告、解压即用......
12 |
13 | 添加网段界面如下:
14 |
15 | 
16 |
17 | 分配地址界面如下
18 | 
19 |
20 | 网段图形化界面如下(鼠标悬停可查看被选中IP的分配信息):
21 | 
22 |
23 | 列表显示网段IP详细信息:
24 | 
25 |
26 | 图形化界面单击地址或列表界面双击地址可以弹出地址分配窗口
27 |
28 | 
29 |
30 |
31 | 批量地址检测
32 |
33 | 
34 |
35 | EXCEL导出界面
36 | 
37 |
38 | 搜索界面
39 | 
40 |
41 | UI帮助界面
42 | 
43 |
44 | 数据导入界面
45 | 
46 |
47 | 数据导入帮助界面
48 | 
49 |
50 |
51 | 数据还原界面
52 | 
53 |
54 | 其他界面
55 | 
56 |
--------------------------------------------------------------------------------
/Resources/ADD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/ADD.png
--------------------------------------------------------------------------------
/Resources/ALLOCATION.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/ALLOCATION.png
--------------------------------------------------------------------------------
/Resources/DATAHELP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/DATAHELP.png
--------------------------------------------------------------------------------
/Resources/DONATION.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/DONATION.png
--------------------------------------------------------------------------------
/Resources/Devices/SWITCH1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/Devices/SWITCH1.png
--------------------------------------------------------------------------------
/Resources/HumanGreeting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/HumanGreeting.png
--------------------------------------------------------------------------------
/Resources/IMPORT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/IMPORT.png
--------------------------------------------------------------------------------
/Resources/LOGIN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/LOGIN.png
--------------------------------------------------------------------------------
/Resources/UI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/Resources/UI.png
--------------------------------------------------------------------------------
/UserControls/GridCanvas.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/UserControls/GridCanvas.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 IPAM_NOTE.UserControls
17 | {
18 | ///
19 | /// GridCanvas.xaml 的交互逻辑
20 | ///
21 | public partial class GridCanvas : UserControl
22 | {
23 | private bool isDragging = false;
24 | private Point lastPosition;
25 | private bool isDraggingCanvas = false;
26 | private bool isDraggingContent = false;
27 | private Point lastCanvasPosition;
28 | private Point lastContentPosition;
29 |
30 | public GridCanvas()
31 | {
32 | InitializeComponent();
33 |
34 | }
35 | private void GridCanvas_OnLoaded(object sender, RoutedEventArgs e)
36 | {
37 | DrawGrid();
38 | }
39 |
40 | private void DrawGrid()
41 | {
42 | double width = canvas.ActualWidth;
43 | double height = canvas.ActualHeight;
44 | double gridSizeInInches = 0.2; // 网格大小(英寸)
45 | double strongLineInterval = 10; // 每隔多少条线显示一根更明显的线条
46 | double strongLineThickness = 0.3; // 更明显的线条的粗细
47 |
48 | // 将网格大小转换为像素值
49 | double gridSizeInPixels = gridSizeInInches * 100; // 1 英寸 = 96 像素
50 |
51 | canvas.Children.Clear(); // 清空之前的网格
52 |
53 | for (double x = 0; x < width; x += gridSizeInPixels)
54 | {
55 | Line line = new Line
56 | {
57 | X1 = x,
58 | Y1 = 0,
59 | X2 = x,
60 | Y2 = height,
61 | Stroke = Brushes.LightGray,
62 | StrokeThickness = (x % (gridSizeInPixels * strongLineInterval) == 0) ? strongLineThickness : 0.1
63 | };
64 |
65 | canvas.Children.Add(line);
66 | }
67 |
68 | for (double y = 0; y < height; y += gridSizeInPixels)
69 | {
70 | Line line = new Line
71 | {
72 | X1 = 0,
73 | Y1 = y,
74 | X2 = width,
75 | Y2 = y,
76 | Stroke = Brushes.LightGray,
77 | StrokeThickness = (y % (gridSizeInPixels * strongLineInterval) == 0) ? strongLineThickness : 0.1
78 | };
79 |
80 | canvas.Children.Add(line);
81 | }
82 | }
83 |
84 |
85 |
86 |
87 | private void Canvas_OnMouseRightButtonDown(object sender, MouseButtonEventArgs e)
88 | {
89 | // 右键按下时开始拖动操作
90 | if (e.RightButton == MouseButtonState.Pressed)
91 | {
92 | if (Keyboard.Modifiers == ModifierKeys.None)
93 | {
94 | // 只拖动内容
95 | isDraggingContent = true;
96 | lastContentPosition = e.GetPosition(contentContainer);
97 | contentContainer.CaptureMouse();
98 | }
99 | else
100 | {
101 | // 拖动整个画布
102 | isDraggingCanvas = true;
103 | lastCanvasPosition = e.GetPosition(canvas);
104 | canvas.CaptureMouse();
105 | }
106 | }
107 | }
108 |
109 | private void Canvas_OnMouseRightButtonUp(object sender, MouseButtonEventArgs e)
110 | {
111 | // 右键释放时停止拖动操作
112 | isDraggingCanvas = false;
113 | isDraggingContent = false;
114 | canvas.ReleaseMouseCapture();
115 | contentContainer.ReleaseMouseCapture();
116 | }
117 |
118 | private void Canvas_OnMouseMove(object sender, MouseEventArgs e)
119 | {
120 | if (isDraggingCanvas)
121 | {
122 | // 如果正在拖动整个画布,则根据鼠标移动的距离调整画布的位置
123 | Point newPosition = e.GetPosition(canvas);
124 | double deltaX = newPosition.X - lastCanvasPosition.X;
125 | double deltaY = newPosition.Y - lastCanvasPosition.Y;
126 |
127 | Canvas.SetLeft(contentContainer, Canvas.GetLeft(contentContainer) + deltaX);
128 | Canvas.SetTop(contentContainer, Canvas.GetTop(contentContainer) + deltaY);
129 |
130 | lastCanvasPosition = newPosition;
131 | }
132 | else if (isDraggingContent)
133 | {
134 | // 如果正在拖动内容,则根据鼠标移动的距离调整内容容器的位置
135 | Point newPosition = e.GetPosition(contentContainer);
136 | double deltaX = newPosition.X - lastContentPosition.X;
137 | double deltaY = newPosition.Y - lastContentPosition.Y;
138 |
139 | Canvas.SetLeft(contentContainer, Canvas.GetLeft(contentContainer) + deltaX);
140 | Canvas.SetTop(contentContainer, Canvas.GetTop(contentContainer) + deltaY);
141 |
142 | lastContentPosition = newPosition;
143 | }
144 | }
145 |
146 |
147 |
148 | private void Canvas_OnMouseWheel(object sender, MouseWheelEventArgs e)
149 | {
150 | // 获取当前鼠标相对于 Canvas 左上角的位置
151 | Point mousePosition = e.GetPosition(canvas);
152 |
153 | // 获取鼠标滚轮滚动的增量
154 | int delta = e.Delta;
155 |
156 | // 定义缩放比例的增量,可以根据实际需求进行调整
157 | double scaleIncrement = 0.1;
158 |
159 | // 获取当前 Canvas 的缩放变换
160 | ScaleTransform scaleTransform = canvas.RenderTransform as ScaleTransform;
161 | if (scaleTransform == null)
162 | {
163 | // 如果没有缩放变换,则创建一个新的缩放变换,并应用到 Canvas 上
164 | scaleTransform = new ScaleTransform(1.0, 1.0);
165 | canvas.RenderTransform = scaleTransform;
166 | }
167 |
168 | // 计算新的缩放比例
169 | double newScale = delta > 0 ? scaleTransform.ScaleX + scaleIncrement : scaleTransform.ScaleX - scaleIncrement;
170 |
171 | // 设置缩放比例的上下限,可以根据实际需求进行调整
172 | double minScale = 1;
173 | double maxScale = 3.0;
174 | newScale = Math.Max(minScale, Math.Min(maxScale, newScale));
175 |
176 | // 计算缩放前后画布左上角的偏移量
177 | double offsetXBeforeScale = Canvas.GetLeft(contentContainer);
178 | double offsetYBeforeScale = Canvas.GetTop(contentContainer);
179 | double offsetXAfterScale = offsetXBeforeScale * newScale;
180 | double offsetYAfterScale = offsetYBeforeScale * newScale;
181 |
182 | // 计算鼠标位置相对于画布左上角的偏移量
183 | double deltaX = mousePosition.X - offsetXBeforeScale;
184 | double deltaY = mousePosition.Y - offsetYBeforeScale;
185 |
186 | // 计算缩放后的位置偏移量
187 | double offsetXDelta = offsetXAfterScale - deltaX;
188 | double offsetYDelta = offsetYAfterScale - deltaY;
189 |
190 | // 应用新的缩放比例到 Canvas 上
191 | scaleTransform.ScaleX = newScale;
192 | scaleTransform.ScaleY = newScale;
193 |
194 | // 同时对内容容器应用相同的缩放变换
195 | contentContainer.LayoutTransform = new ScaleTransform(newScale, newScale);
196 |
197 | // 根据缩放后的位置调整画布,以保持鼠标位置不变
198 | Canvas.SetLeft(contentContainer, offsetXDelta);
199 | Canvas.SetTop(contentContainer, offsetYDelta);
200 | }
201 |
202 | // 当用户调整窗口大小时,重新绘制网格线等内容以适应新的大小
203 | private void GridCanvas_OnSizeChanged(object sender, SizeChangedEventArgs e)
204 | {
205 | DrawGrid();
206 | }
207 | }
208 |
209 | }
210 |
211 |
212 |
--------------------------------------------------------------------------------
/UserPages/About.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
37 |
42 |
43 |
44 |
45 |
52 |
53 |
59 |
66 |
67 |
75 |
76 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
96 |
97 |
104 |
105 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
122 |
123 |
128 |
129 |
134 |
135 |
140 |
141 |
146 |
151 |
152 |
157 |
162 |
163 |
168 |
169 |
174 |
175 |
179 |
183 |
184 |
189 |
190 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
207 |
213 |
214 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
--------------------------------------------------------------------------------
/UserPages/About.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Navigation;
15 | using System.Windows.Shapes;
16 |
17 | namespace IPAM_NOTE.UserPages
18 | {
19 | ///
20 | /// About.xaml 的交互逻辑
21 | ///
22 | public partial class About : UserControl
23 | {
24 | public About()
25 | {
26 | InitializeComponent();
27 | }
28 |
29 | private void GithubDownloadButton_Click(object sender, RoutedEventArgs e)
30 | {
31 | Process.Start(DataBrige.DownloadUrl);
32 | }
33 |
34 | private void LanzouDownloadButton_Click(object sender, RoutedEventArgs e)
35 | {
36 |
37 | MessageBoxResult result = MessageBox.Show("点击确定,将打开蓝奏云下载链接,提取密码为ab7k", "蓝奏云下载", MessageBoxButton.OKCancel, MessageBoxImage.Information);
38 | if (result == MessageBoxResult.OK)
39 | {
40 | Process.Start("https://wwt.lanzout.com/b00sfauuj");
41 | }
42 |
43 | }
44 |
45 |
46 | ///
47 | /// 版本对比
48 | ///
49 | private void VerCheck()
50 | {
51 | NowVer.Text = "版本号:V" + Convert.ToString(DataBrige.Ver) + "-Beta";
52 |
53 |
54 | if (Convert.ToDouble(DataBrige.LatestVersion) > Convert.ToDouble(DataBrige.Ver))
55 | {
56 | NewVerPlan.Visibility = Visibility.Visible;
57 | NewVer.Text = "最新版:V" + Convert.ToString(DataBrige.LatestVersion) + "-Beta";
58 | NewVer.Foreground = Brushes.DarkOrange;
59 |
60 |
61 | }
62 | else
63 | {
64 | NewVerPlan.Visibility = Visibility.Collapsed;
65 | }
66 |
67 | //见鬼的疑惑操作
68 | string updateInfo="";
69 |
70 | if (DataBrige.UpdateInfos != "0")
71 | {
72 | updateInfo = "V" + DataBrige.LatestVersion + "-Beta更新内容";
73 |
74 | }
75 |
76 | if (updateInfo != "V0-Beta更新内容" && updateInfo !="")
77 | {
78 | UpdateBlock.Text = updateInfo;
79 | UpdateInfo.Text = DataBrige.UpdateInfos;
80 | }
81 |
82 |
83 |
84 |
85 | }
86 |
87 |
88 | private void NowVer_MouseDown(object sender, MouseButtonEventArgs e)
89 | {
90 | if (DataBrige.DownloadUrl != "")
91 | {
92 | Process.Start(DataBrige.DownloadUrl);
93 | }
94 |
95 |
96 | }
97 |
98 |
99 |
100 |
101 | private void IpamNote_OnMouseDown(object sender, MouseButtonEventArgs e)
102 | {
103 | Process.Start("https://github.com/yaobus/IPAM-NOTE.git");
104 | }
105 |
106 | private void About_OnLoaded(object sender, RoutedEventArgs e)
107 | {
108 | VerCheck(); //版本检查
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/UserPages/CabinetManage.xaml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/UserPages/CabinetManage.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 IPAM_NOTE.UserPages
17 | {
18 | ///
19 | /// CabinetManage.xaml 的交互逻辑
20 | ///
21 | public partial class CabinetManage : UserControl
22 | {
23 | private bool isDragging = false;
24 | private Point lastPosition;
25 |
26 | private bool isDraggingCanvas = false;
27 | private bool isDraggingContent = false;
28 | private Point lastCanvasPosition;
29 | private Point lastContentPosition;
30 |
31 | public CabinetManage()
32 | {
33 | InitializeComponent();
34 |
35 |
36 | }
37 |
38 | private void Canvas_OnMouseWheel(object sender, MouseWheelEventArgs e)
39 | {
40 | // 获取当前鼠标滚轮滚动的增量
41 | int delta = e.Delta;
42 |
43 | // 定义缩放比例的增量,可以根据实际需求进行调整
44 | double scaleIncrement = 0.1;
45 |
46 | // 获取当前 Canvas 的缩放变换
47 | ScaleTransform scaleTransform = SubCanvas.RenderTransform as ScaleTransform;
48 | if (scaleTransform == null)
49 | {
50 | // 如果没有缩放变换,则创建一个新的缩放变换,并应用到 Canvas 上
51 | scaleTransform = new ScaleTransform(1.0, 1.0);
52 | SubCanvas.RenderTransform = scaleTransform;
53 | }
54 |
55 | // 计算新的缩放比例
56 | double newScale = delta > 0 ? scaleTransform.ScaleX + scaleIncrement : scaleTransform.ScaleX - scaleIncrement;
57 |
58 | // 设置缩放比例的上下限,可以根据实际需求进行调整
59 | double minScale = 1.0;
60 | double maxScale = 3.0;
61 | newScale = Math.Max(minScale, Math.Min(maxScale, newScale));
62 |
63 | // 应用新的缩放比例到 Canvas 上
64 | scaleTransform.ScaleX = newScale;
65 | scaleTransform.ScaleY = newScale;
66 | }
67 |
68 |
69 |
70 |
71 | private void SubCanvas_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
72 | {
73 | // 右键按下时开始拖动操作
74 | if (e.LeftButton == MouseButtonState.Pressed)
75 | {
76 | if (Keyboard.Modifiers == ModifierKeys.None)
77 | {
78 | // 只拖动内容
79 | isDraggingContent = true;
80 | lastContentPosition = e.GetPosition(SubCanvas);
81 | SubCanvas.CaptureMouse();
82 | }
83 | else
84 | {
85 | // 拖动整个画布
86 | isDraggingCanvas = true;
87 | lastCanvasPosition = e.GetPosition(SubCanvas);
88 | SubCanvas.CaptureMouse();
89 | }
90 | }
91 | }
92 |
93 | private void SubCanvas_OnMouseMove(object sender, MouseEventArgs e)
94 | {
95 | Point newPosition = e.GetPosition(SubCanvas);
96 | double deltaX = newPosition.X - lastCanvasPosition.X;
97 | double deltaY = newPosition.Y - lastCanvasPosition.Y;
98 |
99 | Canvas.SetLeft(SubCanvas, Canvas.GetLeft(SubCanvas) + deltaX);
100 | Canvas.SetTop(SubCanvas, Canvas.GetTop(SubCanvas) + deltaY);
101 |
102 | lastCanvasPosition = newPosition;
103 | }
104 | }
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/UserPages/DataPreset.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
31 |
38 |
39 |
40 |
41 |
44 |
49 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
61 |
66 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/UserPages/DataPreset.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 IPAM_NOTE.UserPages
17 | {
18 | ///
19 | /// DataPreset.xaml 的交互逻辑
20 | ///
21 | public partial class DataPreset : UserControl
22 | {
23 | public DataPreset()
24 | {
25 | InitializeComponent();
26 | }
27 |
28 | private void DataPreset_OnLoaded(object sender, RoutedEventArgs e)
29 | {
30 | //加载初始页面
31 | PresetPanel.Children.Clear();
32 | ModelPreset modelPreset = new ModelPreset();
33 | //networkManage.Style = (Style)FindResource("UserControlStyle");
34 | PresetPanel.Children.Add(modelPreset);
35 |
36 |
37 | }
38 |
39 | private void PresetTabControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
40 | {
41 | int index = PresetTabControl.SelectedIndex;
42 |
43 | if (index != -1)
44 | {
45 |
46 | PresetPanel.Children.Clear();
47 |
48 | switch (index)
49 | {
50 | case 0:
51 |
52 | ModelPreset modelPreset = new ModelPreset();
53 |
54 | //dataPreset.Style = (Style)FindResource("DataPresetStyle");
55 |
56 | PresetPanel.Children.Add(modelPreset);
57 |
58 | break;
59 |
60 | case 1:
61 |
62 | PeoplePreset peoplePreset = new PeoplePreset();
63 |
64 | //dataPreset.Style = (Style)FindResource("DataPresetStyle");
65 |
66 | PresetPanel.Children.Add(peoplePreset);
67 |
68 | break;
69 |
70 | }
71 | }
72 |
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/UserPages/DatabaseBackup.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
33 |
34 |
39 |
40 |
46 |
47 |
48 |
49 |
77 |
78 |
108 |
109 |
116 |
117 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
140 |
141 |
142 |
145 |
148 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/UserPages/DatabaseBackup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows;
9 | using System.Windows.Controls;
10 | using System.Windows.Data;
11 | using System.Windows.Documents;
12 | using System.Windows.Input;
13 | using System.Windows.Media;
14 | using System.Windows.Media.Imaging;
15 | using System.Windows.Navigation;
16 | using System.Windows.Shapes;
17 | using Path = System.IO.Path;
18 |
19 | namespace IPAM_NOTE.UserPages
20 | {
21 | ///
22 | /// DatabaseBackup.xaml 的交互逻辑
23 | ///
24 | public partial class DatabaseBackup : UserControl
25 | {
26 | public DatabaseBackup()
27 | {
28 | InitializeComponent();
29 | }
30 |
31 | List backupList = new List();
32 |
33 | private void BackupListView_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
34 | {
35 |
36 | Console.WriteLine(BackupListView.SelectedIndex);
37 |
38 | if (BackupListView.SelectedIndex != -1)
39 | {
40 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\Backup";
41 |
42 | string fileName = backupList[BackupListView.SelectedIndex].FileName;
43 |
44 | BakPath.Text = Path.Combine(dbFilePath, fileName);
45 |
46 | RestoreBackup.IsEnabled = true;
47 |
48 |
49 | }
50 | else
51 | {
52 | RestoreBackup.IsEnabled = false;
53 | }
54 |
55 |
56 |
57 | }
58 |
59 |
60 |
61 | ///
62 | /// 回滚备份
63 | ///
64 | ///
65 | ///
66 | private void RestoreBackup_OnClick(object sender, RoutedEventArgs e)
67 | {
68 |
69 | string destinationFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\Address_database.db";
70 |
71 | string backupFilePath = BakPath.Text;
72 |
73 | RestoreDataBasseBackup(backupFilePath, destinationFilePath);
74 |
75 |
76 | }
77 |
78 | private void RestoreDataBasseBackup(string backupFilePath, string destinationFilePath)
79 | {
80 | try
81 | {
82 | File.Copy(backupFilePath, destinationFilePath, true); // 复制备份文件到目标位置并覆盖源文件
83 | MessageBox.Show("数据库恢复完成,程序即将重启", "注意", MessageBoxButton.OK, MessageBoxImage.Information);
84 |
85 | RestartApplication();
86 | }
87 | catch (Exception ex)
88 | {
89 | Console.WriteLine("文件恢复失败:" + ex.Message);
90 | }
91 | }
92 |
93 | private void RestartApplication()
94 | {
95 | // 获取当前应用程序的可执行文件路径
96 | string appPath = Process.GetCurrentProcess().MainModule.FileName;
97 |
98 | // 启动另一个实例你的软件
99 | Process.Start(appPath);
100 |
101 | // 关闭当前实例
102 | Environment.Exit(0);
103 | }
104 |
105 |
106 | private void OpenFolder(string folderPath)
107 | {
108 | try
109 | {
110 | Process.Start(folderPath);
111 | }
112 | catch (Exception ex)
113 | {
114 | Console.WriteLine("无法打开文件夹:" + ex.Message);
115 | }
116 | }
117 |
118 | private void BackupFile_OnClick(object sender, RoutedEventArgs e)
119 | {
120 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\Backup";
121 | OpenFolder(dbFilePath);
122 | }
123 |
124 | private void DatabaseBackup_OnLoaded(object sender, RoutedEventArgs e)
125 | {
126 | backupList.Clear();
127 |
128 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
129 |
130 | string backupDirectoryPath = System.IO.Path.Combine(dbFilePath, "Backup");
131 |
132 |
133 | string[] backupFiles = Directory.GetFiles(backupDirectoryPath, "*.bak")
134 | .OrderByDescending(f => File.GetLastWriteTime(f))
135 | .Take(20)
136 | .ToArray();
137 |
138 |
139 | for (int i = 0; i < backupFiles.Length; i++)
140 | {
141 | string fileName = System.IO.Path.GetFileName(backupFiles[i]);
142 | DateTime backupTime = File.GetLastWriteTime(backupFiles[i]);
143 | backupList.Add(new ViewMode.BackupInfo
144 | {
145 | Index = i + 1,
146 | FileName = fileName,
147 | BackupTime = backupTime.ToString("yyyy年M月d日HH:mm")
148 | });
149 | }
150 |
151 |
152 | BackupListView.ItemsSource = backupList;
153 | }
154 |
155 |
156 |
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/UserPages/DonationPage.xaml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/UserPages/DonationPage.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 IPAM_NOTE.UserPages
17 | {
18 | ///
19 | /// DonationPage.xaml 的交互逻辑
20 | ///
21 | public partial class DonationPage : UserControl
22 | {
23 | public DonationPage()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/UserPages/HelpPage.xaml:
--------------------------------------------------------------------------------
1 |
18 |
21 |
22 |
26 |
27 |
28 |
29 |
34 |
39 |
44 |
45 |
46 |
47 |
50 |
51 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
69 |
74 |
79 |
80 |
81 |
82 |
83 |
84 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
102 |
107 |
112 |
113 |
114 |
115 |
116 |
117 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
130 |
131 |
132 |
137 |
142 |
147 |
148 |
149 |
150 |
151 |
152 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
165 |
166 |
167 |
172 |
177 |
182 |
183 |
184 |
185 |
186 |
187 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
200 |
201 |
202 |
207 |
212 |
217 |
218 |
219 |
220 |
221 |
222 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
239 |
244 |
249 |
250 |
251 |
252 |
253 |
254 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
271 |
276 |
281 |
282 |
283 |
284 |
285 |
286 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
--------------------------------------------------------------------------------
/UserPages/HelpPage.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 IPAM_NOTE.UserPages
17 | {
18 | ///
19 | /// HelpPage.xaml 的交互逻辑
20 | ///
21 | public partial class HelpPage : UserControl
22 | {
23 | public HelpPage()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/UserPages/HumanGreeting.xaml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/UserPages/HumanGreeting.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 IPAM_NOTE.UserPages
17 | {
18 | ///
19 | /// HumanGreeting.xaml 的交互逻辑
20 | ///
21 | public partial class HumanGreeting : UserControl
22 | {
23 | public HumanGreeting()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/UserPages/IndexPage.xaml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
37 |
38 |
39 |
40 |
41 |
42 |
56 |
57 |
67 |
68 |
78 |
79 |
80 |
81 |
82 |
83 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
104 |
105 |
106 |
107 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
130 |
131 |
141 |
142 |
150 |
151 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/UserPages/ModelPreset.xaml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
35 |
36 |
41 |
42 |
48 |
49 |
77 |
78 |
108 |
109 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
144 |
145 |
146 |
150 |
151 |
154 |
158 |
162 |
165 |
168 |
171 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
--------------------------------------------------------------------------------
/UserPages/ModelPreset.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.SQLite;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Navigation;
15 | using System.Windows.Shapes;
16 | using IPAM_NOTE.DatabaseOperation;
17 | using IPAM_NOTE.PresetWindow;
18 | using static IPAM_NOTE.ViewMode;
19 |
20 | namespace IPAM_NOTE.UserPages
21 | {
22 | ///
23 | /// ModelPreset.xaml 的交互逻辑
24 | ///
25 | public partial class ModelPreset : UserControl
26 | {
27 | public ModelPreset()
28 | {
29 | InitializeComponent();
30 | }
31 | private DbClass dbClass;
32 | private void ModelPreset_OnLoaded(object sender, RoutedEventArgs e)
33 | {
34 | ModelPresetList.ItemsSource = DataBrige.ModelPresetInfos;
35 |
36 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
37 |
38 | string dbName = "Address_database.db";
39 |
40 |
41 | dbFilePath = dbFilePath + dbName;
42 |
43 |
44 |
45 | dbClass = new DbClass(dbFilePath);
46 | dbClass.OpenConnection();
47 |
48 | dbClass.CreateModelPresetIfNotExists("ModelPreset"); //检查表单是否创建
49 |
50 |
51 | LoadModelPreset(dbClass.connection);
52 |
53 | }
54 |
55 | private void AddButton_OnClick(object sender, RoutedEventArgs e)
56 | {
57 |
58 |
59 | AddPreset addPreset = new AddPreset();
60 |
61 | if (addPreset.ShowDialog() == true)
62 | {
63 |
64 | // 当子窗口关闭后执行这里的代码
65 | LoadModelPreset(dbClass.connection);
66 |
67 | }
68 |
69 | }
70 |
71 | ///
72 | /// 加载设备信息列表
73 | ///
74 | ///
75 | public void LoadModelPreset(SQLiteConnection connection)
76 | {
77 | DataBrige.ModelPresetInfos.Clear();
78 | ModelPresetList.ItemsSource = null;
79 | try
80 | {
81 | string query = "SELECT * FROM ModelPreSet";
82 |
83 | SQLiteCommand command = new SQLiteCommand(query, connection);
84 | SQLiteDataReader reader = command.ExecuteReader();
85 |
86 | int i = 0;
87 |
88 |
89 |
90 | while (reader.Read())
91 | {
92 | i++;
93 | // 读取数据行中的每一列
94 |
95 | int id = i;
96 | string modelType = reader["ModelType"].ToString();
97 | string brand = reader["Brand"].ToString();
98 | string model = reader["Model"].ToString();
99 | int ethernet = Convert.ToInt32(reader["Ethernet"].ToString());
100 | int fiber = Convert.ToInt32(reader["Fiber"].ToString());
101 | int disk = Convert.ToInt32(reader["Disk"].ToString());
102 | int Manage = Convert.ToInt32(reader["Manage"].ToString());
103 | DataBrige.ModelPresetInfos.Add(new ModelPresetInfo(id, modelType, brand, model, ethernet, fiber, disk, Manage));
104 |
105 |
106 | }
107 |
108 | ModelPresetList.ItemsSource = DataBrige.ModelPresetInfos;
109 |
110 | reader.Close();
111 | }
112 | catch (Exception ex)
113 | {
114 | MessageBox.Show($"Error: {ex.Message}");
115 | }
116 | }
117 |
118 |
119 |
120 | private void ModelPresetList_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
121 | {
122 | if (ModelPresetList.SelectedIndex != -1)
123 | {
124 | MinusButton.IsEnabled = true;
125 | }
126 | }
127 |
128 |
129 | private void MinusButton_OnClick(object sender, RoutedEventArgs e)
130 | {
131 | string type = DataBrige.ModelPresetInfos[ModelPresetList.SelectedIndex].ModelType;
132 | string brand= DataBrige.ModelPresetInfos[ModelPresetList.SelectedIndex].Brand;
133 | string model = DataBrige.ModelPresetInfos[ModelPresetList.SelectedIndex].Model;
134 |
135 | string sql = $"DELETE FROM \"ModelPreset\" WHERE ModelType = '{type}' AND Brand = '{brand}' AND Model = '{model}'";
136 |
137 | dbClass.ExecuteQuery(sql);
138 | LoadModelPreset(dbClass.connection);
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/UserPages/PeoplePreset.xaml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
35 |
36 |
41 |
42 |
48 |
49 |
77 |
78 |
108 |
109 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
144 |
145 |
146 |
150 |
151 |
154 |
158 |
162 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
--------------------------------------------------------------------------------
/UserPages/PeoplePreset.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data.SQLite;
3 | using System.Windows;
4 | using System.Windows.Controls;
5 | using IPAM_NOTE.DatabaseOperation;
6 | using IPAM_NOTE.PresetWindow;
7 | using static IPAM_NOTE.ViewMode;
8 |
9 | namespace IPAM_NOTE.UserPages
10 | {
11 | ///
12 | /// ModelPreset.xaml 的交互逻辑
13 | ///
14 | public partial class PeoplePreset : UserControl
15 | {
16 | public PeoplePreset()
17 | {
18 | InitializeComponent();
19 | }
20 | private DbClass dbClass;
21 | private void ModelPreset_OnLoaded(object sender, RoutedEventArgs e)
22 | {
23 | PeoplePresetList.ItemsSource = DataBrige.ModelPresetInfos;
24 |
25 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
26 |
27 | string dbName = "Address_database.db";
28 |
29 |
30 | dbFilePath = dbFilePath + dbName;
31 |
32 |
33 |
34 | dbClass = new DbClass(dbFilePath);
35 | dbClass.OpenConnection();
36 |
37 | dbClass.CreateModelPresetIfNotExists("ModelPreset"); //检查表单是否创建
38 |
39 |
40 | LoadModelPreset(dbClass.connection);
41 |
42 | }
43 |
44 | private void AddButton_OnClick(object sender, RoutedEventArgs e)
45 | {
46 |
47 |
48 | AddPreset addPreset = new AddPreset();
49 |
50 | if (addPreset.ShowDialog() == true)
51 | {
52 |
53 | // 当子窗口关闭后执行这里的代码
54 | LoadModelPreset(dbClass.connection);
55 |
56 | }
57 |
58 | }
59 |
60 | ///
61 | /// 加载设备信息列表
62 | ///
63 | ///
64 | public void LoadModelPreset(SQLiteConnection connection)
65 | {
66 | DataBrige.ModelPresetInfos.Clear();
67 | PeoplePresetList.ItemsSource = null;
68 | try
69 | {
70 | string query = "SELECT * FROM ModelPreSet";
71 |
72 | SQLiteCommand command = new SQLiteCommand(query, connection);
73 | SQLiteDataReader reader = command.ExecuteReader();
74 |
75 | int i = 0;
76 |
77 |
78 |
79 | while (reader.Read())
80 | {
81 | i++;
82 | // 读取数据行中的每一列
83 |
84 | int id = i;
85 | string modelType = reader["ModelType"].ToString();
86 | string brand = reader["Brand"].ToString();
87 | string model = reader["Model"].ToString();
88 | int ethernet = Convert.ToInt32(reader["Ethernet"].ToString());
89 | int fiber = Convert.ToInt32(reader["Fiber"].ToString());
90 | int disk = Convert.ToInt32(reader["Disk"].ToString());
91 | int Manage = Convert.ToInt32(reader["Manage"].ToString());
92 | DataBrige.ModelPresetInfos.Add(new ModelPresetInfo(id, modelType, brand, model, ethernet, fiber, disk, Manage));
93 |
94 |
95 | }
96 |
97 | PeoplePresetList.ItemsSource = DataBrige.ModelPresetInfos;
98 |
99 | reader.Close();
100 | }
101 | catch (Exception ex)
102 | {
103 | MessageBox.Show($"Error: {ex.Message}");
104 | }
105 | }
106 |
107 |
108 |
109 | private void PeoplePresetList_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
110 | {
111 | if (PeoplePresetList.SelectedIndex != -1)
112 | {
113 | MinusButton.IsEnabled = true;
114 | }
115 | }
116 |
117 |
118 | private void MinusButton_OnClick(object sender, RoutedEventArgs e)
119 | {
120 | string type = DataBrige.ModelPresetInfos[PeoplePresetList.SelectedIndex].ModelType;
121 | string brand= DataBrige.ModelPresetInfos[PeoplePresetList.SelectedIndex].Brand;
122 | string model = DataBrige.ModelPresetInfos[PeoplePresetList.SelectedIndex].Model;
123 |
124 | string sql = $"DELETE FROM \"ModelPreset\" WHERE ModelType = '{type}' AND Brand = '{brand}' AND Model = '{model}'";
125 |
126 | dbClass.ExecuteQuery(sql);
127 | LoadModelPreset(dbClass.connection);
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/UserWindows/AddIndexWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.SQLite;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Shapes;
15 | using IPAM_NOTE.DatabaseOperation;
16 |
17 | namespace IPAM_NOTE.UserWindows
18 | {
19 | ///
20 | /// AddIndexWindow.xaml 的交互逻辑
21 | ///
22 | public partial class AddIndexWindow : Window
23 | {
24 | public AddIndexWindow()
25 | {
26 | InitializeComponent();
27 | }
28 |
29 | private DbClass dbClass;
30 |
31 | private void AddIndexWindow_OnLoaded(object sender, RoutedEventArgs e)
32 | {
33 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
34 | string dbName = "Address_database.db";
35 |
36 | dbFilePath = dbFilePath + dbName;
37 |
38 | dbClass = new DbClass(dbFilePath);
39 |
40 | dbClass.OpenConnection();
41 |
42 |
43 |
44 |
45 | //判断是编辑还是新建标签
46 | if (DataBrige.EditMode == 1) //编辑模式
47 | {
48 | DeviceBlock.Text = DataBrige.SelectDeviceInfo.Name + " " + DataBrige.SelectDeviceInfo.Number;
49 | ModelTextBlock.Text = "型号:" + DataBrige.SelectDeviceInfo.Model;
50 | DescriptionBlock.Text = "备注:" + DataBrige.SelectDeviceInfo.Description;
51 |
52 | TypeBlock.Text = "当前选中导航标签:" + DataBrige.SelectIndexTag.ToString();
53 |
54 | string sql =
55 | $"SELECT * FROM {DataBrige.SelectDeviceInfo.TableName} WHERE PortType='I' AND PortNumber ={DataBrige.SelectIndexTag}";
56 |
57 | SQLiteCommand command = new SQLiteCommand(sql, dbClass.connection);
58 | SQLiteDataReader reader = command.ExecuteReader();
59 |
60 | ViewMode.DevicePortInfo info = null;
61 |
62 | while (reader.Read())
63 | {
64 | string portType = reader["PortType"].ToString();
65 | string portNumber = reader["PortNumber"].ToString();
66 | int portStatus = Convert.ToInt32(reader["PortStatus"]);
67 | string portTag1 = reader["PortTag1"].ToString();
68 | string portTag2 = reader["PortTag2"].ToString();
69 | string portTag3 = reader["PortTag3"].ToString();
70 | string description = reader["Description"].ToString();
71 |
72 |
73 | NameBox.Text = portTag1;
74 | UrlBox.Text = portTag2;
75 | DescriptionBox.Text = description;
76 |
77 | if (portStatus == 0)
78 | {
79 | EnableBox.IsChecked = false;
80 |
81 | }
82 | else
83 | {
84 | EnableBox.IsChecked = true;
85 | }
86 |
87 |
88 | }
89 | }
90 | else
91 | {
92 |
93 |
94 | int num = CalculateIndexId(DataBrige.SelectDeviceInfo.TableName);
95 |
96 | TypeBlock.Text = "当前新建快速访问标签第" + (num) + "个";
97 | }
98 |
99 |
100 | }
101 |
102 |
103 | ///
104 | /// 保存导航标签配置
105 | ///
106 | ///
107 | ///
108 | private void SaveButton_OnClick(object sender, RoutedEventArgs e)
109 | {
110 |
111 | int enable;
112 |
113 | if (EnableBox.IsChecked == true)
114 | {
115 | enable = 1;
116 | }
117 | else
118 | {
119 | enable = 0;
120 | }
121 |
122 | string tableName = DataBrige.SelectDeviceInfo.TableName;
123 |
124 |
125 | if (NameBox.Text != "" && UrlBox.Text != "")
126 | {
127 | string sql;
128 |
129 | if (DataBrige.EditMode == 0)//新建
130 | {
131 | //计算已有导航标签数量
132 |
133 | string sqlTemp = string.Format($"SELECT COUNT(*) FROM {tableName} WHERE `PortType` = 'I'");
134 |
135 |
136 | int num = CalculateIndexId(tableName);
137 |
138 | Console.WriteLine("num:"+num);
139 |
140 | sql = $"INSERT INTO \"{tableName}\" (\"PortType\", \"PortNumber\", \"PortStatus\", \"PortTag1\", \"PortTag2\", \"Description\") VALUES ('I', '{num}',{enable}, '{NameBox.Text}', '{UrlBox.Text}', '{DescriptionBox.Text}')";
141 |
142 | Console.WriteLine(sql);
143 | }
144 | else
145 | {
146 |
147 | sql = $"UPDATE {tableName} SET \"PortStatus\" = '{enable}', \"PortTag1\" = '{NameBox.Text}' , \"PortTag2\" = '{UrlBox.Text}' , \"PortTag3\" = '', \"Description\" = '{DescriptionBox.Text}' WHERE (PortType = 'I' AND PortNumber = '{DataBrige.SelectIndexTag}')";
148 |
149 | }
150 |
151 |
152 | dbClass.ExecuteQuery(sql); //写入快速访问标签信息
153 |
154 | //DataBrige.DevicePortInfos.Add(new ViewMode.DevicePortInfo("I",(num+1).ToString(),enable,NameBox.Text,UrlBox.Text,"",DescriptionBox.Text));
155 |
156 |
157 | this.DialogResult = true;
158 | this.Close();
159 | }
160 | else
161 | {
162 | MessageBox.Show("请完整填写标签信息", "必要信息不完整", MessageBoxButton.OK, MessageBoxImage.Warning);
163 | }
164 |
165 |
166 | }
167 |
168 |
169 | ///
170 | ///
171 | ///
172 | private int CalculateIndexId(string tableName)
173 | {
174 | //计算已有导航标签数量
175 |
176 | string sqlTemp = string.Format($"SELECT PortNumber FROM {tableName} WHERE PortType ='I'");
177 | SQLiteCommand command = new SQLiteCommand(sqlTemp,dbClass.connection);
178 | SQLiteDataReader reader = command.ExecuteReader();
179 |
180 | List idList = new List();
181 |
182 | while (reader.Read())
183 | {
184 | idList.Add(Convert.ToInt32(reader["PortNumber"]));
185 | }
186 |
187 |
188 | return FindMissingNumber(idList);
189 | }
190 |
191 |
192 | ///
193 | /// 寻找遗失的数值
194 | ///
195 | ///
196 | ///
197 | ///
198 | public static int FindMissingNumber(List numbers)
199 | {
200 | if (numbers == null || numbers.Count == 0)
201 | {
202 | Console.WriteLine("List cannot be null or empty");
203 |
204 | }
205 | else
206 | {
207 | int max = numbers.Max();
208 |
209 | for (int i = 1; i <= max; i++)
210 | {
211 | if (!numbers.Contains(i))
212 | {
213 | return i;
214 |
215 | }
216 | }
217 |
218 | }
219 |
220 |
221 | return numbers.Count + 1;
222 | }
223 |
224 |
225 | ///
226 | /// 自动添加http://
227 | ///
228 | ///
229 | ///
230 | private void UrlBox_OnMouseLeave(object sender, MouseEventArgs e)
231 | {
232 | UrlBox.Text = AddHttpIfNeeded(UrlBox.Text);
233 | }
234 |
235 |
236 | static string AddHttpIfNeeded(string input)
237 | {
238 | if (!input.Contains("https://") && !input.Contains("http://"))
239 | {
240 | // 如果字符串中不存在 "https://" 或 "http://", 添加 "https://"
241 | input = "http://" + input;
242 | }
243 | return input;
244 | }
245 |
246 |
247 | ///
248 | /// 删除标签
249 | ///
250 | ///
251 | ///
252 | private void ReleaseButton_OnClick(object sender, RoutedEventArgs e)
253 | {
254 | string sql = $"DELETE FROM {DataBrige.SelectDeviceTableName} WHERE (PortType = 'I' AND PortNumber = {DataBrige.SelectIndexTag})";
255 | dbClass.ExecuteQuery(sql); //写入快速访问标签信息
256 | this.DialogResult=true;
257 | this.Close();
258 | }
259 | }
260 | }
261 |
--------------------------------------------------------------------------------
/UserWindows/DeviceImportWindow.xaml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
35 |
36 |
43 |
44 |
50 |
51 |
52 |
61 |
62 |
63 |
64 |
65 |
66 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
105 |
106 |
112 |
113 |
114 |
115 |
116 |
127 |
128 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
165 |
166 |
172 |
173 |
174 |
175 |
181 |
182 |
183 |
184 |
185 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
--------------------------------------------------------------------------------
/UserWindows/DeviceImportWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using CsvHelper;
2 | using IPAM_NOTE.DatabaseOperation;
3 | using Microsoft.Win32;
4 | using OfficeOpenXml;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Data.SQLite;
8 | using System.Globalization;
9 | using System.IO;
10 | using System.Linq;
11 | using System.Net.NetworkInformation;
12 | using System.Text;
13 | using System.Threading.Tasks;
14 | using System.Windows;
15 | using System.Windows.Controls;
16 | using System.Windows.Data;
17 | using System.Windows.Documents;
18 | using System.Windows.Input;
19 | using System.Windows.Media;
20 | using System.Windows.Media.Imaging;
21 | using System.Windows.Shapes;
22 | using static IPAM_NOTE.ImportWindow;
23 | using static IPAM_NOTE.ViewMode;
24 |
25 | namespace IPAM_NOTE.UserWindows
26 | {
27 | ///
28 | /// DeviceImportWindow.xaml 的交互逻辑
29 | ///
30 | public partial class DeviceImportWindow : Window
31 | {
32 | public DeviceImportWindow()
33 | {
34 | InitializeComponent();
35 | }
36 |
37 |
38 |
39 |
40 | private void DeviceImportWindow_OnLoaded(object sender, RoutedEventArgs e)
41 | {
42 | DevicesComboBox.ItemsSource = DataBrige.DevicesList;
43 | }
44 |
45 | ///
46 | /// 导出模板
47 | ///
48 | ///
49 | ///
50 | private void ExportButton_OnClick(object sender, RoutedEventArgs e)
51 | {
52 | if (DevicesComboBox.SelectedIndex != -1)
53 | {
54 | ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
55 |
56 | string tableName = DataBrige.DeviceInfos[DevicesComboBox.SelectedIndex].TableName;
57 |
58 | LoadDeviceConfig(tableName);
59 |
60 |
61 |
62 | // 创建 SaveFileDialog 实例
63 | SaveFileDialog saveFileDialog = new SaveFileDialog();
64 | saveFileDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
65 | saveFileDialog.FilterIndex = 1;
66 | saveFileDialog.RestoreDirectory = true;
67 |
68 |
69 | saveFileDialog.FileName = tableName + ".xlsx";
70 |
71 |
72 |
73 | // 显示 SaveFileDialog
74 | bool? result = saveFileDialog.ShowDialog();
75 |
76 | if (result == true)
77 | {
78 | // 获取用户选择的文件路径
79 | string filePath = saveFileDialog.FileName;
80 | ExportToExcel(DataBrige.DevicePortInfos, filePath);
81 | MessageBox.Show("设备内容导出完毕", "导出", MessageBoxButton.OK, MessageBoxImage.Information);
82 | }
83 |
84 |
85 |
86 | }
87 | else
88 | {
89 | MessageBox.Show("请先选择要导出的设备", "你是否遗忘了什么步骤?", MessageBoxButton.OK, MessageBoxImage.Information);
90 | }
91 |
92 |
93 |
94 |
95 | }
96 |
97 |
98 |
99 | public void ExportToExcel(List dataList, string filePath)
100 | {
101 |
102 |
103 |
104 | using (var package = new ExcelPackage())
105 | {
106 | var sheet = package.Workbook.Worksheets.Add(DataBrige.DeviceInfos[DevicesComboBox.SelectedIndex].TableName);
107 |
108 |
109 | // 写入标题行
110 | sheet.Cells[1, 1].Value = "PortType";
111 | sheet.Cells[1, 2].Value = "PortNumber";
112 | sheet.Cells[1, 3].Value = "PortStatus";
113 | sheet.Cells[1, 4].Value = "PortTag1";
114 | sheet.Cells[1, 5].Value = "PortTag2";
115 | sheet.Cells[1, 6].Value = "PortTag3";
116 | sheet.Cells[1, 7].Value = "Description";
117 |
118 | // 写入数据
119 | int rowIndex = 2;
120 | foreach (var info in dataList)
121 | {
122 | sheet.Cells[rowIndex, 1].Value = info.PortType;
123 | sheet.Cells[rowIndex, 2].Value = info.PortNumber;
124 | sheet.Cells[rowIndex, 3].Value = info.PortStatus;
125 | sheet.Cells[rowIndex, 4].Value = info.PortTag1;
126 | sheet.Cells[rowIndex, 5].Value = info.PortTag2;
127 | sheet.Cells[rowIndex, 6].Value = info.PortTag3; ;
128 | sheet.Cells[rowIndex, 7].Value = info.Description; ;
129 | rowIndex++;
130 | }
131 |
132 |
133 | // 保存Excel文件
134 | FileInfo excelFile = new FileInfo(filePath);
135 |
136 |
137 |
138 | package.SaveAs(excelFile);
139 | }
140 |
141 |
142 |
143 |
144 |
145 | }
146 |
147 | ///
148 | /// 加载IP地址表配置
149 | ///
150 | private void LoadDeviceConfig(string tableName)
151 | {
152 |
153 | string sql = string.Format("SELECT * FROM {0} ORDER BY PortType ASC", tableName);
154 |
155 |
156 |
157 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
158 | string dbName = "Address_database.db";
159 |
160 | dbFilePath = dbFilePath + dbName;
161 |
162 | // 打开 SQLite 数据库连接
163 | string connectionString = string.Format("Data Source={0};Version=3;", dbFilePath);
164 |
165 | using (SQLiteConnection connection = new SQLiteConnection(connectionString))
166 | {
167 | connection.Open();
168 |
169 |
170 | SQLiteCommand command = new SQLiteCommand(sql, connection);
171 |
172 | SQLiteDataReader reader = command.ExecuteReader();
173 |
174 | DataBrige.DevicePortInfos.Clear();
175 |
176 |
177 | while (reader.Read())
178 | {
179 | string portType = reader["PortType"].ToString();
180 | string portNumber = reader["PortNumber"].ToString();
181 | int portStatus = Convert.ToInt32(reader["PortStatus"]);
182 | string portTag1 = reader["PortTag1"].ToString();
183 | string portTag2 = reader["PortTag2"].ToString();
184 | string portTag3 = reader["PortTag3"].ToString();
185 | string description = reader["Description"].ToString();
186 |
187 |
188 |
189 | DevicePortInfo portInfo = new DevicePortInfo(portType, portNumber, portStatus, portTag1, portTag2,
190 | portTag3, description);
191 |
192 | DataBrige.DevicePortInfos.Add(portInfo);
193 | }
194 |
195 |
196 |
197 | reader.Dispose();
198 |
199 |
200 |
201 | }
202 | }
203 |
204 |
205 | ///
206 | /// 浏览CSV文件
207 | ///
208 | ///
209 | ///
210 | private void BrowseButton_OnClick(object sender, RoutedEventArgs e)
211 | {
212 | // 创建 OpenFileDialog 实例
213 | OpenFileDialog openFileDialog = new OpenFileDialog();
214 |
215 | // 设置文件类型筛选,仅允许选择 CSV 文件
216 | openFileDialog.Filter = "CSV files (*.csv)|*.csv";
217 |
218 | // 显示对话框并获取用户选择的结果
219 | bool? result = openFileDialog.ShowDialog();
220 |
221 | // 如果用户选择了文件,则将文件路径加载到 TextBox 中
222 | if (result == true)
223 | {
224 | string selectedFilePath = openFileDialog.FileName;
225 | SourceData.Text = selectedFilePath;
226 | }
227 | }
228 |
229 | ///
230 | /// 导入数据
231 | ///
232 | ///
233 | ///
234 | private void ImportButton_OnClick(object sender, RoutedEventArgs e)
235 | {
236 |
237 | MessageBoxResult result = MessageBox.Show("注意!导入数据将覆盖数据库内原有数据,是否继续?\r\r\r如果导入之后出现异常可前往数据恢复页面\r进入之后选择'备份还原'即可看到恢复选项", "危险操作", MessageBoxButton.YesNo,
238 | MessageBoxImage.Warning);
239 |
240 | if (result == MessageBoxResult.Yes)
241 | {
242 | if (DevicesComboBox.SelectedIndex != -1 && File.Exists(SourceData.Text))
243 | {
244 | string tableName = DataBrige.DeviceInfos[DevicesComboBox.SelectedIndex].TableName;
245 |
246 | ImportDataFromCsv(SourceData.Text, tableName);
247 | }
248 | else
249 | {
250 | MessageBox.Show("未选择被导入的网段或未找到被导入的CSV文件", "注意", MessageBoxButton.OK, MessageBoxImage.Error);
251 | }
252 | }
253 | }
254 |
255 | private void ImportDataFromCsv(string csvFilePath, string tableName)
256 | {
257 | ProgressBar.IsIndeterminate = true;
258 | string dbFilePath = AppDomain.CurrentDomain.BaseDirectory + @"db\";
259 | string dbName = "Address_database.db";
260 |
261 | dbFilePath = dbFilePath + dbName;
262 |
263 | // 打开 SQLite 数据库连接
264 | string connectionString = string.Format("Data Source={0};Version=3;", dbFilePath);
265 |
266 | try
267 | {
268 | // 检查CSV文件编码并转换为UTF-8
269 | string utf8CsvFilePath = CheckAndConvertCsvToUtf8(csvFilePath);
270 |
271 |
272 | using (SQLiteConnection connection = new SQLiteConnection(connectionString))
273 | {
274 | connection.Open();
275 |
276 | // 创建一个 SQLiteCommand 对象来执行 SQL 查询和命令
277 | using (SQLiteCommand command = connection.CreateCommand())
278 | {
279 |
280 | // 将 CSV 文件中的数据读取到一个列表中
281 | List records;
282 |
283 | using (var reader = new StreamReader(utf8CsvFilePath))
284 | using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
285 | {
286 | records = csv.GetRecords().ToList();
287 |
288 |
289 |
290 | // 遍历 CSV 文件中的每一行数据
291 | foreach (var record in records)
292 | {
293 | // 从 CSV 记录中获取需要插入或更新到数据库的字段值
294 | string type = record.PortType;
295 |
296 | string number= record.PortNumber;
297 |
298 |
299 |
300 | // 检查数据库中是否已存在相同的 type和端口
301 |
302 | command.CommandText = string.Format($"SELECT COUNT(*) FROM {tableName} WHERE (PortType = '{type}' AND PortNumber = '{number}') ");
303 |
304 | int count = Convert.ToInt32(command.ExecuteScalar());
305 |
306 |
307 |
308 | string portStatus = record.PortStatus;
309 | string portTag1 = record.PortTag1;
310 | string portTag2 = record.PortTag2;
311 | string portTag3 = record.PortTag3;
312 | string description = record.Description;
313 |
314 |
315 | if (count > 0)
316 | {
317 | // 数据库中已存在相同的 端口号,执行更新操作
318 | command.CommandText =
319 | string.Format(
320 | $"UPDATE {tableName} SET PortStatus = {portStatus}, PortTag1 = '{portTag1}',PortTag2 = '{portTag2}', PortTag3 = '{portTag3}', Description = '{description}' WHERE (PortType ='{type}' AND PortNumber='{number}')");
321 |
322 |
323 | }
324 | else
325 | {
326 | // 数据库中不存在相同的 IpAddress,执行插入操作
327 | command.CommandText =
328 | string.Format(
329 | $"INSERT INTO {tableName} (PortType, PortNumber, PortTag1, PortTag2,PortTag3,Description) VALUES ({type}, {number}, {portTag1}, {portTag2}, {portTag3}, {description})");
330 | }
331 |
332 |
333 | Console.WriteLine(command.CommandText);
334 |
335 | command.ExecuteNonQuery();
336 | }
337 |
338 | ProgressBar.IsIndeterminate = false;
339 | }
340 |
341 | }
342 |
343 | MessageBox.Show("数据导入完毕,请检查数据是否正常。", "导入完成", MessageBoxButton.OK,
344 | MessageBoxImage.Information);
345 | connection.Close();
346 | this.Close();
347 | }
348 | }
349 | catch (Exception ex)
350 | {
351 | MessageBox.Show($"导入CSV文件时出错:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
352 | }
353 | }
354 |
355 | private string CheckAndConvertCsvToUtf8(string csvFilePath)
356 | {
357 | // 检查文件编码
358 | Encoding encoding = GetCsvFileEncoding(csvFilePath);
359 |
360 | // 如果不是UTF-8,则转换为UTF-8并返回新的文件路径
361 | if (encoding != Encoding.UTF8)
362 | {
363 | string utf8CsvFilePath = System.IO.Path.GetTempFileName();
364 | ConvertCsvToUtf8(csvFilePath, utf8CsvFilePath);
365 | return utf8CsvFilePath;
366 | }
367 |
368 | // 文件已经是UTF-8编码,直接返回原始文件路径
369 | return csvFilePath;
370 | }
371 |
372 | ///
373 | /// 检测CSV文件编码
374 | ///
375 | ///
376 | ///
377 | private Encoding GetCsvFileEncoding(string filePath)
378 | {
379 | using (var reader = new PinnedStreamReader(filePath))
380 | {
381 | return reader.CurrentEncoding;
382 | }
383 | }
384 |
385 | ///
386 | /// 转换CSV为UTF-8编码
387 | ///
388 | ///
389 | ///
390 | private void ConvertCsvToUtf8(string sourceFilePath, string targetFilePath)
391 | {
392 | string csvContent = File.ReadAllText(sourceFilePath, Encoding.Default);
393 | File.WriteAllText(targetFilePath, csvContent, Encoding.UTF8);
394 | }
395 |
396 |
397 | }
398 | }
399 |
--------------------------------------------------------------------------------
/UserWindows/SetPasswordWindow.xaml:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
39 |
40 |
48 |
54 |
58 |
59 |
67 |
68 |
77 |
80 |
85 |
86 |
87 |
95 |
96 |
105 |
106 |
109 |
114 |
115 |
116 |
117 |
118 |
126 |
127 |
136 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/UserWindows/SetPasswordWindow.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.Shapes;
14 |
15 | namespace IPAM_NOTE.UserWindows
16 | {
17 | ///
18 | /// SetPasswordWindow.xaml 的交互逻辑
19 | ///
20 | public partial class SetPasswordWindow : Window
21 | {
22 | public SetPasswordWindow()
23 | {
24 | InitializeComponent();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/UserWindows/TESTWindow.xaml:
--------------------------------------------------------------------------------
1 |
21 |
22 |
25 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/UserWindows/TESTWindow.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.Shapes;
14 |
15 | namespace IPAM_NOTE.UserWindows
16 | {
17 | ///
18 | /// TESTWindow.xaml 的交互逻辑
19 | ///
20 | public partial class TESTWindow : Window
21 | {
22 | public TESTWindow()
23 | {
24 | InitializeComponent();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/UserWindows/VerifyPasswordWindow.xaml:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
40 |
41 |
49 |
55 |
56 |
60 |
61 |
69 |
70 |
79 |
80 |
83 |
88 |
89 |
90 |
91 |
92 |
100 |
101 |
110 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/UserWindows/VerifyPasswordWindow.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.Shapes;
14 |
15 | namespace IPAM_NOTE.UserWindows
16 | {
17 | ///
18 | /// VerifyPasswordWindow.xaml 的交互逻辑
19 | ///
20 | public partial class VerifyPasswordWindow : Window
21 | {
22 | public VerifyPasswordWindow()
23 | {
24 | InitializeComponent();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/VersionCheck.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace IPAM_NOTE
10 | {
11 | internal class VersionCheck
12 | {
13 |
14 | public class GitHubRelease
15 | {
16 | [JsonProperty("tag_name")]
17 | public string TagName { get; set; }
18 | }
19 |
20 | public class VersionChecker
21 | {
22 | private const string GitHubRepoUrl = "https://api.github.com/repos/yaobus/IPAM-NOTE/releases/latest";
23 | private readonly HttpClient _httpClient;
24 |
25 | public VersionChecker()
26 | {
27 | _httpClient = new HttpClient();
28 | _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("IPAM-NOTE");
29 | }
30 |
31 | public async Task GetLatestVersionAsync()
32 | {
33 | try
34 | {
35 | HttpResponseMessage response = await _httpClient.GetAsync(GitHubRepoUrl);
36 | response.EnsureSuccessStatusCode();
37 |
38 | string json = await response.Content.ReadAsStringAsync();
39 | var release = JsonConvert.DeserializeObject(json);
40 |
41 | return release.TagName;
42 | }
43 | catch (Exception ex)
44 | {
45 | // 处理异常
46 | Console.WriteLine($"An error occurred: {ex.Message}");
47 | return null;
48 | }
49 | }
50 | }
51 |
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/ipam.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaobus/IPAM-NOTE/bb0b543b2a10350be71c20d67f23adc660256ae0/ipam.ico
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------