Table des matières
  1.开发环境:
  2.新建项目:
Maison développement back-end Tutoriel C#.Net Comment résoudre le problème de l'appel du SDK Hikvision lors de la création de contrôles ActiveX en C#

Comment résoudre le problème de l'appel du SDK Hikvision lors de la création de contrôles ActiveX en C#

Sep 06, 2017 pm 01:46 PM
.net

  这个事情就是一个坑,耽误了两周时间,之前并没有做过ActiveX这玩意,现在客户需求如此,只能说是在网上看着教程做了。

  事情是这样的,有一台海康威视的摄像头,客户需要一个ActiveX控件嵌入到网页中,通过点击按钮开始录制和结束录制来进行视频的录制和保存,关于海康摄像头的二次开发在此就不多说了,可以参考SDK中的说明。

  直接上流程:

  1.开发环境:

    VS2010,这个打包方便,之前用VS2013打包的,总是调用不了,不知道原因是什么;SDK是32位的,用64位的在Winform中可以正常使用,在网页中使用控件时会报错。

  2.新建项目:

    新建一个类库项目,如下:

 

    右键点击项目,添加“用户控件”,如下:

    界面拖控件,如下:

    控件代码如下,其中Guid是“工具”->“创建GUID”自动生成的,#region->#endregion折叠部分是实现的IObjectSafety接口

using System;

namespace VideoHelper
{
    [System.Security.SecuritySafeCritical]
    public class Videos
    {
        private bool m_initSDK = false;
        /// <summary>
        /// 正在录制
        /// </summary>
        private bool m_Record = false;
        private uint LastErr = 0;
        private Int32 m_RealHandle = -1;
        private Int32 m_lUserID = -1;
        public IntPtr handle { get; set; }
        public bool Initialize(string ip = "192.168.1.64", int port = 8000, string username = "admin", string password = "8910jqk#")
        {
            try
            {
                m_initSDK = CHCNetSDK.NET_DVR_Init();
                if (m_initSDK)
                {
                    CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);
                    //设备参数结构体
                    CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
                    //注册设备
                    m_lUserID = CHCNetSDK.NET_DVR_Login_V30(ip, port, username, password, ref DeviceInfo);
                    return m_lUserID >= 0;
                }
                return false;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("Initialize:" + ex.Message);
                return false;
            }
        }

