CAMERA V1

This commit is contained in:
2025-09-11 20:29:17 +08:00
parent c7165f0dc5
commit ccbe0f626f
135 changed files with 26211 additions and 182 deletions

View File

@@ -0,0 +1,94 @@
---
trigger: manual
---
# 🌊 Windsurf Rules for FATrace Projects
## 📦 全局规则
1. **语言/框架**
* 使用 **C# + WinForms + ReaLTaiizor + FreeSql**
* 项目代码应结构清晰,命名规范,遵循 C# 标准。
* 尽量保持简单,不要过度封装,模块化即可。
2. **外部依赖**
* 使用 **海康威视 SDK**(提供 CHM/PDF 手册作为主要参考)。
* SDK 接口调用需要稳定性,尽量用封装类统一管理,避免散乱调用。
3. **开发风格**
* UI使用 ReaLTaiizor 美化控件,风格现代、简洁。
* 数据:使用 FreeSql 管理视频文件信息、索引和元数据。
* 模块:每个大功能单独建 `Module`,保持独立,方便后期扩展。
---
## 🎥 FATrace.OEMApp 模块规则
1. **功能目标**
* 支持实时显示海康摄像头视频流。
* 在触发事件时,回溯 **30秒前到触发结束** 的录像,并保存为视频文件。
* 保存的视频需带有元数据(时间戳、触发来源、文件路径等)。
2. **实现规则**
* 视频捕获和录像功能封装在 `MediaCaptureModule`
* SDK 相关逻辑写在单独的 `HikvisionSdkWrapper` 类里,不直接散落在 UI 层。
* 视频文件保存路径支持配置,命名规则:`YYYYMMDD_HHMMSS_trigger.mp4`
* 保持触发录像的逻辑简单,不要写复杂的多线程调度,能满足实时即可。
3. **数据规则**
* 使用 FreeSql 存储录像片段的索引信息:
* `Id`
* `StartTime`
* `EndTime`
* `FilePath`
* `TriggerSource`
---
## 🌐 FATrace.MediaServer 模块规则
1. **功能目标**
* 将 FATrace.OEMApp 保存的视频片段以 API 或文件共享形式发布。
* 提供接口供其他用户查询和下载录像片段。
2. **实现规则**
* 使用 ASP.NET Core Minimal API 或简单的 Web 服务,不需要复杂框架。
* 提供 REST API
* `GET /videos` → 获取视频列表(支持按时间过滤)。
* `GET /videos/{id}` → 下载对应视频。
* 不要实现复杂权限系统,先保证能正常发布。
3. **数据规则**
* 直接复用 FreeSql 数据库,作为视频片段索引的查询来源。
---
## 📚 SDK 文档使用规则
1. Windsurf 在调用 SDK 时,应结合我提供的 **海康 SDK CHM/PDF 文档**作为主要参考。
2. 如果遇到接口不确定,应优先查阅 SDK 文档,再写封装代码。
3. 封装类需要加上注释,标明对应的 SDK 函数。
4. SDK文档地址在FATrace.OEMApp.SDKHelper中
5. 可以联网查询使用方法
---
## ✅ 开发约束总结
* 不要过度架构,保持模块化和简单性。
* 所有和视频相关的逻辑集中在 `Media` 模块,不要分散到 UI。
* UI 只负责展示和触发,不处理 SDK 细节。
* 保存和发布的视频信息必须有数据库索引。
---

6
.windsurf/rules/r.md Normal file
View File

@@ -0,0 +1,6 @@
---
trigger: manual
glob:
description:
---

214
FATrace.Com/ConfigHelper.cs Normal file
View File

