Time  Attendance System
Time Attendance System

Reputation: 319

connect biometric device using c#?

I am trying to connect biometric device in web application. I works fine in windows application but in web it throw error.

Windows-form.cs:

int nPort = Convert.ToInt32(textPort.Text);
                        int nPassword = Convert.ToInt32(textPassword.Text);
                        string strIP = ipAddressControl1.IPAddress.ToString();
                        bRet = axFP_CLOCK.SetIPAddress(ref strIP, nPort, nPassword);
                        if(!bRet)
                        {
                            return;
                        }

Form Designer:

((System.ComponentModel.ISupportInitialize)(this.axFP_CLOCK)).BeginInit();
       this.axFP_CLOCK.Enabled = true;
            this.axFP_CLOCK.Location = new System.Drawing.Point(476, 382);
            this.axFP_CLOCK.Name = "axFP_CLOCK";
            this.axFP_CLOCK.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axFP_CLOCK.OcxState")));
            this.axFP_CLOCK.Size = new System.Drawing.Size(100, 50);
            this.axFP_CLOCK.TabIndex = 11;
            this.axFP_CLOCK.Visible = false;
    ((System.ComponentModel.ISupportInitialize)(this.axFP_CLOCK)).EndInit();

Likewise i try to connect in web application but it shows error: Webform1:

 public AxFP_CLOCKLib.AxFP_CLOCK axFP_CLOCK;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                bool bRet;
                string ip= "192.168.1.109";
                int nPort = Convert.ToInt32(5005);
                int nPassword = Convert.ToInt32(0);
                axFP_CLOCK = new AxFP_CLOCKLib.AxFP_CLOCK();
                bRet = axFP_CLOCK.SetIPAddress(ref ip, nPort, nPassword);
                if (!bRet)
                {
                    Response.Write("success");
                }

                else
                {
                    Response.Write("failure");
                }
            }
        }

It throw error as

ActiveX control '87733ee1-d095-442b-a200-6de90c5c8318' cannot be instantiated because the current thread is not in a single-threaded apartment.

Dll:

 public virtual bool SetIPAddress(ref string lpszIPAddress, int dwPortNumber, int dwPassWord)
    {
      if (this.ocx == null)
        throw new AxHost.InvalidActiveXStateException(nameof (SetIPAddress), AxHost.ActiveXInvokeKind.MethodInvoke);
      return this.ocx.SetIPAddress(ref lpszIPAddress, dwPortNumber, dwPassWord);
    }

Anyone could help me to rectify this error?

Upvotes: 0

Views: 938

Answers (2)

Mayank Pathak
Mayank Pathak

Reputation: 3681

You should run your method in a Thread.

Something like below.

var thr = new Thread(new AxFP_CLOCKLib.AxFP_CLOCK().SetIPAddress(ref ip, nPort, nPassword));
    thr.SetApartmentState(ApartmentState.STA);
    thr.Start();

I am not very sure about it but annotating your Page_Load should help as well.

  [STAThread]
protected void Page_Load(object sender, EventArgs e)
{
 // Code Goes here
}

Upvotes: 1

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

The error message indicates that ActiveX control you're using requires STA (Single Threaded Apartment) state. You can set the apartment state of corresponding thread by using Thread.SetApartmentState() method.

Assume you're already created a Thread to wrap ActiveX instance like this:

var thread = new Thread(() => {
    // other running processes inside thread
    Application.Run();
});

Then you should specify apartment state of that thread to STA (ApartmentState.STA) before using Start():

thread.SetApartmentState(ApartmentState.STA);
thread.Start();

The reason behind this issue is most of .NET background threads (or worker APIs) will create new threads as multithreaded apartment state (MTA), while ActiveX control threads usually instantiated in STA mode.

Related issue:

Single-threaded apartment - cannot instantiate ActiveX control

Upvotes: 1

Related Questions