        public bool Start(IntPtr handle, string filename)
        {
            try
            {
                CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();
                lpPreviewInfo.lChannel = 1;
                lpPreviewInfo.dwLinkMode = 0;
                lpPreviewInfo.dwStreamType = 0;
                lpPreviewInfo.bBlocked = true;
                lpPreviewInfo.dwDisplayBufNum = 15;
                lpPreviewInfo.hPlayWnd = handle;
                IntPtr pUser = IntPtr.Zero;//new IntPtr();         
                //获取实时视频流
                m_RealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null, pUser);
                if (m_Record == false)
                {
                    CHCNetSDK.NET_DVR_MakeKeyFrame(m_lUserID, 1);
                    if (!CHCNetSDK.NET_DVR_SaveRealData(m_RealHandle, filename))
                    {
                        LastErr = CHCNetSDK.NET_DVR_GetLastError();
                        return false;
                    }
                    else
                    {
                        m_Record = true;
                        return true;
                    }
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        public bool End()
        {
            if (m_Record)
            {
                if (!CHCNetSDK.NET_DVR_StopSaveRealData(m_RealHandle))
                {
                    LastErr = CHCNetSDK.NET_DVR_GetLastError();
                    return false;
                }
                m_Record = false;
                m_RealHandle = -1;
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Dispose()
        {
            try
            {
                if (m_lUserID >= 0)
                {
                    CHCNetSDK.NET_DVR_Logout_V30(m_lUserID);
                    m_lUserID = -1;
                }

                if (m_RealHandle >= 0)
                {
                    CHCNetSDK.NET_DVR_StopRealPlay(m_RealHandle);
                    m_RealHandle = -1;
                }

                CHCNetSDK.NET_DVR_Cleanup();
            }
            catch
            { }
        }
    }
}

录制视频操作类
Copier après la connexion

录制视频操作类

using System;
using System.Runtime.InteropServices;

namespace VideoHelper
{
    [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        [PreserveSig]
        int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);

        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
    }
}

接口代码
Copier après la connexion
using System;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace VideoHelper
{
    [System.Security.SecuritySafeCritical]
    [Guid("79629620-3C0C-4D47-B93B-2D36AEF8EF31")]
    public partial class VideoControl : UserControl,IObjectSafety
    {
        public VideoControl()
        {
            InitializeComponent();
        }
        string videopath = Environment.CurrentDirectory;
        Videos video;
        IntPtr handle;
        private void btnLogin_Click(object sender, EventArgs e)
        {
            if (btnLogin.Text == "登录")
            {
                try
                {
                    if (string.IsNullOrWhiteSpace(this.txtIP.Text))
                    {
                        MessageBox.Show("IP地址不能为空!");
                        return;
                    }
                    if (string.IsNullOrWhiteSpace(this.txtUserID.Text))
                    {
                        MessageBox.Show("用户名不能为空!");
                        return;
                    }
                    if (string.IsNullOrWhiteSpace(this.txtPwd.Text))
                    {
                        MessageBox.Show("密码不能为空!");
                        return;
                    }
                    video = new Videos();
                    if (video.Initialize(this.txtIP.Text, Convert.ToInt32(this.numericUpDown1.Value), this.txtUserID.Text, this.txtPwd.Text))
                    {
                        this.btnLogin.Text = "注销";
                        MessageBox.Show("登录成功!");
                        this.btnStart.Enabled = true;
                        this.btnSave.Enabled = true;
                    }
                    else
                    {
                        MessageBox.Show("登录失败!");
                    }
                }
                catch (Exception ee)
                {
                    MessageBox.Show("登录异常:" + ee.Message);
                }
            }
            else if (btnLogin.Text == "注销")
            {
                try
                {
                    video.Dispose();
                    this.btnLogin.Text = "登录";
                    this.btnStart.Enabled = false;
                    this.btnSave.Enabled = false;
                }
                catch (Exception ee)
                {
                    MessageBox.Show("注销异常:" + ee.Message);
                }
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                string filename = txtFile.Text.Trim();
                if (filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0 || string.IsNullOrWhiteSpace(filename))
                {
                    MessageBox.Show("文件名含有非法字符或空格,请重新输入");
                    txtFile.Focus();
                    return;
                }
                video.Start(handle, filename + comboBox1.SelectedItem.ToString());
                this.btnStart.Enabled = false;
                this.btnSave.Enabled = true;
            }
            catch (Exception ee)
            {
                MessageBox.Show("异常:" + ee.Message);
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                if (video.End())
                {
                    MessageBox.Show("视频已保存!");
                    this.btnStart.Enabled = true;
                    this.btnSave.Enabled = false;
                }
                else
                {
                    MessageBox.Show("保存失败!");
                    this.btnStart.Enabled = true;
                    this.btnSave.Enabled = true;
                }
            }
            catch (Exception ee)
            { MessageBox.Show("异常:" + ee.Message); }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(videopath);

            }
            catch
            { }
        }

        private void VideoControl_Load(object sender, EventArgs e)
        {
            this.comboBox1.SelectedItem = ".mp4";
            this.handle = pictureBox1.Handle;
            this.btnStart.Enabled = false;
            this.btnSave.Enabled = false;
        }

        #region IObjectSafety 成员
        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";

        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);

        private bool _fSafeForScripting = true;
        private bool _fSafeForInitializing = true;

        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            int Rslt = E_FAIL;
            string strGUID = riid.ToString("B");
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
                        Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        #endregion
    }
}

控件代码
Copier après la connexion
namespace VideoHelper
{
    partial class VideoControl
    {
        /// <summary> 
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region 组件设计器生成的代码

