I'm new to credential providers and I'm having a problem, I don't know exactly how to display the credentials for all users, right now the credentials are only displayed for the user with index 0, I'm following this example CSharpSampleProvider (FullProject) from https://github.com/djcho
I added a for to the code to generate a credential for each user that was in the system but the credential ended up showing in the last user when the loop finished executing, a new credential is not being created for each user and assigned to the user according to the Id , it's more like you're updating the information and you run the for until you get to the last user and the credential that exists has been available first to the user with index 0, then index 1, and so on.
int EnumerateCredentials()
{
Log.LogMethodCall();
int hr = HResultValues.E_UNEXPECTED;
if (_pCredProviderUserArray != null)
{
uint dwUserCount = 0;
_pCredProviderUserArray.GetCount(out dwUserCount);
if (dwUserCount > 0)
{
for (uint i = 0; i < dwUserCount; i++)
{
ICredentialProviderUser pCredUser;
hr = _pCredProviderUserArray.GetAt(i, out pCredUser);
if (hr >= 0)
{
_pCredential = new CSharpSampleCredential();
if (_pCredential != null)
{
hr = _pCredential.Initialize(_cpus, Field.s_rgCredProvFieldDescriptors, Field.s_rgFieldStatePairs, pCredUser);
if (hr < 0)
{
var intPtr = Marshal.GetIUnknownForObject(_pCredential);
Marshal.Release(intPtr);
_pCredential = null;
}
}
else
{
hr = HResultValues.E_OUTOFMEMORY;
}
{
var intPtr = Marshal.GetIUnknownForObject(pCredUser);
Marshal.Release(intPtr);
}
}
}
}
}
return hr;
}
I really appreciate the help, greetings.
Related
Hello I have a Blazor server side app, where a service is responsable to read cyclic data from a PLC control system. I am using a 3. party dll for reading the PLC values. The PLC values is are read in a second intervall for 30 seconds tottaly. The function is placed in a service.
In the service I am writing the read values in parallel to a log file with timestamp. I see that the values are logged correctly when they are generated, that means each second. (see code !!!!! part)
That means my function is working correct.
I am calling the function from my razor page and I want to visualise the PLC values live on my screen. But the PLC process values are updated in my screen after the function is completed totaly (after 30 seconds). That means not every second.
I think I need something like "StateHasChanged" in my service to rerender my page, but I don't know how to do this in a service.
My Razor page
#page "/PLC_Var"
#inject PLCService PLCService //
<button #onclick="Read_PLC_Var">Read</button>
#for (int i = 0; i <= 4; i++)
{
// The values are not updated after each second !!!
<td> #PLC_VAR_result[i]</td>
<br>
}
#code {
public async Task Read_PLC_Var()
{
DoCyclicReadingEx(Deltalogic.Return_Connect_PLC, 5000);
}
}
This is my function in my service (PLCService)
public Int32 DoCyclicReadingEx(Int32 connnr, Int32 timeout)
{
Int32 cycletime = 1000;
AGL4.DATA_RW40[] rwfield = new AGL4.DATA_RW40[1];
rwfield[0] = new AGL4.DATA_RW40();
rwfield[0].BitNr = 0;
rwfield[0].DBNr = 1;
rwfield[0].Offset = 0;
rwfield[0].OpAnz = 1;
rwfield[0].OpArea = AGL4.AREA_FLAG;
rwfield[0].OpType = AGL4.TYP_DWORD;
rwfield[0].Result = 0;
rwfield[0].Value = new UInt32[rwfield[0].OpAnz];
rwfield[0].Value[0] = 1;
Int32 handle = 0;
Int32 cycles = 5;
String errormsg = "";
Boolean start = false;
// When start is set to "true" StartCyclicRead will be called automatically
Int32 result = AGL4.InitCyclicReadEx(connnr, cycletime, start, ref rwfield, out handle, timeout);
if (result == AGL4.AGL40_SUCCESS)
{
// Only required if start = false at InitCyclicReadEx
result = AGL4.StartCyclicRead(connnr, handle, timeout);
if (result == AGL4.AGL40_SUCCESS)
{
for (Int32 i = 0; i < cycles; i++)
{
result = AGL4.GetCyclicReadEx(connnr, ref rwfield, handle, timeout);
if (result == AGL4.AGL40_SUCCESS)
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// The PLC_VAR_result values are updated in my screen after the function is executed completely (after 30 seconds)
PLC_VAR_result[i] = rwfield[0].Value[0];
// But the values are written to the log file just when they are read
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
using (StreamWriter sw = File.AppendText(log_file))
{
sw.WriteLine("PLC VAR_"+i+ " "+PLC_VAR_result[i] + "" + Convert.ToString(DateTime.Now));
}
}
else
{
// Error happened
AGL4.GetErrorMsg(result, out errormsg);
}
}
result = AGL4.StopCyclicRead(connnr, handle, timeout);
result = AGL4.ExitCyclicRead(connnr, handle, timeout);
}
else
{
// Error happened
AGL4.GetErrorMsg(result, out errormsg);
}
}
else
{
// Error happened
AGL4.GetErrorMsg(result, out errormsg);
}
return result;
}
I have a ZKTeco K80 device, what I can get now are the logs data ( DateTime, InOut, VerifyMethod..)
private void btnPullData_Click(object sender, EventArgs e)
{
try
{
ShowStatusBar(string.Empty, true);
ICollection<MachineInfo> lstMachineInfo = manipulator.GetLogData(objZkeeper, int.Parse(tbxMachineNumber.Text.Trim()));
if (lstMachineInfo != null && lstMachineInfo.Count > 0)
{
BindToGridView(lstMachineInfo);
ShowStatusBar(lstMachineInfo.Count + " records found !!", true);
}
else
DisplayListOutput("No records found");
}
catch (Exception ex)
{
DisplayListOutput(ex.Message);
}
}
public ICollection<MachineInfo> GetLogData(ZkemClient objZkeeper, int machineNumber)
{
string dwEnrollNumber1 = "";
int dwVerifyMode = 0;
int dwInOutMode = 0;
int dwYear = 0;
int dwMonth = 0;
int dwDay = 0;
int dwHour = 0;
int dwMinute = 0;
int dwSecond = 0;
int dwWorkCode = 0;
ICollection<MachineInfo> lstEnrollData = new List<MachineInfo>();
objZkeeper.ReadAllGLogData(machineNumber);
while (objZkeeper.SSR_GetGeneralLogData(machineNumber, out dwEnrollNumber1, out dwVerifyMode, out dwInOutMode, out dwYear, out dwMonth, out dwDay, out dwHour, out dwMinute, out dwSecond, ref dwWorkCode))
{
string inputDate = new DateTime(dwYear, dwMonth, dwDay, dwHour, dwMinute, dwSecond).ToString();
MachineInfo objInfo = new MachineInfo();
objInfo.MachineNumber = machineNumber;
objInfo.IndRegID = int.Parse(dwEnrollNumber1);
objInfo.DateTimeRecord = inputDate;
objInfo.dwInOutMode = dwInOutMode;
lstEnrollData.Add(objInfo);
}
return lstEnrollData;
}
Ref : Csharp-ZKTeco-Biometric-Device-Getting-Started
I'm searching for a method to get the absent days , how can I configure the device to count all the absent days starting from a week and except Saturday and Sunday or this is not related to the device and should I configure it myself using SQL tables??
Well, you can not get the absent days from the biometric device. It must be part of your application logic. You have to read all the attendance data from the biometric device, and consider all the missing dates as absent days.
I'm writing a program that uses a fingerprint reader. I have stored the fingerprint data in an array [arr]. Unfortunately, only the first value is read i.e [0]. So only one finger is detected and the rest are ignored but if I place a specific number in the array e.g 2. It works fine for that value alone:
Here's my code:
for (int x = 0; x < (arr.Length - 1); x++)
{
byte[] fpbyte = GetStringToBytes(arr[x]);
Stream stream = new MemoryStream(fpbyte);
Data.Templates[x] = new DPFP.Template(stream);
}
foreach (DPFP.Template template in Data.Templates)
{
// Get template from storage.
if (template != null)
{
// Compare feature set with particular template.
ver.Verify(FeatureSet, template, ref res);
Data.IsFeatureSetMatched = res.Verified;
Data.FalseAcceptRate = res.FARAchieved;
if (res.Verified)
MessageBox.Show("Yes");
break; // success
}
}
if (!res.Verified)
Status = DPFP.Gui.EventHandlerStatus.Failure;
MessageBox.Show("No");
Data.Update();
You unconditionally break from your loop, whether verified or not.
Your code should read :
if (res.Verified) {
MessageBox.Show("Yes");
break; // success
}
This is a good example why good coding practice suggests always having the brackets, even for a one line conditional effect, as the error would have been much more obvious.
Similarly you should have written
if (!res.Verified) {
Status = DPFP.Gui.EventHandlerStatus.Failure;
MessageBox.Show("No");
}
at the end of your snippet.
Thanks to Dragonthoughts, I made the following changes and the code works just fine:
for (int x = 0; x < (arr.Length - 1); x++)
{
byte[] fpbyte = GetStringToBytes(arr[x]);
using (Stream stream = new MemoryStream(fpbyte))
{
Data.Templates[x] = new DPFP.Template(stream);
// Get template from storage.
if (Data.Templates[x] != null)
{
// Compare feature set with particular template.
ver.Verify(FeatureSet, Data.Templates[x], ref res);
Data.IsFeatureSetMatched = res.Verified;
Data.FalseAcceptRate = res.FARAchieved;
if (res.Verified)
{
status.Text = "Verified";
break; // success
}
}
}
}
if (!res.Verified)
{
Status = DPFP.Gui.EventHandlerStatus.Failure;
status.Text = "Unverified";
}
Data.Update();
I'm using a SOAP Web Reference in a C# service for this.
If I call (in my SForceManager class) CreateSForceCase() multiple times within the same connection, I receive the same exact CaseNumber until the connection times out and is reconnected (or if i create a new connection for each).
The problem with this, is that I'm needing to insert upto say 5000 cases, and at 3 seconds per case that will take ~4 hours to insert all 5000 cases. Is there a way to let the API know that I want a brand new case each and every time I create one without logging out?
Here's my Manager code:
public String CreateSForceCase(Case sfCase, out string errMsg)
{
//Verify that we are already authenticated, if not
//call the login function to do so
if (!isConnected()) login();
errMsg = "";
sObject[] objCases = new sObject[1];
for (int j = 0; j < objCases.Length; j++)
objCases[j] = sfCase;
//create the object(s) by sending the array to the web service
SaveResult[] sr = _Binding.create(objCases);
for (int j = 0; j < sr.Length; j++)
{
if (sr[j].success)
{
//save the account ids in a class array
if (_cases == null)
_cases = new string[] { sr[j].id };
else
{
string[] tempcases = null;
tempcases = new string[_cases.Length + 1];
for (int i = 0; i < _cases.Length; i++)
tempcases[i] = _cases[i];
tempcases[_cases.Length] = sr[j].id;
_cases = tempcases;
}
return getCaseNumberFromCaseId(_cases[0]);
}
else
{
//there were errors during the create call, go through the errors
//array and write them to the screen
for (int i = 0; i < sr[j].errors.Length; i++)
{
//get the next error
Error err = sr[j].errors[i];
errMsg = err.message;
}
}
}
return string.Empty;
}
and the call within for getting the case # is:
public String getCaseNumberFromCaseId(string caseId)
{
if (!isConnected()) login();
sObject[] ret = _Binding.retrieve("CaseNumber", "Case", new string[] { caseId });
if (ret != null)
return ((Case)ret[0]).CaseNumber;
else
return string.Empty;
}
so something like:
SForceManager manager = new SForceManager();
string case1 = manager.CreateSForceCase(...);
string case2 = manager.CreateSForceCase(...);
string case3 = manager.CreateSForceCase(...);
then case1 == case2 == case3
but if i do:
SForceManager manager = new SForceManager();
string case1 = manager.CreateSForceCase(...);
SForceManager manager = new SForceManager();
string case2 = manager.CreateSForceCase(...);
SForceManager manager = new SForceManager();
string case3 = manager.CreateSForceCase(...);
then case1 != case2 != case3 like i expect
So I figured out a way to perform this.
The idea is to actually take in a list of "Case objects" and send those all at once, then return a string array of case id's.
I'm not sure what would happen if I try opening too many such that the timeout period may pass in the middle of processing (so it could be improved yet):
public String[] CreateSForceCases(Case[] sfCase, out List<string> errMsg)
{
String[] toRet = new string[sfCase.Length];
errMsg = new List<string>();
//Verify that we are already authenticated, if not
//call the login function to do so
if (!isConnected()) login();
//errMsg = "";
sObject[] objCases = new sObject[sfCase.Length];
for (int j = 0; j < objCases.Length; j++)
objCases[j] = sfCase[j];
//create the object(s) by sending the array to the web service
SaveResult[] sr = _Binding.create(objCases);
for (int j = 0; j < sr.Length; j++)
{
if (sr[j].success)
{
//save the account ids in a class array
if (_cases == null)
_cases = new string[] { sr[j].id };
else
{
string[] tempcases = null;
tempcases = new string[_cases.Length + 1];
for (int i = 0; i < _cases.Length; i++)
tempcases[i] = _cases[i];
tempcases[_cases.Length] = sr[j].id;
_cases = tempcases;
}
toRet[j] = getCaseNumberFromCaseId(_cases[j]);
}
else
{
//there were errors during the create call, go through the errors
//array and write them to the screen
for (int i = 0; i < sr[j].errors.Length; i++)
{
//get the next error
Error err = sr[j].errors[i];
errMsg.Add(err.message);
}
}
}
return toRet;
//return null;
}
There was also a problem in the error handling process in the original, however this one fixes that. I figured I would post my solution in case anyone else has come across this issue...I was not able to find any answer to my question anywhere.
if I have more than one camera attached to my PC ... I want to know the best available resolutions for a specific camera ...
for example some cameras are HD or FullHD (1,280×720 pixels (720p) or 1,920×1,080 pixels (1080i/1080p)) or the most common are web cameras....
I want to know at least the best video mode that the camera work properly...(the mode that the camera made to work with)
my work is on WPF using C# (I am using Directshow)
thanks in advance
This is a code that I wrote, its working perfectly for me
public static List<Point> GetAllAvailableResolution(DsDevice vidDev)
{
try
{
int hr;
int max = 0;
int bitCount = 0;
IBaseFilter sourceFilter = null;
var m_FilterGraph2 = new FilterGraph() as IFilterGraph2;
hr = m_FilterGraph2.AddSourceFilterForMoniker(vidDev.Mon, null, vidDev.Name, out sourceFilter);
var pRaw2 = DsFindPin.ByCategory(sourceFilter, PinCategory.Capture, 0);
var AvailableResolutions = new List<Point>();
VideoInfoHeader v = new VideoInfoHeader();
IEnumMediaTypes mediaTypeEnum;
hr = pRaw2.EnumMediaTypes(out mediaTypeEnum);
AMMediaType[] mediaTypes = new AMMediaType[1];
IntPtr fetched = IntPtr.Zero;
hr = mediaTypeEnum.Next(1, mediaTypes, fetched);
while (fetched != null && mediaTypes[0] != null)
{
Marshal.PtrToStructure(mediaTypes[0].formatPtr, v);
if (v.BmiHeader.Size != 0 && v.BmiHeader.BitCount != 0)
{
if (v.BmiHeader.BitCount > bitCount)
{
AvailableResolutions.Clear();
max = 0;
bitCount = v.BmiHeader.BitCount;
}
AvailableResolutions.Add(new Point(v.BmiHeader.Width, v.BmiHeader.Height));
if (v.BmiHeader.Width > max || v.BmiHeader.Height > max)
max = (Math.Max(v.BmiHeader.Width, v.BmiHeader.Height));
}
hr = mediaTypeEnum.Next(1, mediaTypes, fetched);
}
return AvailableResolutions;
}
catch (Exception ex)
{
Log(ex);
return new List<Point>();
}
}
(E.g. this can be added to VideoCaptureElement in WPF-MediaKit)
i use this to get max frame size, just change to suit your needs ;)
private Point GetMaxFrameSize(IPin pStill)
{
VideoInfoHeader v;
IAMStreamConfig videoStreamConfig = pStill as IAMStreamConfig;
int iCount = 0, iSize = 0;
videoStreamConfig.GetNumberOfCapabilities(out iCount, out iSize);
IntPtr TaskMemPointer = Marshal.AllocCoTaskMem(iSize);
int iMaxHeight = 0;
int iMaxWidth = 0;
for (int iFormat = 0; iFormat < iCount; iFormat++)
{
AMMediaType pmtConfig = null;
IntPtr ptr = IntPtr.Zero;
videoStreamConfig.GetStreamCaps(iFormat, out pmtConfig, TaskMemPointer);
v = (VideoInfoHeader)Marshal.PtrToStructure(pmtConfig.formatPtr, typeof(VideoInfoHeader));
if (v.BmiHeader.Width > iMaxWidth)
{
iMaxWidth = v.BmiHeader.Width;
iMaxHeight = v.BmiHeader.Height;
}
DsUtils.FreeAMMediaType(pmtConfig);
}
Marshal.FreeCoTaskMem(TaskMemPointer);
return new Point(iMaxWidth, iMaxHeight);
}
/// <summary>
/// Free the nested structures and release any
/// COM objects within an AMMediaType struct.
/// </summary>
public static void FreeAMMediaType(AMMediaType mediaType)
{
if (mediaType != null)
{
if (mediaType.formatSize != 0)
{
Marshal.FreeCoTaskMem(mediaType.formatPtr);
mediaType.formatSize = 0;
mediaType.formatPtr = IntPtr.Zero;
}
if (mediaType.unkPtr != IntPtr.Zero)
{
Marshal.Release(mediaType.unkPtr);
mediaType.unkPtr = IntPtr.Zero;
}
}
}
According to this webpage:
http://www.e-consystems.com/blog/camera/?p=651, you should use this call for getting the capabilities of this device:
g_DShowCaptureGraph.GetNumberOfCapabilities(nStream, &iCount, &iSize);
g_DShowCaptureGraph.GetStreamCaps(nStream,iFormat, &pmtConfig, (BYTE*)&scc);
They are C++, however.