@@ -0,0 +1,214 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.Com
{
public class ConfigHelper
{
private static readonly Configuration AppConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
/// <summary>
/// 根据 key 读取字符串配置。若不存在或为空,抛出带有明确提示的信息。
/// </summary>
public static string GetRequiredString(string configKey)
{
if (string.IsNullOrWhiteSpace(configKey))
{
throw new ArgumentException("配置键不能为空", nameof(configKey));
}
try
{
var raw = ConfigurationManager.AppSettings[configKey];
if (raw == null)
{
throw new ConfigurationErrorsException($"未找到配置项: {configKey}");
}
var value = raw.Trim();
if (value.Length == 0)
{
throw new ConfigurationErrorsException($"配置项为空: {configKey}");
}
return value;
}
catch (ConfigurationErrorsException)
{
throw;
}
catch (Exception ex)
{
throw new ConfigurationErrorsException($"读取配置项失败: {configKey}", ex);
}
}
/// <summary>
/// 根据 key 读取字符串配置,不存在时返回默认值。
/// </summary>
public static string GetStringOrDefault(string configKey, string defaultValue)
{
if (string.IsNullOrWhiteSpace(configKey)) return defaultValue;
try
{
var raw = ConfigurationManager.AppSettings[configKey];
return string.IsNullOrWhiteSpace(raw) ? defaultValue : raw.Trim();
}
catch
{
return defaultValue;
}
}
/// <summary>
/// 尝试读取字符串配置。
/// </summary>
public static bool TryGetString(string configKey, out string value)
{
value = string.Empty;
if (string.IsNullOrWhiteSpace(configKey)) return false;
try
{
var raw = ConfigurationManager.AppSettings[configKey];
if (raw == null) return false;
value = raw.Trim();
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 读取 int 配置,支持默认值。
/// </summary>
public static int GetIntOrDefault(string configKey, int defaultValue)
{
var raw = GetStringOrDefault(configKey, string.Empty);
if (string.IsNullOrWhiteSpace(raw)) return defaultValue;
return int.TryParse(raw, out var result) ? result : defaultValue;
}
/// <summary>
/// 读取 bool 配置,支持默认值。
/// </summary>
public static bool GetBoolOrDefault(string configKey, bool defaultValue)
{
var raw = GetStringOrDefault(configKey, string.Empty);
if (string.IsNullOrWhiteSpace(raw)) return defaultValue;
return bool.TryParse(raw, out var result) ? result : defaultValue;
}
/// <summary>
/// 读取 TimeSpan 配置(毫秒或标准格式),支持默认值。
/// </summary>
public static TimeSpan GetTimeSpanOrDefault(string configKey, TimeSpan defaultValue)
{
var raw = GetStringOrDefault(configKey, string.Empty);
if (string.IsNullOrWhiteSpace(raw)) return defaultValue;
// 优先解析为毫秒整数
if (int.TryParse(raw, out var milliseconds))
{
return TimeSpan.FromMilliseconds(milliseconds);
}
return TimeSpan.TryParse(raw, out var ts) ? ts : defaultValue;
}
/// <summary>
/// 根据Key修改Value保存到 App.config
/// </summary>
public static void SetValue(string configKey, string newValue)
{
if (string.IsNullOrWhiteSpace(configKey))
{
throw new ArgumentException("配置键不能为空", nameof(configKey));
}
try
{
if (AppConfiguration.AppSettings.Settings[configKey] == null)
{
AppConfiguration.AppSettings.Settings.Add(configKey, newValue ?? string.Empty);
}
else
{
AppConfiguration.AppSettings.Settings[configKey].Value = newValue ?? string.Empty;
}
AppConfiguration.Save();
ConfigurationManager.RefreshSection("appSettings");
}
catch (ConfigurationErrorsException)
{
throw;
}
catch (Exception ex)
{
throw new ConfigurationErrorsException($"写入配置项失败: {configKey}", ex);
}
}
/// <summary>
/// 添加新的 Key/Value。
/// </summary>
public static void Add(string configKey, string value)
{
if (string.IsNullOrWhiteSpace(configKey))
{
throw new ArgumentException("配置键不能为空", nameof(configKey));
}
try
{
AppConfiguration.AppSettings.Settings.Add(configKey, value ?? string.Empty);
AppConfiguration.Save();
ConfigurationManager.RefreshSection("appSettings");
}
catch (ConfigurationErrorsException)
{
throw;
}
catch (Exception ex)
{
throw new ConfigurationErrorsException($"添加配置项失败: {configKey}", ex);
}
}
/// <summary>
/// 根据 Key 删除项。
/// </summary>
public static void Remove(string configKey)
{
if (string.IsNullOrWhiteSpace(configKey)) return;
try
{
AppConfiguration.AppSettings.Settings.Remove(configKey);
AppConfiguration.Save();
ConfigurationManager.RefreshSection("appSettings");
}
catch (Exception ex)
{
throw new ConfigurationErrorsException($"删除配置项失败: {configKey}", ex);
}
}
/// <summary>
/// 读取必需的连接字符串配置。
/// </summary>
public static string GetRequiredConnectionString(string configKey)
{
var cs = GetRequiredString(configKey);
if (cs.IndexOf("Initial Catalog", StringComparison.OrdinalIgnoreCase) < 0 &&
cs.IndexOf("Database", StringComparison.OrdinalIgnoreCase) < 0)
{
throw new ConfigurationErrorsException($"连接字符串看起来不完整: {configKey}");
}
return cs;
}
}
}

View File

@@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using System.ComponentModel;
using System.Reflection;
namespace FATrace.HKNetLib.Common
{
public static class EnumExtension
{
public static string GetDesc<T>(this T em) where T : Enum
{
Type type = em.GetType();
FieldInfo fd = type.GetField(em.ToString());
var num = Convert.ToInt32(em);
if (fd == null)
{
return $"{num}";
}
var firstAttr = fd.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault();
if (firstAttr == null) return $"{num}";
return (firstAttr as DescriptionAttribute).Description;
}
}
}

View File

@@ -0,0 +1,195 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Remove="Lib\x64\AudioRender.dll" />
<None Remove="Lib\x64\ClientDemo.exe" />
<None Remove="Lib\x64\DemoLocalCfg.json" />
<None Remove="Lib\x64\DeviceCfg.json" />
<None Remove="Lib\x64\GdiPlus.dll" />
<None Remove="Lib\x64\GdiPlus.lib" />
<None Remove="Lib\x64\HCCore.dll" />
<None Remove="Lib\x64\HCCore.lib" />
<None Remove="Lib\x64\HCNetSDK.dll" />
<None Remove="Lib\x64\HCNetSDK.lib" />
<None Remove="Lib\x64\HCNetSDKCom\AnalyzeData.dll" />
<None Remove="Lib\x64\HCNetSDKCom\AudioIntercom.dll" />
<None Remove="Lib\x64\HCNetSDKCom\AudioRender.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCAlarm.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCAlarm.lib" />
<None Remove="Lib\x64\HCNetSDKCom\HCCoreDevCfg.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCDisplay.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCGeneralCfgMgr.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCGeneralCfgMgr.lib" />
<None Remove="Lib\x64\HCNetSDKCom\HCIndustry.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCPlayBack.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCPreview.dll" />
<None Remove="Lib\x64\HCNetSDKCom\HCPreview.lib" />
<None Remove="Lib\x64\HCNetSDKCom\HCVoiceTalk.dll" />
<None Remove="Lib\x64\HCNetSDKCom\libiconv2.dll" />
<None Remove="Lib\x64\HCNetSDKCom\OpenAL32.dll" />
<None Remove="Lib\x64\HCNetSDKCom\StreamTransClient.dll" />
<None Remove="Lib\x64\HCNetSDKCom\SystemTransform.dll" />
<None Remove="Lib\x64\hlog.dll" />
<None Remove="Lib\x64\HmMerge.dll" />
<None Remove="Lib\x64\hpr.dll" />
<None Remove="Lib\x64\HXVA.dll" />
<None Remove="Lib\x64\libcrypto-1_1-x64.dll" />
<None Remove="Lib\x64\libmmd.dll" />
<None Remove="Lib\x64\libssl-1_1-x64.dll" />
<None Remove="Lib\x64\LocalSensorAdd.dat" />
<None Remove="Lib\x64\LocalXml.zip" />
<None Remove="Lib\x64\MP_Render.dll" />
<None Remove="Lib\x64\NPQos.dll" />
<None Remove="Lib\x64\OpenAL32.dll" />
<None Remove="Lib\x64\PlayCtrl.dll" />
<None Remove="Lib\x64\PlayCtrl.lib" />
<None Remove="Lib\x64\SuperRender.dll" />
<None Remove="Lib\x64\YUVProcess.dll" />
<None Remove="Lib\x64\zlib1.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="Lib\x64\AudioRender.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\ClientDemo.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\DemoLocalCfg.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\DeviceCfg.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\GdiPlus.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\GdiPlus.lib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCCore.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCCore.lib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDK.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDK.lib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\AnalyzeData.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\AudioIntercom.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\AudioRender.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCAlarm.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCAlarm.lib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCCoreDevCfg.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCDisplay.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCGeneralCfgMgr.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCGeneralCfgMgr.lib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCIndustry.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCPlayBack.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCPreview.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCPreview.lib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\HCVoiceTalk.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\libiconv2.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\OpenAL32.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\StreamTransClient.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HCNetSDKCom\SystemTransform.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\hlog.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HmMerge.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\hpr.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\HXVA.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\libcrypto-1_1-x64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\libmmd.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\libssl-1_1-x64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\LocalSensorAdd.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\LocalXml.zip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\MP_Render.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\NPQos.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\OpenAL32.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\PlayCtrl.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\PlayCtrl.lib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\SuperRender.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\YUVProcess.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\x64\zlib1.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,369 @@
using System.ComponentModel;
namespace FATrace.HKNetLib.Hardware
{
/// <summary>
/// 海康错误码定义
/// </summary>
public enum HKErrorCode
{
[Description("未知错误,枚举中未定义该类型")]
UNKOWN = -1,
[Description("没有错误")]
NET_DVR_NOERROR = 0,
[Description("用户名密码错误")]
NET_DVR_PASSWORD_ERROR = 1,
[Description("权限不足")]
NET_DVR_NOENOUGHPRI = 2,
[Description("没有初始化")]
NET_DVR_NOINIT = 3,
[Description("通道号错误")]
NET_DVR_CHANNEL_ERROR = 4,
[Description("连接到DVR的客户端个数超过最大")]
NET_DVR_OVER_MAXLINK = 5,
[Description("版本不匹配")]
NET_DVR_VERSIONNOMATCH = 6,
[Description("连接服务器失败")]
NET_DVR_NETWORK_FAIL_CONNECT = 7,
[Description("向服务器发送失败")]
NET_DVR_NETWORK_SEND_ERROR = 8,
[Description("从服务器接收数据失败")]
NET_DVR_NETWORK_RECV_ERROR = 9,
[Description("从服务器接收数据超时")]
NET_DVR_NETWORK_RECV_TIMEOUT = 10,
[Description("传送的数据有误")]
NET_DVR_NETWORK_ERRORDATA = 11,
[Description("调用次序错误")]
NET_DVR_ORDER_ERROR = 12,
[Description("无此权限")]
NET_DVR_OPERNOPERMIT = 13,
[Description("DVR命令执行超时")]
NET_DVR_COMMANDTIMEOUT = 14,
[Description("串口号错误")]
NET_DVR_ERRORSERIALPORT = 15,
[Description("报警端口错误")]
NET_DVR_ERRORALARMPORT = 16,
[Description("参数错误")]
NET_DVR_PARAMETER_ERROR = 17,
[Description("服务器通道处于错误状态")]
NET_DVR_CHAN_EXCEPTION = 18,
[Description("没有硬盘")]
NET_DVR_NODISK = 19,
[Description("硬盘号错误")]
NET_DVR_ERRORDISKNUM = 20,
[Description("服务器硬盘满")]
NET_DVR_DISK_FULL = 21,
[Description("服务器硬盘出错")]
NET_DVR_DISK_ERROR = 22,
[Description("服务器不支持")]
NET_DVR_NOSUPPORT = 23,
[Description("服务器忙")]
NET_DVR_BUSY = 24,
[Description("服务器修改不成功")]
NET_DVR_MODIFY_FAIL = 25,
[Description("密码输入格式不正确")]
NET_DVR_PASSWORD_FORMAT_ERROR = 26,
[Description("硬盘正在格式化,不能启动操作")]
NET_DVR_DISK_FORMATING = 27,
[Description("DVR资源不足")]
NET_DVR_DVRNORESOURCE = 28,
[Description("DVR操作失败")]
NET_DVR_DVROPRATEFAILED = 29,
[Description("打开PC声音失败")]
NET_DVR_OPENHOSTSOUND_FAIL = 30,
[Description("服务器语音对讲被占用")]
NET_DVR_DVRVOICEOPENED = 31,
[Description("时间输入不正确")]
NET_DVR_TIMEINPUTERROR = 32,
[Description("回放时服务器没有指定的文件")]
NET_DVR_NOSPECFILE = 33,
[Description("创建文件出错")]
NET_DVR_CREATEFILE_ERROR = 34,
[Description("打开文件出错")]
NET_DVR_FILEOPENFAIL = 35,
[Description("上次的操作还没有完成")]
NET_DVR_OPERNOTFINISH = 36,
[Description("获取当前播放的时间出错")]
NET_DVR_GETPLAYTIMEFAIL = 37,
[Description("播放出错")]
NET_DVR_PLAYFAIL = 38,
[Description("文件格式不正确")]
NET_DVR_FILEFORMAT_ERROR = 39,
[Description("路径错误")]
NET_DVR_DIR_ERROR = 40,
[Description("资源分配错误")]
NET_DVR_ALLOC_RESOURCE_ERROR = 41,
[Description("声卡模式错误")]
NET_DVR_AUDIO_MODE_ERROR = 42,
[Description("缓冲区太小")]
NET_DVR_NOENOUGH_BUF = 43,
[Description("创建SOCKET出错")]
NET_DVR_CREATESOCKET_ERROR = 44,
[Description("设置SOCKET出错")]
NET_DVR_SETSOCKET_ERROR = 45,
[Description("个数达到最大")]
NET_DVR_MAX_NUM = 46,
[Description("用户不存在")]
NET_DVR_USERNOTEXIST = 47,
[Description("写FLASH出错")]
NET_DVR_WRITEFLASHERROR = 48,
[Description("DVR升级失败")]
NET_DVR_UPGRADEFAIL = 49,
[Description("解码卡已经初始化过")]
NET_DVR_CARDHAVEINIT = 50,
[Description("调用播放库中某个函数失败")]
NET_DVR_PLAYERFAILED = 51,
[Description("设备端用户数达到最大")]
NET_DVR_MAX_USERNUM = 52,
[Description("获得客户端的IP地址或物理地址失败")]
NET_DVR_GETLOCALIPANDMACFAIL = 53,
[Description("该通道没有编码")]
NET_DVR_NOENCODEING = 54,
[Description("IP地址不匹配")]
NET_DVR_IPMISMATCH = 55,
[Description("MAC地址不匹配")]
NET_DVR_MACMISMATCH = 56,
[Description("升级文件语言不匹配")]
NET_DVR_UPGRADELANGMISMATCH = 57,
[Description("播放器路数达到最大")]
NET_DVR_MAX_PLAYERPORT = 58,
[Description("备份设备中没有足够空间进行备份")]
NET_DVR_NOSPACEBACKUP = 59,
[Description("没有找到指定的备份设备")]
NET_DVR_NODEVICEBACKUP = 60,
[Description("图像素位数不符限24色")]
NET_DVR_PICTURE_BITS_ERROR = 61,
[Description("图片高*宽超限限128*256")]
NET_DVR_PICTURE_DIMENSION_ERROR = 62,
[Description("图片大小超限限100K")]
NET_DVR_PICTURE_SIZ_ERROR = 63,
[Description("载入当前目录下PlayerSdk出错")]
NET_DVR_LOADPLAYERSDKFAILED = 64,
[Description("找不到PlayerSdk中某个函数入口")]
NET_DVR_LOADPLAYERSDKPROC_ERROR = 65,
[Description("载入当前目录下DSsdk出错")]
NET_DVR_LOADDSSDKFAILED = 66,
[Description("找不到DsSdk中某个函数入口")]
NET_DVR_LOADDSSDKPROC_ERROR = 67,
[Description("调用硬解码库DsSdk中某个函数失败")]
NET_DVR_DSSDK_ERROR = 68,
[Description("声卡被独占")]
NET_DVR_VOICEMONOPOLIZE = 69,
[Description("加入多播组失败")]
NET_DVR_JOINMULTICASTFAILED = 70,
[Description("建立日志文件目录失败")]
NET_DVR_CREATEDIR_ERROR = 71,
[Description("绑定套接字失败")]
NET_DVR_BINDSOCKET_ERROR = 72,
[Description("socket连接中断此错误通常是由于连接中断或目的地不可达")]
NET_DVR_SOCKETCLOSE_ERROR = 73,
[Description("注销时用户ID正在进行某操作")]
NET_DVR_USERID_ISUSING = 74,
[Description("监听失败")]
NET_DVR_SOCKETLISTEN_ERROR = 75,
[Description("程序异常")]
NET_DVR_PROGRAM_EXCEPTION = 76,
[Description("写文件失败")]
NET_DVR_WRITEFILE_FAILED = 77,
[Description("禁止格式化只读硬盘")]
NET_DVR_FORMAT_READONLY = 78,
[Description("用户配置结构中存在相同的用户名")]
NET_DVR_WITHSAMEUSERNAME = 79,
[Description("导入参数时设备型号不匹配")]
NET_DVR_DEVICETYPE_ERROR = 80,
[Description("导入参数时语言不匹配")]
NET_DVR_LANGUAGE_ERROR = 81,
[Description("导入参数时软件版本不匹配")]
NET_DVR_PARAVERSION_ERROR = 82,
[Description("预览时外接IP通道不在线")]
NET_DVR_IPCHAN_NOTALIVE = 83,
[Description("加载高清IPC通讯库StreamTransClient.dll失败")]
NET_DVR_RTSP_SDK_ERROR = 84,
[Description("加载转码库失败")]
NET_DVR_CONVERT_SDK_ERROR = 85,
[Description("超出最大的ip接入通道数")]
NET_DVR_IPC_COUNT_OVERFLOW = 86,
[Description("添加标签(一个文件片段64)等个数达到最大")]
NET_DVR_MAX_ADD_NUM = 87,
[Description("图像增强仪,参数模式错误(用于硬件设置时,客户端进行软件设置时错误值)")]
NET_DVR_PARAMMODE_ERROR = 88,
[Description("视频综合平台,码分器不在线")]
NET_DVR_CODESPITTER_OFFLINE = 89,
[Description("设备正在备份")]
NET_DVR_BACKUP_COPYING = 90,
[Description("通道不支持该操作")]
NET_DVR_CHAN_NOTSUPPORT = 91,
[Description("高度线位置太集中或长度线不够倾斜")]
NET_DVR_CALLINEINVALID = 92,
[Description("取消标定冲突,如果设置了规则及全局的实际大小尺寸过滤")]
NET_DVR_CALCANCELCONFLICT = 93,
[Description("标定点超出范围")]
NET_DVR_CALPOINTOUTRANGE = 94,
[Description("尺寸过滤器不符合要求")]
NET_DVR_FILTERRECTINVALID = 95,
[Description("设备没有注册到ddns上")]
NET_DVR_DDNS_DEVOFFLINE = 96,
[Description("DDNS服务器内部错误")]
NET_DVR_DDNS_INTER_ERROR = 97,
[Description("此功能不支持该操作系统")]
NET_DVR_FUNCTION_NOT_SUPPORT_OS = 98,
[Description("解码通道绑定显示输出次数受限")]
NET_DVR_DEC_CHAN_REBIND = 99,
[Description("加载当前目录下的语音对讲库失败")]
NET_DVR_INTERCOM_SDK_ERROR = 100,
[Description("没有正确的升级包")]
NET_DVR_NO_CURRENT_UPDATEFILE = 101,
[Description("用户还没登陆成功")]
NET_DVR_USER_NOT_SUCC_LOGIN = 102,
[Description("正在使用日志开关文件")]
NET_DVR_USE_LOG_SWITCH_FILE = 103,
[Description("端口池中用于绑定的端口已耗尽")]
NET_DVR_POOL_PORT_EXHAUST = 104,
[Description("码流封装格式错误")]
NET_DVR_PACKET_TYPE_NOT_SUPPORT = 105,
[Description("IP接入配置时IPID有误")]
NET_DVR_IPPARA_IPID_ERROR = 106,
[Description("预览组件加载失败")]
NET_DVR_LOAD_HCPREVIEW_SDK_ERROR = 107,
[Description("语音组件加载失败")]
NET_DVR_LOAD_HCVOICETALK_SDK_ERROR = 108,
[Description("报警组件加载失败")]
NET_DVR_LOAD_HCALARM_SDK_ERROR = 109,
[Description("回放组件加载失败")]
NET_DVR_LOAD_HCPLAYBACK_SDK_ERROR = 110,
[Description("显示组件加载失败")]
NET_DVR_LOAD_HCDISPLAY_SDK_ERROR = 111,
[Description("行业应用组件加载失败")]
NET_DVR_LOAD_HCINDUSTRY_SDK_ERROR = 112,
[Description("通用配置管理组件加载失败")]
NET_DVR_LOAD_HCGENERALCFGMGR_SDK_ERROR = 113,
[Description("设备配置核心组件加载失败")]
NET_DVR_LOAD_HCCOREDEVCFG_SDK_ERROR = 114,
[Description("HCNetUtils加载失败")]
NET_DVR_LOAD_HCNETUTILS_SDK_ERROR = 115,
[Description("单独加载组件时组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH = 121,
[Description("预览组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH_HCPREVIEW = 122,
[Description("语音组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH_HCVOICETALK = 123,
[Description("报警组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH_HCALARM = 124,
[Description("回放组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH_HCPLAYBACK = 125,
[Description("显示组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH_HCDISPLAY = 126,
[Description("行业应用组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH_HCINDUSTRY = 127,
[Description("通用配置管理组件与core版本不匹配")]
NET_DVR_CORE_VER_MISMATCH_HCGENERALCFGMGR = 128,
[Description("预览组件与HCNetSDK版本不匹配")]
NET_DVR_COM_VER_MISMATCH_HCPREVIEW = 136,
[Description("语音组件与HCNetSDK版本不匹配")]
NET_DVR_COM_VER_MISMATCH_HCVOICETALK = 137,
[Description("报警组件与HCNetSDK版本不匹配")]
NET_DVR_COM_VER_MISMATCH_HCALARM = 138,
[Description("回放组件与HCNetSDK版本不匹配")]
NET_DVR_COM_VER_MISMATCH_HCPLAYBACK = 139,
[Description("显示组件与HCNetSDK版本不匹配")]
NET_DVR_COM_VER_MISMATCH_HCDISPLAY = 140,
[Description("行业应用组件与HCNetSDK版本不匹配")]
NET_DVR_COM_VER_MISMATCH_HCINDUSTRY = 141,
[Description("通用配置管理组件与HCNetSDK版本不匹配")]
NET_DVR_COM_VER_MISMATCH_HCGENERALCFGMGR = 142,
[Description("配置文件导入失败")]
NET_ERR_CONFIG_FILE_IMPORT_FAILED = 145,
[Description("配置文件导出失败")]
NET_ERR_CONFIG_FILE_EXPORT_FAILED = 146,
[Description("证书错误")]
NET_DVR_CERTIFICATE_FILE_ERROR = 147,
[Description("加载SSL库失败可能是版本不匹配也可能是不存在")]
NET_DVR_LOAD_SSL_LIB_ERROR = 148,
[Description("SSL库版本不匹配")]
NET_DVR_SSL_VERSION_NOT_MATCH = 149,
[Description("别名重复,通过别名或者序列号来访问设备的新版本ddns的配置")]
NET_DVR_ALIAS_DUPLICATE = 150,
[Description("无效通信")]
NET_DVR_INVALID_COMMUNICATION = 151,
[Description("用户名不存在用户名不存在IPC5.1.7中发布出去了,所以删不掉。后续的产品这个错误码用不上)")]
NET_DVR_USERNAME_NOT_EXIST = 152,
[Description("用户被锁定")]
NET_DVR_USER_LOCKED = 153,
[Description("无效用户ID")]
NET_DVR_INVALID_USERID = 154,
[Description("登录版本低")]
NET_DVR_LOW_LOGIN_VERSION = 155,
[Description("加载libeay32.dll库失败")]
NET_DVR_LOAD_LIBEAY32_DLL_ERROR = 156,
[Description("加载ssleay32.dll库失败")]
NET_DVR_LOAD_SSLEAY32_DLL_ERROR = 157,
[Description("加载libiconv库失败")]
NET_ERR_LOAD_LIBICONV = 158,
[Description("SSL连接失败")]
NET_ERR_SSL_CONNECT_FAILED = 159,
[Description("获取多播地址错误")]
NET_ERR_MCAST_ADDRESS_ERROR = 160,
[Description("加载zlib.dll库失败")]
NET_ERR_LOAD_ZLIB = 161,
[Description("Openssl库未初始化")]
NET_ERR_OPENSSL_NO_INIT = 162,
[Description("对应的服务器找不到,查找时输入的国家编号或者服务器类型错误")]
NET_DVR_SERVER_NOT_EXIST = 164,
[Description("连接测试服务器失败")]
NET_DVR_TEST_SERVER_FAIL_CONNECT = 165,
[Description("NAS服务器挂载目录失败目录无效")]
NET_DVR_NAS_SERVER_INVALID_DIR = 166,
[Description("NAS服务器挂载目录失败没有权限")]
NET_DVR_NAS_SERVER_NOENOUGH_PRI = 167,
[Description("服务器使用域名但是没有配置DNS可能造成域名无效。")]
NET_DVR_EMAIL_SERVER_NOT_CONFIG_DNS = 168,
[Description("没有配置网关,可能造成发送邮件失败。")]
NET_DVR_EMAIL_SERVER_NOT_CONFIG_GATEWAY = 169,
[Description("用户名密码不正确,测试服务器的用户名或密码错误")]
NET_DVR_TEST_SERVER_PASSWORD_ERROR = 170,
[Description("设备和smtp服务器交互异常")]
NET_DVR_EMAIL_SERVER_CONNECT_EXCEPTION_WITH_SMTP = 171,
[Description("FTP服务器创建目录失败")]
NET_DVR_FTP_SERVER_FAIL_CREATE_DIR = 172,
[Description("FTP服务器没有写入权限")]
NET_DVR_FTP_SERVER_NO_WRITE_PIR = 173,
[Description("IP冲突")]
NET_DVR_IP_CONFLICT = 174,
[Description("存储池空间已满")]
NET_DVR_INSUFFICIENT_STORAGEPOOL_SPACE = 175,
[Description("云服务器存储池无效,没有配置存储池或者存储池ID错误")]
NET_DVR_STORAGEPOOL_INVALID = 176,
[Description("生效需要重启")]
NET_DVR_EFFECTIVENESS_REBOOT = 177,
[Description("断网续传布防连接已经存在(该错误码是在私有布防连接建立的情况下,重复布防的断网续传功能时,返回。)")]
NET_ERR_ANR_ARMING_EXIST = 178,
[Description("断网续传上传连接已经存在(EHOME协议和SDK协议是不能同时支持断网续传的当一个协议存在的时候另外一个连接建立话报错这个错误码。)")]
NET_ERR_UPLOADLINK_EXIST = 179,
[Description("导入文件格式不正确")]
NET_ERR_INCORRECT_FILE_FORMAT = 180,
[Description("导入文件内容不正确")]
NET_ERR_INCORRECT_FILE_CONTENT = 181,
[Description("HRUDP连接数超过设备限制")]
NET_ERR_MAX_HRUDP_LINK = 182,
[Description("接入秘钥或加密秘钥不正确")]
NET_SDK_ERR_ACCESSKEY_SECRETKEY = 183,
[Description("创建端口复用失败")]
NET_SDK_ERR_CREATE_PORT_MULTIPLEX = 184,
[Description("不支持无阻塞抓图")]
NET_DVR_NONBLOCKING_CAPTURE_NOTSUPPORT = 185,
[Description("已开启异步,该功能无效")]
NET_SDK_ERR_FUNCTION_INVALID = 186,
[Description("已达到端口复用最大数目")]
NET_SDK_ERR_MAX_PORT_MULTIPLEX = 187,
[Description("连接尚未建立或连接无效")]
NET_DVR_INVALID_LINK = 188,
[Description("接口不支持ISAPI协议")]
NET_DVR_ISAPI_NOT_SUPPORT = 189,
[Description("设备未激活")]
NET_DVR_ERROR_DEVICE_NOT_ACTIVATED = 250,
[Description("有风险的密码")]
NET_DVR_ERROR_RISK_PASSWORD = 251,
[Description("设备已激活")]
NET_DVR_ERROR_DEVICE_HAS_ACTIVATED = 252
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.HKNetLib.Wrapper
{
/// <summary>
/// 海康DVR登录信息
/// </summary>
public class CameraLoginInfo
{
/// <summary>
/// 摄像头的IP地址
/// </summary>
public string IP { get; set; }
/// <summary>
/// 登录端口号
/// </summary>
public ushort Port { get; set; } = 8000;
/// <summary>
/// 登录用户名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 登录密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 默认通道
/// </summary>
public int ChannelNo { get; set; } = 1;
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.HKNetLib.Wrapper
{
public enum CodeStreamType
{
[Description("主码流")]
Main = 0,
[Description("子码流")]
Sub = 1,
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.HKNetLib.Wrapper
{
/// <summary>
/// 海康对焦模式
/// </summary>
public enum FocusModeType
{
/// <summary>
/// 自动
/// </summary>
Auto = 0,
/// <summary>
/// 手动
/// </summary>
Manual = 1,
/// <summary>
/// 半自动
/// </summary>
HalfAuto = 2,
/// <summary>
/// 未知/无
/// </summary>
None = 4
}
}

View File

@@ -0,0 +1,577 @@
using FATrace.HKNetLib.Common;
using FATrace.HKNetLib.Hardware;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static FATrace.HKNetLib.Hardware.CHCNetSDK;
namespace FATrace.HKNetLib.Wrapper
{
public class HkCamera : ICamera
{
private bool _disposedValue;
private bool _sdkInit;
private int _userId;
private string _serailNumber;
private CameraLoginInfo _loginInfo = new CameraLoginInfo();
/// <summary>
/// 初始化海康sdk
/// </summary>
/// <exception cref="BadImageFormatException"></exception>
public HkCamera()
{
_sdkInit = CHCNetSDK.NET_DVR_Init();
}
static HkCamera()
{
//设置搜索路径兼容x86 和 x64
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
path = Path.Combine(path, "Lib", IntPtr.Size == 8 ? "x64" : "x86");
bool ok = SetDllDirectory(path);
if (!ok) throw new System.ComponentModel.Win32Exception();
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetDllDirectory(string path);
/// <summary>
/// 获取最新的错误信息
/// </summary>
/// <returns></returns>
public string GetLastError()
{
var error = CHCNetSDK.NET_DVR_GetLastError();
if (error == 0)
{
return string.Empty;
}
if (Enum.TryParse(error.ToString(), out HKErrorCode result))
{
return result.GetDesc();
}
return $"错误码: {error}";
}
public string GetSerialNumber() { return _serailNumber; }
public bool Login(CameraLoginInfo cameraLoginInfo)
{
try
{
if (_userId >= 0)
{
Logout();
}
_loginInfo = cameraLoginInfo;
var loginInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();
loginInfo.sDeviceAddress = cameraLoginInfo.IP;
loginInfo.wPort = cameraLoginInfo.Port;
loginInfo.sUserName = cameraLoginInfo.UserName;
loginInfo.sPassword = cameraLoginInfo.Password;
//是否异步登录0- 否1- 是
loginInfo.bUseAsynLogin = false;
var _deviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();
_userId = CHCNetSDK.NET_DVR_Login_V40(ref loginInfo, ref _deviceInfo);
_serailNumber = _deviceInfo.struDeviceV30.sSerialNumber;
return _userId >= 0;
}
catch
{
return false;
}
}
#region NVR开发
/// <summary>
/// NVR设备信息 DVR_DEVICEINFO_V30
/// </summary>
public NET_DVR_DEVICEINFO_V30 DVRDeviceInfoV30;
/// <summary>
/// DVR_IPPARACFG_V40
/// </summary>
public CHCNetSDK.NET_DVR_IPPARACFG_V40 DVR_IPPARACFG_V40 { get; set; }
private uint dwAChanTotalNum { get; set; } = 0;
private uint dwDChanTotalNum { get; set; } = 0;
public NET_DVR_GET_STREAM_UNION DVR_GET_STREAM_UNION { get; set; }
public CHCNetSDK.NET_DVR_IPCHANINFO DVR_IPCHANINFO { get; set; }
/// <summary>
/// 最新的错误信息
/// </summary>
public string LastMsgErr { get; set; }
/// <summary>
/// 登录的用户Id
/// </summary>
public Int32 m_lUserID { get; set; } = -1;
/// <summary>
/// 选择的通道号
/// 一般是 一个通道对应一个相机
/// </summary>
public long iSelIndex = 0;
/// <summary>
/// 通道集合
/// </summary>
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 96, ArraySubType = UnmanagedType.U4)]
public int[] iChannelNum = new int[96];
/// <summary>
/// 下载的Handle
/// </summary>
public Int32 m_lDownHandle { get; set; } = -1;
/// <summary>
/// 用户登录
/// </summary>
/// <returns></returns>
public bool Sdk_NET_DVR_Login_V30(string DVRIPAddress, int DVRPortNumber, string DVRUserName, string DVRPassword)
{
//登录设备 Login the device
m_lUserID = CHCNetSDK.NET_DVR_Login_V30(DVRIPAddress, DVRPortNumber, DVRUserName, DVRPassword, ref DVRDeviceInfoV30);
if (m_lUserID < 0)
{
LastMsgErr = GetLastError();
//MessageBox.Show(str1);
return false;
}
else
{
//登录成功
//MessageBox.Show("Login Success!");
//btnLogin.Text = "Logout";
dwAChanTotalNum = (uint)DVRDeviceInfoV30.byChanNum;
dwDChanTotalNum = (uint)DVRDeviceInfoV30.byIPChanNum + 256 * (uint)DVRDeviceInfoV30.byHighDChanNum;
if (dwDChanTotalNum > 0)
{
InfoIPChannel();
}
else
{
for (int i = 0; i < dwAChanTotalNum; i++)
{
//ListAnalogChannel(i + 1, 1);
iChannelNum[i] = i + (int)DVRDeviceInfoV30.byStartChan;
}
// MessageBox.Show("This device has no IP channel!");
}
}
return true;
}
/// <summary>
/// 获取通道信息
/// </summary>
private void InfoIPChannel()
{
uint dwSize = (uint)Marshal.SizeOf(DVR_IPPARACFG_V40);
IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal((Int32)dwSize);
Marshal.StructureToPtr(DVR_IPPARACFG_V40, ptrIpParaCfgV40, false);
uint dwReturn = 0;
int iGroupNo = 0; //该Demo仅获取第一组64个通道如果设备IP通道大于64路需要按组号0~i多次调用NET_DVR_GET_IPPARACFG_V40获取
if (!CHCNetSDK.NET_DVR_GetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_IPPARACFG_V40, iGroupNo, ptrIpParaCfgV40, dwSize, ref dwReturn))
{
LastMsgErr = GetLastError();
/*str1 = "NET_DVR_GET_IPPARACFG_V40 failed, error code= " + iLastErr; //*/
//获取IP资源配置信息失败输出错误号
//MessageBox.Show(str1);
}
else
{
// succ
DVR_IPPARACFG_V40 = (CHCNetSDK.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40, typeof(CHCNetSDK.NET_DVR_IPPARACFG_V40));
for (int i = 0; i < dwAChanTotalNum; i++)
{
//ListAnalogChannel(i + 1, DVR_IPPARACFG_V40.byAnalogChanEnable[i]);
iChannelNum[i] = i + (int)DVRDeviceInfoV30.byStartChan;
}
byte byStreamType;
uint iDChanNum = 64;
if (dwDChanTotalNum < 64)
{
iDChanNum = dwDChanTotalNum; //如果设备IP通道小于64路按实际路数获取
}
for (int i = 0; i < iDChanNum; i++)
{
iChannelNum[i + dwAChanTotalNum] = i + (int)DVR_IPPARACFG_V40.dwStartDChan;
byStreamType = DVR_IPPARACFG_V40.struStreamMode[i].byGetStreamType;
DVR_GET_STREAM_UNION = DVR_IPPARACFG_V40.struStreamMode[i].uGetStream;
switch (byStreamType)
{
//目前NVR仅支持0- 直接从设备取流一种方式
case 0:
dwSize = (uint)Marshal.SizeOf(DVR_GET_STREAM_UNION);
IntPtr ptrChanInfo = Marshal.AllocHGlobal((Int32)dwSize);
Marshal.StructureToPtr(DVR_GET_STREAM_UNION, ptrChanInfo, false);
DVR_IPCHANINFO = (CHCNetSDK.NET_DVR_IPCHANINFO)Marshal.PtrToStructure(ptrChanInfo, typeof(CHCNetSDK.NET_DVR_IPCHANINFO));
//列出IP通道
//ListIPChannel(i + 1, DVR_IPCHANINFO.byEnable, DVR_IPCHANINFO.byIPID);
Marshal.FreeHGlobal(ptrChanInfo);
break;
default:
break;
}
}
}
Marshal.FreeHGlobal(ptrIpParaCfgV40);
}
/// <summary>
/// 根据时间获取DVR统计信息
/// </summary>
public (bool Result, string Msg) Sdk_NET_DVR_GetFileByTime_V40(DateTime startTime, DateTime endTime, string SaveVideFilePath)
{
if (m_lDownHandle >= 0)
{
//MessageBox.Show("Downloading, please stop firstly!");//正在下载,请先停止下载
return (Result: false, Msg: "正在下载,请先停止下载");
}
NET_DVR_PLAYCOND struDownPara = new NET_DVR_PLAYCOND();
struDownPara.dwChannel = (uint)iChannelNum[(int)iSelIndex]; //通道号 Channel number
//设置下载的开始时间 Set the starting time
struDownPara.struStartTime.dwYear = startTime.Year;
struDownPara.struStartTime.dwMonth = startTime.Month;
struDownPara.struStartTime.dwDay = startTime.Day;
struDownPara.struStartTime.dwHour = startTime.Hour;
struDownPara.struStartTime.dwMinute = startTime.Minute;
struDownPara.struStartTime.dwSecond = startTime.Second;
//设置下载的结束时间 Set the stopping time
struDownPara.struStopTime.dwYear = endTime.Year;
struDownPara.struStopTime.dwMonth = endTime.Month;
struDownPara.struStopTime.dwDay = endTime.Day;
struDownPara.struStopTime.dwHour = endTime.Hour;
struDownPara.struStopTime.dwMinute = endTime.Minute;
struDownPara.struStopTime.dwSecond = endTime.Second;
//string sVideoFileName; //录像文件保存路径和文件名 the path and file name to save
//sVideoFileName = "D:\\Downtest_Channel" + struDownPara.dwChannel + ".mp4";
//按时间下载 Download by time
m_lDownHandle = CHCNetSDK.NET_DVR_GetFileByTime_V40(m_lUserID, SaveVideFilePath, ref struDownPara);
if (m_lDownHandle < 0)
{
LastMsgErr = GetLastError();
return (Result: false, Msg: $"[NET_DVR_GetFileByTime_V40] 执行下载失败:{LastMsgErr}");
}
uint iOutValue = 0;
//该接口指定了当前要下载的录像文件调用成功后还需要调用NET_DVR_PlayBackControl_V40接口的开始播放控制命令NET_DVR_PLAYSTART才能实现下载。
//V5.0.3.2或以后版本通过该接口保存录像保存的录像文件数据超过文件最大限制字节数默认为1024MBSDK会自动切片即新建文件进行保存文件名命名规则为“在接口传入的文件名基础上增加数字标识(例如:*_1.mp4、*_2.mp4)”。
//可以调用NET_DVR_GetSDKLocalCfg、NET_DVR_SetSDKLocalCfg(配置类型NET_DVR_LOCAL_CFG_TYPE_GENERAL)获取和设置切片模式和文件最大限制字节数。
if (!CHCNetSDK.NET_DVR_PlayBackControl_V40(m_lDownHandle, CHCNetSDK.NET_DVR_PLAYSTART, IntPtr.Zero, 0, IntPtr.Zero, ref iOutValue))
{
LastMsgErr = GetLastError();
return (Result: false, Msg: $"[NET_DVR_PlayBackControl_V40] 执行下载控制失败:{LastMsgErr}");
}
return (Result: true, Msg: "下载成功!");
}
/// <summary>
/// 获取下载的进度
/// </summary>
/// <param name="downHandle"></param>
/// <returns></returns>
public int Sdk_NET_DVR_GetDownloadPos(Int32 downHandle)
{
return CHCNetSDK.NET_DVR_GetDownloadPos(downHandle);
}
#endregion
public bool IsOnline()
{
try
{
return CHCNetSDK.NET_DVR_RemoteControl(_userId, CHCNetSDK.NET_DVR_CHECK_USER_STATUS, IntPtr.Zero, 0);
}
catch { return false; }
}
public void Logout()
{
try
{
if (_userId >= 0)
{
CHCNetSDK.NET_DVR_Logout(_userId);
_userId = -1;
}
}
catch { }
}
private bool CheckLogin()
{
if (IsOnline()) return true;
return Login(_loginInfo);
}
/// <summary>
/// 控制云台,设备接收到控制命令后直接返回成功。不关心云台是否进行相应的动作
/// </summary>
/// <param name="cmd"></param>
/// <param name="speed">取值范围[1,7] </param>
/// <returns></returns>
public bool StartPTZControl(PtzCommand cmd, Int32 speed = 4)
{
try
{
if (!CheckLogin()) return false;
var result = CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(_userId, _loginInfo.ChannelNo, (uint)cmd, 0, (uint)speed);
return result;
}
catch
{
return false;
}
}
/// <summary>
/// 停止云台
/// </summary>
/// <param name="cmd"></param>
/// <returns></returns>
public bool StopPTZControl(PtzCommand cmd)
{
try
{
if (!CheckLogin()) return false;
var result = CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(_userId, _loginInfo.ChannelNo, (uint)cmd, 1, 4);
return result;
}
catch
{
return false;
}
}
/// <summary>
/// 抓图
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public bool CapturePicture(string fileName)
{
if (!CheckLogin()) return false;
try
{
FileInfo fi = new FileInfo(fileName);
if (fi.Exists)
{
File.Delete(fi.FullName);
}
if (!Directory.Exists(fi.DirectoryName))
{
Directory.CreateDirectory(fi.DirectoryName);
}
CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA
{
wPicQuality = 0,
wPicSize = 0xff
};
return CHCNetSDK.NET_DVR_CaptureJPEGPicture(_userId, _loginInfo.ChannelNo, ref lpJpegPara, fileName);
}
catch
{
return false;
}
}
public bool SetFocusMode(FocusModeType focusModeType)
{
bool res = false;
var destMode = focusModeType;
CHCNetSDK.NET_DVR_FOCUSMODE_CFG focusmode_cfg = new CHCNetSDK.NET_DVR_FOCUSMODE_CFG();
focusmode_cfg.byRes = new byte[48];
focusmode_cfg.byRes1 = new byte[2];
int nSize = Marshal.SizeOf(focusmode_cfg);
focusmode_cfg.dwSize = (uint)nSize;
IntPtr ptrDeviceCfg = Marshal.AllocHGlobal(nSize);
try
{
// 获取当前模式
Marshal.StructureToPtr(focusmode_cfg, ptrDeviceCfg, false);
uint rSize = (uint)nSize;
if (!CHCNetSDK.NET_DVR_GetDVRConfig(_userId, CHCNetSDK.NET_DVR_GET_FOCUSMODECFG, 1, ptrDeviceCfg, (uint)nSize, ref rSize))
{
var errorStr = CHCNetSDK.NET_DVR_GetLastError();
return res;
}
// 如果当前模式与请求模式相同则直接返回true
CHCNetSDK.NET_DVR_FOCUSMODE_CFG getObj = (CHCNetSDK.NET_DVR_FOCUSMODE_CFG)Marshal.PtrToStructure(ptrDeviceCfg, typeof(CHCNetSDK.NET_DVR_FOCUSMODE_CFG));
var curMode = (FocusModeType)getObj.byFocusMode;
if (curMode == destMode)
{
res = true;
return res;
}
// 否则调用设置方法
getObj.fOpticalZoomLevel = 0;
getObj.byOpticalZoom = 32;
getObj.byFocusMode = (byte)destMode;
IntPtr ptrDeviceCfg1 = Marshal.AllocHGlobal((int)getObj.dwSize);
Marshal.StructureToPtr(getObj, ptrDeviceCfg1, false);
res = CHCNetSDK.NET_DVR_SetDVRConfig(_userId, CHCNetSDK.NET_DVR_SET_FOCUSMODECFG, 1, ptrDeviceCfg1, focusmode_cfg.dwSize);
if (!res)
{
var errorStr = CHCNetSDK.NET_DVR_GetLastError();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
Marshal.FreeHGlobal(ptrDeviceCfg);
}
return res;
}
/// <summary>
/// 获取对焦距模式
/// </summary>
/// <returns></returns>
public FocusModeType GetFocusMode()
{
FocusModeType retValue = FocusModeType.None;
CHCNetSDK.NET_DVR_FOCUSMODE_CFG focusmode_cfg = new CHCNetSDK.NET_DVR_FOCUSMODE_CFG
{
byRes = new byte[48],
byRes1 = new byte[2]
};
int nSize = Marshal.SizeOf(focusmode_cfg);
focusmode_cfg.dwSize = (uint)nSize;
IntPtr ptrDeviceCfg = Marshal.AllocHGlobal(nSize);
try
{
Marshal.StructureToPtr(focusmode_cfg, ptrDeviceCfg, false);
uint rSize = (uint)nSize;
if (CHCNetSDK.NET_DVR_GetDVRConfig(this._userId, CHCNetSDK.NET_DVR_GET_FOCUSMODECFG, 1, ptrDeviceCfg, (uint)nSize, ref rSize))
{
CHCNetSDK.NET_DVR_FOCUSMODE_CFG getObj = (CHCNetSDK.NET_DVR_FOCUSMODE_CFG)Marshal.PtrToStructure(ptrDeviceCfg, typeof(CHCNetSDK.NET_DVR_FOCUSMODE_CFG));
retValue = (FocusModeType)getObj.byFocusMode;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
Marshal.FreeHGlobal(ptrDeviceCfg);
}
return retValue;
}
public bool Shutdown()
{
try
{
if (!CheckLogin()) return false;
return CHCNetSDK.NET_DVR_ShutDownDVR(_userId);
}
catch
{
return false;
}
}
public bool Reboot()
{
try
{
if (!CheckLogin()) return false;
return CHCNetSDK.NET_DVR_RebootDVR(_userId);
}
catch
{
return false;
}
}
#region
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
}
if (_sdkInit)
{
if (_userId >= 0)
{
Logout();
}
try
{
CHCNetSDK.NET_DVR_Cleanup();
}
catch { }
}
_disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
#endregion
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.HKNetLib.Wrapper
{
public interface ICamera : IDisposable
{
/// <summary>
/// 获取最后的异常描述
/// </summary>
/// <returns></returns>
string GetLastError();
/// <summary>
/// 获取序列号字符串, 需要先登录
/// </summary>
/// <returns></returns>
string GetSerialNumber();
/// <summary>
/// 登入相机
/// </summary>
/// <param name="cameraLoginInfo"></param>
/// <returns></returns>
bool Login(CameraLoginInfo cameraLoginInfo);
/// <summary>
/// 是否在线
/// </summary>
/// <returns></returns>
bool IsOnline();
/// <summary>
/// 登出
/// </summary>
void Logout();
bool SetFocusMode(FocusModeType focusModeType);
FocusModeType GetFocusMode();
/// <summary>
/// 控制云台开始
/// </summary>
/// <param name="cmd"></param>
/// <param name="speed"></param>
/// <returns></returns>
bool StartPTZControl(PtzCommand cmd, Int32 speed = 4);
/// <summary>
/// 控制云台结束
/// </summary>
/// <param name="cmd"></param>
/// <returns></returns>
bool StopPTZControl(PtzCommand cmd);
/// <summary>
/// 抓取相机内的图片
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
bool CapturePicture(string fileName);
/// <summary>
/// 关闭相机
/// </summary>
/// <returns></returns>
bool Shutdown();
/// <summary>
/// 重启相机
/// </summary>
/// <returns></returns>
bool Reboot();
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.HKNetLib.Wrapper
{
/// <summary>
/// 云台操作命令
/// </summary>
public enum PtzCommand
{
/// <summary>
/// 未知命令
/// </summary>
[Description("未知命令")]
UNKOWN = 0,
/// <summary>
/// 打开灯光电源
/// </summary>
[Description("打开灯光电源")]
LIGHT_PWRON = 2,
/// <summary>
/// 打开雨刷开关
/// </summary>
[Description("打开雨刷开关")]
WIPER_PWRON = 3,
/// <summary>
/// 打开风扇开关
/// </summary>
[Description("打开风扇开关")]
FAN_PWRON = 4,
/// <summary>
/// 打开加热器开关
/// </summary>
[Description("打开加热器开关")]
HEATER_PWRON = 5,
/// <summary>
/// 打开辅助设备开关
/// </summary>
[Description("打开辅助设备开关")]
AUX_PWRON1 = 6,
/// <summary>
/// 打开辅助设备开关
/// </summary>
[Description("打开辅助设备开关")]
AUX_PWRON2 = 7,
/// <summary>
/// 焦距变大
/// </summary>
[Description("焦距变大")]
ZOOM_IN = 11,
/// <summary>
/// 焦距变小
/// </summary>
[Description("焦距变小")]
ZOOM_OUT = 12,
/// <summary>
/// 焦点前调
/// </summary>
[Description("焦点前调")]
FOCUS_NEAR = 13,
/// <summary>
/// 焦点后调
/// </summary>
[Description("焦点后调")]
FOCUS_FAR = 14,
/// <summary>
/// 光圈扩大
/// </summary>
[Description("光圈扩大")]
IRIS_OPEN = 15,
/// <summary>
/// 光圈缩小
/// </summary>
[Description("光圈缩小")]
IRIS_CLOSE = 16,
/// <summary>
/// 上仰
/// </summary>
[Description("上仰")]
TILT_UP = 21,
/// <summary>
/// 下俯
/// </summary>
[Description("下俯")]
TILT_DOWN = 22,
/// <summary>
/// 左转
/// </summary>
[Description("左转")]
PAN_LEFT = 23,
/// <summary>
/// 右转
/// </summary>
[Description("右转")]
PAN_RIGHT = 24,
/// <summary>
/// 上仰和左转
/// </summary>
[Description("上仰和左转")]
UP_LEFT = 25,
/// <summary>
/// 上仰和右转
/// </summary>
[Description("上仰和右转")]
UP_RIGHT = 26,
/// <summary>
/// 下俯和左转
/// </summary>
[Description("下俯和左转")]
DOWN_LEFT = 27,
/// <summary>
/// 下俯和右转
/// </summary>
[Description("下俯和右转")]
DOWN_RIGHT = 28,
/// <summary>
/// 左右自动扫描
/// </summary>
[Description("左右自动扫描")]
PAN_AUTO = 29
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace FATrace.Model
{
public abstract class BaseEntity
{
public long Id { get; set; }
public DateTime CreateTime { get; set; } = DateTime.Now;
public DateTime UpdateTime { get; set; } = DateTime.Now;
}
}

View File

@@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FreeSql" Version="3.5.213" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,79 @@
using FreeSql.DataAnnotations;
namespace FATrace.Model
{
/// <summary>
/// 视频事件
/// </summary>
[Table(Name = "VideoAction")]
public class VideoAction
{
/// <summary>
/// 主键
/// </summary>
[Column(IsPrimary = true, IsIdentity = true)]
public long Id { get; set; }
/// <summary>
/// Code
/// </summary>
[Column(Name = "Code", IsNullable = false, StringLength = 100)]
public string? Code { get; set; }
/// <summary>
/// 用户信息
/// </summary>
[Column(Name = "User", IsNullable = false, StringLength = 100)]
public string? User { get; set; }
///// <summary>
///// 分类信息-CAN/LIN
///// </summary>
//[Column(Name = "CANLINInfo", IsNullable = false, MapType = typeof(string))]
//public CANLIN CANLINInfo { get; set; }
/// <summary>
/// 视频文件路径
/// </summary>
[Column(Name = "VideoFilePath", IsNullable = false, StringLength = 200)]
public string? VideoFilePath { get; set; }
/// <summary>
/// 视频名称
/// </summary>
[Column(Name = "VideoName", IsNullable = false, StringLength = 100)]
public string? VideoName { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[Column(Name = "StartTime")]
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
[Column(Name = "EndTime")]
public DateTime EndTime { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column(ServerTime = DateTimeKind.Local, CanUpdate = true)]
public DateTime CreateTime { get; set; }
///// <summary>
///// ///////////////////////////////////////////导航属性///////////////////////////////////////////////////////
///// </summary>
//public List<CanLinRWConfig>? CanLinConfigContents { get; set; }
///// <summary>
///// ///////////////////////////////////////////导航属性 LIN 一对一///////////////////////////////////////////////////////
///// </summary>
//public long CANFdConfigExdId { get; set; } // 外键字段,必要
//public CANFdConfigExd CANFdConfigExd { get; set; }
}
}

15
FATrace.OEMApp/App.config Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="connecting1" value="Data Source=192.168.40.2;user instance=false;Initial Catalog=DissColorMachine;User ID=sa;Password=ABCabc123" />
<add key="connecting" value="Data Source=CT-PC;user instance=false;Initial Catalog=MoviconDb;User ID=sa;Password=12345678" />
<add key="RemoteConnecting" value="Data Source=CT-PC;user instance=false;Initial Catalog=MoviconDb;User ID=sa;Password=12345678" />
<add key="PLCIP" value="127.0.0.1" />
<add key="PLCPort" value="6000" />
<add key="PLCScan" value="600" />
<add key="InsCheckPort" value="COM10" />
<add key="InsCheckRate" value="9600" />
</appSettings>
</configuration>

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
@@ -6,11 +6,436 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateResourceWarnOnBinaryFormatterUse>false</GenerateResourceWarnOnBinaryFormatterUse>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\2.wav" />
<None Remove="Images\29.wav" />
<None Remove="Images\About.png" />
<None Remove="Images\alert_128px_1082676_easyicon.net.ico" />
<None Remove="Images\alert_on_128px_581757_easyicon.net.ico" />
<None Remove="Images\button1.png" />
<None Remove="Images\button10.png" />
<None Remove="Images\button11.png" />
<None Remove="Images\button13.png" />
<None Remove="Images\button2.png" />
<None Remove="Images\button3.png" />
<None Remove="Images\button4.png" />
<None Remove="Images\button5.png" />
<None Remove="Images\button6.png" />
<None Remove="Images\button7.png" />
<None Remove="Images\button8.png" />
<None Remove="Images\button9.png" />
<None Remove="Images\cz1.ico" />
<None Remove="Images\Falut.png" />
<None Remove="Images\flux_128px_1157201_easyicon.net.ico" />
<None Remove="Images\hand1.png" />
<None Remove="Images\hand2.png" />
<None Remove="Images\handauto.png" />
<None Remove="Images\icontexto_message_types_alert_red_128px_505529_easyicon.net.png" />
<None Remove="Images\Input.png" />
<None Remove="Images\IPQC制程检验 (1).png" />
<None Remove="Images\IPQC制程检验.png" />
<None Remove="Images\ip_address_512px_1169699_easyicon.net.png" />
<None Remove="Images\Load.png" />
<None Remove="Images\Log.png" />
<None Remove="Images\logo.png" />
<None Remove="Images\Main.png" />
<None Remove="Images\name.png" />
<None Remove="Images\NG.png" />
<None Remove="Images\no name.wav" />
<None Remove="Images\no.png" />
<None Remove="Images\ok.png" />
<None Remove="Images\Output.png" />
<None Remove="Images\P0.ico" />
<None Remove="Images\P1.ico" />
<None Remove="Images\P2.ico" />
<None Remove="Images\P3.ico" />
<None Remove="Images\P4.png" />
<None Remove="Images\putput1.png" />
<None Remove="Images\putput2.png" />
<None Remove="Images\putput3.png" />
<None Remove="Images\Question.png" />
<None Remove="Images\Quit.png" />
<None Remove="Images\red_alert_128px_569416_easyicon.net.png" />
<None Remove="Images\RunState 1.png" />
<None Remove="Images\RunState 2.png" />
<None Remove="Images\RunState 3.png" />
<None Remove="Images\RunState 4.png" />
<None Remove="Images\RunState 5.png" />
<None Remove="Images\RunState.png" />
<None Remove="Images\set1.png" />
<None Remove="Images\set2.png" />
<None Remove="Images\set3.png" />
<None Remove="Images\time_128px_1195887_easyicon.net.ico" />
<None Remove="Images\Tool.png" />
<None Remove="Images\user_853px_1149308_easyicon.net.png" />
<None Remove="Images\Wait.png" />
<None Remove="Images\Well.png" />
<None Remove="Images\不合格.png" />
<None Remove="Images\任务完成数量.png" />
<None Remove="Images\关闭.png" />
<None Remove="Images\分类.png" />
<None Remove="Images\切换.png" />
<None Remove="Images\切换1.png" />
<None Remove="Images\包装 (1).png" />
<None Remove="Images\包装.png" />
<None Remove="Images\压缩机.png" />
<None Remove="Images\双手自动.png" />
<None Remove="Images\合格.png" />
<None Remove="Images\垫付费核销.png" />
<None Remove="Images\工单 (1).png" />
<None Remove="Images\工单.png" />
<None Remove="Images\工单信息.png" />
<None Remove="Images\时间.png" />
<None Remove="Images\条码 (1).png" />
<None Remove="Images\条码.png" />
<None Remove="Images\次品1 (1).png" />
<None Remove="Images\次品1.png" />
<None Remove="Images\次品报表.png" />
<None Remove="Images\注销.png" />
<None Remove="Images\用户 管理.png" />
<None Remove="Images\登录 (1).png" />
<None Remove="Images\登录 (2).png" />
<None Remove="Images\登录.png" />
<None Remove="Images\箱子.png" />
<None Remove="Images\裕同包装.ico" />
<None Remove="Images\警告.png" />
<None Remove="Images\质检 (1).png" />
<None Remove="Images\质检 (2).png" />
<None Remove="Images\质检 (3).png" />
<None Remove="Images\质检.png" />
<None Remove="Images\进度.png" />
<None Remove="Images\选择.png" />
<None Remove="Images\错误.png" />
</ItemGroup>
<ItemGroup>
<Content Include="Images\2.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\29.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\About.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\alert_128px_1082676_easyicon.net.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\alert_on_128px_581757_easyicon.net.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button10.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button11.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button13.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button3.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button4.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button5.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button6.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button7.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button8.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\button9.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\cz1.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Falut.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\flux_128px_1157201_easyicon.net.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\hand1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\hand2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\handauto.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\icontexto_message_types_alert_red_128px_505529_easyicon.net.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Input.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\IPQC制程检验 (1).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\IPQC制程检验.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\ip_address_512px_1169699_easyicon.net.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Load.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Log.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\logo.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Main.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\name.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\NG.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\no name.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\no.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\ok.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Output.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\P0.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\P1.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\P2.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\P3.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\P4.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\putput1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\putput2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\putput3.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Question.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Quit.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\red_alert_128px_569416_easyicon.net.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\RunState 1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\RunState 2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\RunState 3.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\RunState 4.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\RunState 5.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\RunState.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\set1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\set2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\set3.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\time_128px_1195887_easyicon.net.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Tool.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\user_853px_1149308_easyicon.net.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Wait.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\Well.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\不合格.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\任务完成数量.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\关闭.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\分类.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\切换.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\切换1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\包装 (1).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\包装.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\压缩机.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\双手自动.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\合格.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\垫付费核销.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\工单 (1).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\工单.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\工单信息.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\时间.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\条码 (1).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\条码.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\次品1 (1).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\次品1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\次品报表.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\注销.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\用户 管理.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\登录 (1).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\登录 (2).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\登录.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\箱子.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\裕同包装.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\警告.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\质检 (1).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\质检 (2).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\质检 (3).png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\质检.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\进度.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\选择.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\错误.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="FreeSql" Version="3.5.213" />
<PackageReference Include="FreeSql.Provider.SqlServer" Version="3.5.213" />
<PackageReference Include="HslCommunication" Version="12.3.0" />
<PackageReference Include="NLog" Version="6.0.3" />
<PackageReference Include="NLog.Config" Version="4.7.15" />
<PackageReference Include="ReaLTaiizor" Version="3.8.1.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FATrace.Com\FATrace.Com.csproj" />
<ProjectReference Include="..\FATrace.HKNetLib\FATrace.HKNetLib.csproj" />
<ProjectReference Include="..\FATrace.Model\FATrace.Model.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Data\" />
<Folder Include="Model\" />
<Folder Include="Services\" />
</ItemGroup>
<ItemGroup>
<None Include="NLog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,33 @@
using FATrace.Com;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.OEMApp
{
public class FSqlContext
{
private static readonly Lazy<IFreeSql> LazyFreeSql = new Lazy<IFreeSql>(() =>
{
var connectionString = ConfigHelper.GetRequiredConnectionString("connecting");
try
{
return new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.SqlServer, connectionString)
.UseAutoSyncStructure(false)
.Build();
}
catch (Exception ex)
{
throw new InvalidOperationException("初始化数据库连接失败,请检查连接字符串与数据库网络连通性。", ex);
}
});
/// <summary>
/// 获取单例数据库实例。
/// </summary>
public static IFreeSql FDb => LazyFreeSql.Value;
}
}

View File

@@ -1,39 +0,0 @@
namespace FATrace.OEMApp
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@@ -1,10 +0,0 @@
namespace FATrace.OEMApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

BIN
FATrace.OEMApp/Images/2.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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