        /// <summary> 
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.comboBox1 = new System.Windows.Forms.ComboBox();
            this.label4 = new System.Windows.Forms.Label();
            this.txtFile = new System.Windows.Forms.TextBox();
            this.btnSave = new System.Windows.Forms.Button();
            this.btnStart = new System.Windows.Forms.Button();
            this.btnLogin = new System.Windows.Forms.Button();
            this.label3 = new System.Windows.Forms.Label();
            this.txtPwd = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.txtUserID = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
            this.IP = new System.Windows.Forms.Label();
            this.txtIP = new System.Windows.Forms.TextBox();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Cursor = System.Windows.Forms.Cursors.Hand;
            this.button1.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.button1.Location = new System.Drawing.Point(377, 360);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(138, 22);
            this.button1.TabIndex = 58;
            this.button1.Text = "打开视频存放位置";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // comboBox1
            // 
            this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.comboBox1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.comboBox1.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.Items.AddRange(new object[] {
            ".mp4",
            ".avi",
            ".wmv",
            ".3gp",
            ".flv"});
            this.comboBox1.Location = new System.Drawing.Point(303, 361);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(55, 25);
            this.comboBox1.TabIndex = 57;
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.label4.Location = new System.Drawing.Point(14, 360);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(116, 17);
            this.label4.TabIndex = 56;
            this.label4.Text = "请输入视频文件名:";
            // 
            // txtFile
            // 
            this.txtFile.Location = new System.Drawing.Point(136, 360);
            this.txtFile.Name = "txtFile";
            this.txtFile.Size = new System.Drawing.Size(161, 21);
            this.txtFile.TabIndex = 55;
            // 
            // btnSave
            // 
            this.btnSave.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnSave.Font = new System.Drawing.Font("微软雅黑", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.btnSave.Location = new System.Drawing.Point(490, 298);
            this.btnSave.Name = "btnSave";
            this.btnSave.Size = new System.Drawing.Size(57, 45);
            this.btnSave.TabIndex = 54;
            this.btnSave.Text = "保存";
            this.btnSave.UseVisualStyleBackColor = true;
            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
            // 
            // btnStart
            // 
            this.btnStart.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnStart.Font = new System.Drawing.Font("微软雅黑", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.btnStart.Location = new System.Drawing.Point(421, 298);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(57, 45);
            this.btnStart.TabIndex = 53;
            this.btnStart.Text = "录制";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // btnLogin
            // 
            this.btnLogin.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnLogin.Font = new System.Drawing.Font("微软雅黑", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.btnLogin.Location = new System.Drawing.Point(352, 298);
            this.btnLogin.Name = "btnLogin";
            this.btnLogin.Size = new System.Drawing.Size(57, 45);
            this.btnLogin.TabIndex = 52;
            this.btnLogin.Text = "登录";
            this.btnLogin.UseVisualStyleBackColor = true;
            this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.label3.Location = new System.Drawing.Point(172, 325);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(44, 17);
            this.label3.TabIndex = 51;
            this.label3.Text = "密码:";
            // 
            // txtPwd
            // 
            this.txtPwd.Location = new System.Drawing.Point(221, 322);
            this.txtPwd.Name = "txtPwd";
            this.txtPwd.PasswordChar = &#39;*&#39;;
            this.txtPwd.Size = new System.Drawing.Size(115, 21);
            this.txtPwd.TabIndex = 50;
            this.txtPwd.Text = "8910jqk#";
            this.txtPwd.UseSystemPasswordChar = true;
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.label2.Location = new System.Drawing.Point(8, 322);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(44, 17);
            this.label2.TabIndex = 49;
            this.label2.Text = "用户名";
            // 
            // txtUserID
            // 
            this.txtUserID.Location = new System.Drawing.Point(66, 322);
            this.txtUserID.Name = "txtUserID";
            this.txtUserID.Size = new System.Drawing.Size(100, 21);
            this.txtUserID.TabIndex = 48;
            this.txtUserID.Text = "admin";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.label1.Location = new System.Drawing.Point(172, 295);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(44, 17);
            this.label1.TabIndex = 47;
            this.label1.Text = "端口:";
            // 
            // numericUpDown1
            // 
            this.numericUpDown1.Location = new System.Drawing.Point(222, 295);
            this.numericUpDown1.Maximum = new decimal(new int[] {
            65535,
            0,
            0,
            0});
            this.numericUpDown1.Minimum = new decimal(new int[] {
            1,
            0,
            0,
            0});
            this.numericUpDown1.Name = "numericUpDown1";
            this.numericUpDown1.Size = new System.Drawing.Size(114, 21);
            this.numericUpDown1.TabIndex = 46;
            this.numericUpDown1.Value = new decimal(new int[] {
            8000,
            0,
            0,
            0});
            // 
            // IP
            // 
            this.IP.AutoSize = true;
            this.IP.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.IP.Location = new System.Drawing.Point(20, 295);
            this.IP.Name = "IP";
            this.IP.Size = new System.Drawing.Size(19, 17);
            this.IP.TabIndex = 45;
            this.IP.Text = "IP";
            // 
            // txtIP
            // 
            this.txtIP.Location = new System.Drawing.Point(66, 295);
            this.txtIP.Name = "txtIP";
            this.txtIP.Size = new System.Drawing.Size(100, 21);
            this.txtIP.TabIndex = 44;
            this.txtIP.Text = "192.168.1.64";
            // 
            // pictureBox1
            // 
            this.pictureBox1.Location = new System.Drawing.Point(5, 5);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(542, 269);
            this.pictureBox1.TabIndex = 43;
            this.pictureBox1.TabStop = false;
            // 
            // VideoControl
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.button1);
            this.Controls.Add(this.comboBox1);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.txtFile);
            this.Controls.Add(this.btnSave);
            this.Controls.Add(this.btnStart);
            this.Controls.Add(this.btnLogin);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.txtPwd);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.txtUserID);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.numericUpDown1);
            this.Controls.Add(this.IP);
            this.Controls.Add(this.txtIP);
            this.Controls.Add(this.pictureBox1);
            this.Name = "VideoControl";
            this.Size = new System.Drawing.Size(556, 398);
            this.Load += new System.EventHandler(this.VideoControl_Load);
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.ComboBox comboBox1;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox txtFile;
        private System.Windows.Forms.Button btnSave;
        private System.Windows.Forms.Button btnStart;
        private System.Windows.Forms.Button btnLogin;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.TextBox txtPwd;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox txtUserID;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.NumericUpDown numericUpDown1;
        private System.Windows.Forms.Label IP;
        private System.Windows.Forms.TextBox txtIP;
        private System.Windows.Forms.PictureBox pictureBox1;
    }
}

控件设计器代码
Copier après la connexion

控件设计器代码

    至此,此项目结束。

    右键点击解决方案,添加新项目,如下,至于为什么建立两个项目,我一会儿在下面解释,

    在HkHelper项目中添加类CHCNetSDK.cs,此类是海康提供的,可以在官网找到

    接下来,最重要的,项目属性设置如下,两个项目都要设置:

    至此,自定义控件已经完成,接下来就是打包,新建一个安装项目:

    右键点击安装项目,“添加”->“项目输出”,并选择自定义控件的项目,然后确定

    然后添加海康提供的SDK的库文件文件夹下的所有文件和文件夹到项目中,如下:

    然后生成项目,会生成setup.exe和SetupVideo.msi两个文件,然后用打包文件,把这两个文件打包称cab文件就OK了

打包文件一共三个cabarc.exe、build.bat、install.inf

build.bat文件:


"cabarc.exe"  n VideoSetup.cab SetupVideo.msi install.inf
Copier après la connexion

install.inf文件:


[version]
signature="$CHICAGO$"AdvancedINF=2.0[Setup Hooks]
hook1=hook1

[hook1]
run=msiexec.exe /i "%EXTRACT_DIR%\SetupVideo.msi" /qn
Copier après la connexion

cabarc.exe是微软提供的工具

最后说一下为什么要分为两个项目去实现控件,那是因为如果在一个项目中的话,调用海康动态库的类CHCNetSDK.cs不能进行COM注册

 

 

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Quelles sont les perspectives d'emploi du C# ? Quelles sont les perspectives d'emploi du C# ? Oct 19, 2023 am 11:02 AM

Que vous soyez débutant ou professionnel expérimenté, la maîtrise du C# ouvrira la voie à votre carrière.

Partagez plusieurs frameworks de projets open source .NET liés à l'IA et au LLM Partagez plusieurs frameworks de projets open source .NET liés à l'IA et au LLM May 06, 2024 pm 04:43 PM

Le développement des technologies d’intelligence artificielle (IA) bat son plein aujourd’hui et elles ont montré un grand potentiel et une grande influence dans divers domaines. Aujourd'hui, Dayao partagera avec vous 4 cadres de projets liés au modèle d'IA open source .NET LLM, dans l'espoir de vous fournir une référence. https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.mdSemanticKernelSemanticKernel est un kit de développement logiciel (SDK) open source conçu pour intégrer de grands modèles de langage (LLM) tels qu'OpenAI, Azure

Technologie d'optimisation des performances .NET pour les développeurs Technologie d'optimisation des performances .NET pour les développeurs Sep 12, 2023 am 10:43 AM

Si vous êtes un développeur .NET, vous devez être conscient de l'importance d'optimiser les fonctionnalités et les performances pour fournir des logiciels de haute qualité. En utilisant de manière experte les ressources fournies et en réduisant les temps de chargement des sites Web, vous créez non seulement une expérience agréable pour vos utilisateurs, mais vous réduisez également les coûts d'infrastructure.

Différences de performances entre le framework Java et le framework .NET Différences de performances entre le framework Java et le framework .NET Jun 03, 2024 am 09:19 AM

En termes de traitement des requêtes à haute concurrence, .NETASP.NETCoreWebAPI fonctionne mieux que JavaSpringMVC. Les raisons incluent : la compilation précoce AOT, qui réduit le temps de démarrage, une gestion plus raffinée de la mémoire, où les développeurs sont responsables de l'allocation et de la libération de la mémoire des objets.

C # .NET des questions et réponses d'entrevue: améliorez votre expertise C # .NET des questions et réponses d'entrevue: améliorez votre expertise Apr 07, 2025 am 12:01 AM

C # .NET Les questions et réponses d'entrevue comprennent les connaissances de base, les concepts de base et l'utilisation avancée. 1) Connaissances de base: C # est un langage orienté objet développé par Microsoft et est principalement utilisé dans le framework .NET. 2) Concepts de base: la délégation et les événements permettent des méthodes de liaison dynamiques, et LINQ fournit des fonctions de requête puissantes. 3) Utilisation avancée: la programmation asynchrone améliore la réactivité et les arbres d'expression sont utilisés pour la construction de code dynamique.

Tutoriel avancé C # .NET: Ace votre prochain entretien de développeur senior Tutoriel avancé C # .NET: Ace votre prochain entretien de développeur senior Apr 08, 2025 am 12:06 AM

L'entrevue avec C # Developer Senior Developer nécessite de maîtriser les connaissances de base telles que la programmation asynchrone, la LINQ et les principes de travail internes des frameworks .NET. 1. La programmation asynchrone simplifie les opérations par asynchronisation et attend pour améliorer la réactivité de l'application. 2.Linq exploite des données dans le style SQL et fait attention aux performances. 3. La CLR du cadre net gère la mémoire et la collecte des ordures doit être utilisée avec prudence.

C # .NET: Explorer les concepts de base et les principes fondamentaux de la programmation C # .NET: Explorer les concepts de base et les principes fondamentaux de la programmation Apr 10, 2025 am 09:32 AM

C # est un langage de programmation moderne et orienté objet développé par Microsoft et dans le cadre du .NET Framework. 1.C # prend en charge la programmation orientée objet (POO), y compris l'encapsulation, l'héritage et le polymorphisme. 2. La programmation asynchrone en C # est implémentée via Async et attend des mots clés pour améliorer la réactivité des applications. 3. Utilisez LINQ pour traiter les collections de données concisement. 4. Les erreurs courantes incluent les exceptions de référence NULL et les exceptions indexes hors gamme. Les compétences de débogage comprennent l'utilisation d'un débogueur et une gestion des exceptions. 5. L'optimisation des performances comprend l'utilisation de StringBuilder et d'éviter l'emballage et le déballage inutiles.

C # code dans .NET: Explorer le processus de programmation C # code dans .NET: Explorer le processus de programmation Apr 12, 2025 am 12:02 AM

Le processus de programmation de C # dans .NET comprend les étapes suivantes: 1) l'écriture de code C #, 2) la compilation dans un langage intermédiaire (IL) et 3) l'exécution par .NET Runtime (CLR). Les avantages de C # dans .NET sont sa syntaxe moderne, son système de type puissant et son intégration serrée avec le Framework .NET, adapté à divers scénarios de développement des applications de bureau aux services Web.

See all articles