I am using ZKFinger SDK2.3.3.1 version and Device
Communication Protocol SDK(32Bit Ver6.2.4.1 -- DLL Version : zkemkeeper.dll - 6.2.4.1. I have a small USB fingerprint scanner. When I scan the fingerprint,
I get an array of bytes . I saved it to disc in a bitmap file and jpg both and the fingerprint looks quite good scanned. To set the fingerprint template to a user on the device, i decomporessed fingerprint image, and then call SetUserTmp Function of zkemkeeper.dll.
I am getting size error , (-3) in code.
How can i go further? What is my mistake?
Below is my code for transfering finger from USB device to BioMetric device
bool fullImage = false;
zkfpEng.SaveJPG("Myfirstfinger.jpg");
string strtmp, sRegTemplate;
object pTemplate;
sRegTemplate = zkfpEng.GetTemplateAsStringEx("9");
pTemplate = zkfpEng.DecodeTemplate1(sRegTemplate);
// Note: 10.0Template can not be compressed
zkfpEng.SetTemplateLen(ref pTemplate, 602);
zkfpEng.SaveTemplate("Myfirstfingerprint.tpl", pTemplate);
byte[] TmpData = new byte[700];
TmpData =ObjectToByteArray(pTemplate);
if (bIsConnected == false)
{
MessageBox.Show("Please connect the device first!", "Error");
return;
}
int idwFingerIndex = Convert.ToInt32(cbFingerIndex.Text.Trim());
int idwEnrollNumber = Convert.ToInt32(txtUserID.Text.Trim());
int iTmpLength = 0;
string sdwEnrollNumber = txtUserID.Text.Trim();
axCZKEM1.EnableDevice(iMachineNumber, false);
Cursor = Cursors.WaitCursor;
bool IsSetTmp = false;
IsSetTmp = axCZKEM1.SetUserTmp(iMachineNumber, idwEnrollNumber, idwFingerIndex, ref TmpData[0]);
int errCode = 0;
axCZKEM1.GetLastError(ref errCode);
MessageBox.Show(IsSetTmp.ToString() + " " + errCode.ToString());
if (IsSetTmp == true)
{
MessageBox.Show("User template set successfully!", "Success");
}
else
{
MessageBox.Show("User template not set successfully!", "Error");
}
i think you don't have to convert it to image file, just like Remin said.
here some example. i'm using xaf and mysql db
private void DownloadUserInformationAction_Execute(object sender, SimpleActionExecuteEventArgs e)
{
IObjectSpace os = Application.CreateObjectSpace();
Terminal terminal = (Terminal)View.SelectedObjects[0];
//create new czkemclass obj
CZKEMClass myCZKEMClass = new CZKEMClass();
//connecting the device
myCZKEMClass.Connect_Net(terminal.IPAddress, terminal.Port);
//Initialize variable for store temporary user information
int tMachineNo = 0;
string tEnrollNo = "";
string tName = "";
string tPassword = "";
int tPrivilage = 0;
bool tEnabled = false;
int tFingerIndex;
int tFlag = 0;
string tTemplateData = "";
int tTemplateLength = 0;
myCZKEMClass.EnableDevice(terminal.DeviceId, false);
myCZKEMClass.ReadAllUserID(terminal.DeviceId);
myCZKEMClass.ReadAllTemplate(terminal.DeviceId);
while (myCZKEMClass.SSR_GetAllUserInfo(tMachineNo, out tEnrollNo, out tName, out tPassword, out tPrivilage, out tEnabled))
{
for (tFingerIndex = 0; tFingerIndex < 10; tFingerIndex++)
{
if (myCZKEMClass.GetUserTmpExStr(tMachineNo, tEnrollNo, tFingerIndex, out tFlag, out tTemplateData, out tTemplateLength))
{
EmployeeBiometric employeeBiometric = new EmployeeBiometric(terminal.Session);
//employeeBiometric.EnrollNumber = tEnrollNo;
XPCollection<Employee> employees = new XPCollection<Employee>(terminal.Session);
employeeBiometric.Employee = employees.Where(emp => emp.EnrollNo == tEnrollNo).FirstOrDefault();//(emp => emp.Sequence.ToString() == tEnrollNo).FirstOrDefault();
employeeBiometric.UserName = tName;
employeeBiometric.Password = tPassword;
employeeBiometric.Privilege = (Privilege)Enum.ToObject(typeof(Privilege), tPrivilage);
employeeBiometric.Enabled = tEnabled;
employeeBiometric.FingerprintIndex = tFingerIndex;
employeeBiometric.FingerprintTemplate = tTemplateData;
employeeBiometric.TemplateLength = tTemplateLength;
terminal.Session.CommitTransaction();
}
}
}
myCZKEMClass.EnableDevice(terminal.DeviceId, true);
}
that's method for downloading the your fingerprint image from device to your apps.
and here you can upload it back to another device
private void UploadUserInformationAction_Execute(object sender, PopupWindowShowActionExecuteEventArgs e)
{
IObjectSpace os = Application.CreateObjectSpace();
EmployeeBiometric employeeBiometric = (EmployeeBiometric)View.SelectedObjects[0];
EmployeeBiometricParameter param = (EmployeeBiometricParameter)e.PopupWindowViewCurrentObject;
//create new czkemclass obj
CZKEMClass myCZKEMClass = new CZKEMClass();
//connecting the device
myCZKEMClass.Connect_Net(param.Terminal.IPAddress, param.Terminal.Port);
myCZKEMClass.EnableDevice(param.Terminal.DeviceId, false);
int myCount = View.SelectedObjects.Count;
//Set specific user to fingerprint device
for (int i = 1; i <= myCount; i++)
{
int tMachineNo = param.Terminal.DeviceId;
string tEnrollNo = employeeBiometric.Employee.EnrollNo;//Sequence.ToString();
string tName = employeeBiometric.UserName;
string tPassword = employeeBiometric.Password;
int tPrivilege = (int)employeeBiometric.Privilege;
bool tEnabled = employeeBiometric.Enabled;
int tFingerIndex = employeeBiometric.FingerprintIndex;
string tTmpData = employeeBiometric.FingerprintTemplate;
int tFlag = 1;
if (myCZKEMClass.SSR_SetUserInfo(tMachineNo, tEnrollNo, tName, tPassword, tPrivilege, tEnabled))
{
myCZKEMClass.SetUserTmpExStr(tMachineNo, tEnrollNo, tFingerIndex, tFlag, tTmpData);
}
}
myCZKEMClass.RefreshData(param.Terminal.DeviceId);
myCZKEMClass.EnableDevice(param.Terminal.DeviceId, true);
}
and this is my "Terminal" Class
public partial class Terminal : XPCustomObject
{
Guid fOid;
[Key(AutoGenerate = true), Browsable(false)]
public Guid Oid
{
get { return fOid; }
set { SetPropertyValue<Guid>("Oid", ref fOid, value); }
}
private Branch _Branch;
[RuleRequiredField("", DefaultContexts.Save, "Branch required")]
public Branch Branch
{
get
{
return _Branch;
}
set
{
SetPropertyValue("Branch", ref _Branch, value);
}
}
string fDescription;
[RuleUniqueValue("", DefaultContexts.Save, "The value was already registered within the system.", ResultType = ValidationResultType.Warning)]
[RuleRequiredField("", DefaultContexts.Save, "Description required")]
public string Description
{
get { return fDescription; }
set { SetPropertyValue<string>("Description", ref fDescription, value); }
}
string fIPAddress;
[Size(15)]
public string IPAddress
{
get { return fIPAddress; }
set { SetPropertyValue<string>("IPAddress", ref fIPAddress, value); }
}
private int _Port;
public int Port
{
get
{
return _Port;
}
set
{
SetPropertyValue("Port", ref _Port, value);
}
}
string fDeviceDescription;
public string DeviceDescription
{
get { return fDeviceDescription; }
set { SetPropertyValue<string>("DeviceDescription", ref fDeviceDescription, value); }
}
private int _DeviceId;
public int DeviceId
{
get
{
return _DeviceId;
}
set
{
SetPropertyValue("DeviceId", ref _DeviceId, value);
}
}
private bool _Disabled;
public bool Disabled
{
get
{
return _Disabled;
}
set
{
SetPropertyValue("Disabled", ref _Disabled, value);
}
}}
Read the FP as string and push the same string to the Biometric device without any compression or conversion.
Related
In perl there's a rather simple method of tying a data structure to a file, whether it be a string, hash(dictionary in C#) or a simple array/list.
I've cobbled together my own half-assed solution in C# but I was wondering if there's a more inbuilt way to achieve this functionality?
Edit in response to comment below--The question, directly: Is there an inbuilt way to "tie" a class/dictionary to a file so any changes in either is reflected in the other? (Without doing as I've done below)
(Tieing a dictionary means that any changes in the dictionary are immediately reflected/updated in the file and declaring a tied var loads the object from disk if it already exists; see PerlTie )
My pseudo-tie'd class is below:
#region options
private float _Opacity;
public float Opacity {
get {
return Opacity;
}
set {
_Opacity = value;
this.Save();
}
}
private Font _Font;
public Font Font {
get {
return _Font;
}
set {
_Font = value;
this.Save();
}
}
private Color _FontColor;
public Color FontColor {
get {
return _FontColor;
}
set {
_FontColor = value;
this.Save();
}
}
private Color _BGColor;
public Color BGColor {
get {
return _BGColor;
}
set {
_BGColor = value;
this.Save();
}
}
private Point _Location;
public Point Location {
get {
return _Location;
}
set {
_Location = value;
this.Save();
}
}
private Size _Size;
public Size Size {
get {
return _Size;
}
set {
_Size = value;
this.Save();
}
}
private ushort _HistoryLines;
public ushort HistoryLines {
get {
return _HistoryLines;
}
set {
_HistoryLines = value;
this.Save();
}
}
private ChatType _ChatModes;
public ChatType ChatModes {
get {
return _ChatModes;
}
set {
_ChatModes = value;
this.Save();
}
}
private bool _Debugging;
public bool Debugging {
get {
return _Debugging;
}
set {
_Debugging = value;
this.Save();
}
}
#endregion options
private FontConverter FontConvert;
private FileInfo SettingsFile;
private MLogConf() {
}
public MLogConf(string stateFile) {
FontConvert = new FontConverter();
try {
if (!Directory.Exists(Path.GetDirectoryName(stateFile)))
Directory.CreateDirectory(Path.GetDirectoryName(stateFile));
if (!File.Exists(stateFile)) {
FileStream fs = File.Create(stateFile);
fs.Close();
}
SettingsFile = new FileInfo(stateFile);
if (SettingsFile.Length == 0) {
this.SetDefaultOptions();
} else {
if (!this.Load()) {
throw new FileLoadException("Couldn't load settings file");
}
}
} catch (Exception ex) {
Trace.Write($"Failed to create MLogConf({nameof(stateFile)}) {ex.Message + Environment.NewLine + ex.StackTrace}");
}
}
private bool Load() {
if (SettingsFile == null)
return false;
try {
byte[] data = File.ReadAllBytes(SettingsFile.FullName);
using (MemoryStream m = new MemoryStream(data)) {
using (BinaryReader reader = new BinaryReader(m)) {
_Opacity = reader.ReadSingle();
_Font = (Font)(FontConvert.ConvertFromString(Encoding.ASCII.GetString(Convert.FromBase64String(reader.ReadString()))));
_FontColor = Color.FromArgb(reader.ReadInt32());
_BGColor = Color.FromArgb(reader.ReadInt32());
_Location = new Point(reader.ReadInt32(), reader.ReadInt32());
_Size = new Size(reader.ReadInt32(), reader.ReadInt32());
_HistoryLines = reader.ReadUInt16();
_ChatModes = (ChatType)reader.ReadInt32();
_Debugging = reader.ReadBoolean();
}
}
} catch (Exception e) {
Trace.WriteLine($"Exception reading binary data: {e.Message + Environment.NewLine + e.StackTrace}");
return false;
}
return true;
}
private bool Save() {
try {
using (FileStream fs = new FileStream(SettingsFile.FullName, FileMode.Create)) {
using (BinaryWriter writer = new BinaryWriter(fs)) {
writer.Write(_Opacity);
writer.Write(Convert.ToBase64String(Encoding.ASCII.GetBytes((string)FontConvert.ConvertTo(Font, typeof(string)))));
writer.Write(_FontColor.ToArgb());
writer.Write(_BGColor.ToArgb());
writer.Write(_Location.X);
writer.Write(_Location.Y);
writer.Write(_Size.Width);
writer.Write(_Size.Height);
writer.Write(_HistoryLines);
writer.Write((int)_ChatModes);
writer.Write(_Debugging);
}
}
} catch (Exception e) {
Trace.WriteLine($"Exception writing binary data: {e.Message + Environment.NewLine + e.StackTrace}");
return false;
}
return true;
}
private bool SetDefaultOptions() {
this._BGColor = Color.Black;
this._ChatModes = ChatType.Alliance | ChatType.Emote | ChatType.FreeCompany | ChatType.Linkshell | ChatType.Party | ChatType.SayShoutYell | ChatType.Tell;
this._Opacity = 1f;
this._Font = new Font("Verdana", 50);
this._FontColor = Color.CornflowerBlue;
this._Location = new Point(100, 400);
this._Size = new Size(470, 150);
this._HistoryLines = 512;
this._Debugging = false;
return this.Save();
}
I suppose you are looking for an easy way to store class instances in files.
Serialization is the process of converting an object into a stream of bytes in order to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization.
The shortest solution I've found for C# here some time ago was Json.NET from Newtonsoft, available as NuGet package. It will do all the 'long class-properties-to-string code' for you and leave you with string ready to be written in file.
Official site can provide code examples: http://www.newtonsoft.com/json
Save to file:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
// {
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Sizes": [
// "Small"
// ]
// }
Read from file:
string json = #"{
'Name': 'Bad Boys',
'ReleaseDate': '1995-4-7T00:00:00',
'Genres': [
'Action',
'Comedy'
]
}";
Movie m = JsonConvert.DeserializeObject<Movie>(json);
string name = m.Name;
// Bad Boys
Okay, so I'm working with custom network code for pretty much the first time. I have a packet created to transfer some game information back and forth, however beyond the initial content if I try to access some of the commands, I get "null" - though on the server side, it's showing as properly populated.
I have a feeling that this has to do with the setup in receiving the data. The code for the packet follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public enum DataIdentifier
{
Message,
Command,
LogIn,
LogOut,
Null
}
public class Packet
{
private DataIdentifier dataIdentifier;
private string name;
private string player;
private string playerData;
private string message;
private string command;
private string x;
private string y;
private string z;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public string Player
{
get
{
return player;
}
set
{
player = value;
}
}
public string Message
{
get
{
return message;
}
set
{
message = value;
}
}
public string Command
{
get
{
return command;
}
set
{
command = value;
}
}
public DataIdentifier DataIdentifier
{
get
{
return dataIdentifier;
}
set
{
dataIdentifier = value;
}
}
public string PlayerData
{
get
{
return playerData;
}
set
{
playerData = value;
}
}
public string X
{
get
{
return x;
}
set
{
x = value;
}
}
public string Y
{
get
{
return y;
}
set
{
y = value;
}
}
public string Z
{
get
{
return z;
}
set
{
z = value;
}
}
public Packet()
{
this.DataIdentifier = DataIdentifier.Null;
this.message = null;
this.name = null;
this.player = null;
this.playerData = null;
this.x = null;
this.y = null;
this.z = null;
this.command = null;
}
public Packet(byte[] dataStream)
{
// Read the data identifier from the beginning of the stream (4 bytes)
this.DataIdentifier = (DataIdentifier)BitConverter.ToInt32(dataStream, 0);
// Read the length of the name (4 bytes)
int nameLength = BitConverter.ToInt32(dataStream, 4);
// Read the length of the message (4 bytes)
int msgLength = BitConverter.ToInt32(dataStream, 8);
// Read the name field
if (nameLength > 0)
this.name = Encoding.UTF8.GetString(dataStream, 12, nameLength);
else
this.name = null;
// Read the message field
if (msgLength > 0)
this.message = Encoding.UTF8.GetString(dataStream, 12 + nameLength, msgLength);
else
this.message = null;
}
public byte[] GetDataStream()
{
List<byte> dataStream = new List<byte>();
// Add the dataIdentifier
dataStream.AddRange(BitConverter.GetBytes((int)this.DataIdentifier));
// Add the name length
if (this.name != null)
dataStream.AddRange(BitConverter.GetBytes(this.name.Length));
else
dataStream.AddRange(BitConverter.GetBytes(0));
// Add the message length
if (this.message != null)
dataStream.AddRange(BitConverter.GetBytes(this.message.Length));
else
dataStream.AddRange(BitConverter.GetBytes(0));
// Add the name
if (this.name != null)
dataStream.AddRange(Encoding.UTF8.GetBytes(this.name));
// Add the message
if (this.message != null)
dataStream.AddRange(Encoding.UTF8.GetBytes(this.message));
if (this.playerData != null)
{
dataStream.AddRange(Encoding.UTF8.GetBytes(this.playerData));
}
if (this.command != null)
{
dataStream.AddRange(Encoding.UTF8.GetBytes(this.command));
}
if (this.x != null)
{
dataStream.AddRange(Encoding.UTF8.GetBytes(this.x));
}
if (this.y != null)
{
dataStream.AddRange(Encoding.UTF8.GetBytes(this.y));
}
if (this.z != null)
{
dataStream.AddRange(Encoding.UTF8.GetBytes(this.z));
}
return dataStream.ToArray();
}
}
This is how the packet is recieved:
// Receive all data
this.clientSocket.EndReceive(AR);
// Initialise a packet object to store the received data
Packet receivedData = new Packet(this.dataStream);
// Evaulate command played
if (PacketDelegate != null)
{
PacketDelegate(receivedData);
}
// Reset data stream
this.dataStream = new byte[8142];
// Continue listening for broadcasts
clientSocket.BeginReceiveFrom(this.dataStream, 0, this.dataStream.Length, SocketFlags.None, ref epServer, new AsyncCallback(this.ReceiveCallback), null);
And this is the delegate function responsible for handling a packet:
public void RecievePacket(Packet Communication)
{
// Check and manipulate the contents of the packet here //
}
I have confirmed that I can get name, DataIdentifier, and Message, but it's the additional information I've added to the packet itself - player/data, command, x,y,z, I can't seem to get.
My thought is that the problem exists in establishing Packet(byte[] dataStream). However, I'm not quite sure how to calculate or add the additional variables to this. Can anyone give me some tips on how to do so?
The editor class has a method called GetString which prompts the user for a string value via AutoCAD's command prompt. I call it in this wrapper method:
public static string PromptUserForString(string message = "Enter a string: ", string defaultAnswer = "")
{
return _editor.GetString("\n" + message).StringResult;
}
The argument message becomes the message the user sees when prompted for a string. How do I set it up so that the value of default answer is automatically set to be the answer so that if the user hits enter right away that becomes the value like in the screen shot below
So 1 is automatically typed as an answer meaning the user can either hit enter for the value of 1 or change 1 to whatever non-default answer they want
I paste you some code as example for the different prompts :
using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
namespace EditorUtilities
{
/// <summary>
/// Prompts with the active document ( MdiActiveDocument )
/// </summary>
public class EditorHelper : IEditorHelper
{
private readonly Editor _editor;
public EditorHelper(Document document)
{
_editor = document.Editor;
}
public PromptEntityResult PromptForObject(string promptMessage, Type allowedType, bool exactMatchOfAllowedType)
{
var polyOptions = new PromptEntityOptions(promptMessage);
polyOptions.SetRejectMessage("Entity is not of type " + allowedType);
polyOptions.AddAllowedClass(allowedType, exactMatchOfAllowedType);
var polyResult = _editor.GetEntity(polyOptions);
return polyResult;
}
public PromptPointResult PromptForPoint(string promptMessage, bool useDashedLine = false, bool useBasePoint = false, Point3d basePoint = new Point3d(),bool allowNone = true)
{
var pointOptions = new PromptPointOptions(promptMessage);
if (useBasePoint)
{
pointOptions.UseBasePoint = true;
pointOptions.BasePoint = basePoint;
pointOptions.AllowNone = allowNone;
}
if (useDashedLine)
{
pointOptions.UseDashedLine = true;
}
var pointResult = _editor.GetPoint(pointOptions);
return pointResult;
}
public PromptPointResult PromptForPoint(PromptPointOptions promptPointOptions)
{
return _editor.GetPoint(promptPointOptions);
}
public PromptDoubleResult PromptForDouble(string promptMessage, double defaultValue = 0.0)
{
var doubleOptions = new PromptDoubleOptions(promptMessage);
if (Math.Abs(defaultValue - 0.0) > Double.Epsilon)
{
doubleOptions.UseDefaultValue = true;
doubleOptions.DefaultValue = defaultValue;
}
var promptDoubleResult = _editor.GetDouble(doubleOptions);
return promptDoubleResult;
}
public PromptIntegerResult PromptForInteger(string promptMessage)
{
var promptIntResult = _editor.GetInteger(promptMessage);
return promptIntResult;
}
public PromptResult PromptForKeywordSelection(
string promptMessage, IEnumerable<string> keywords, bool allowNone, string defaultKeyword = "")
{
var promptKeywordOptions = new PromptKeywordOptions(promptMessage) { AllowNone = allowNone };
foreach (var keyword in keywords)
{
promptKeywordOptions.Keywords.Add(keyword);
}
if (defaultKeyword != "")
{
promptKeywordOptions.Keywords.Default = defaultKeyword;
}
var keywordResult = _editor.GetKeywords(promptKeywordOptions);
return keywordResult;
}
public Point3dCollection PromptForRectangle(out PromptStatus status, string promptMessage)
{
var resultRectanglePointCollection = new Point3dCollection();
var viewCornerPointResult = PromptForPoint(promptMessage);
var pointPromptStatus = viewCornerPointResult.Status;
if (viewCornerPointResult.Status == PromptStatus.OK)
{
var rectangleJig = new RectangleJig(viewCornerPointResult.Value);
var jigResult = _editor.Drag(rectangleJig);
if (jigResult.Status == PromptStatus.OK)
{
// remove duplicate point at the end of the rectangle
var polyline = rectangleJig.Polyline;
var viewPolylinePoints = GeometryUtility.GetPointsFromPolyline(polyline);
if (viewPolylinePoints.Count == 5)
{
viewPolylinePoints.RemoveAt(4); // dont know why but true, probably mirror point with the last point
}
}
pointPromptStatus = jigResult.Status;
}
status = pointPromptStatus;
return resultRectanglePointCollection;
}
public PromptSelectionResult PromptForSelection(string promptMessage = null, SelectionFilter filter = null)
{
var selectionOptions = new PromptSelectionOptions { MessageForAdding = promptMessage };
var selectionResult = String.IsNullOrEmpty(promptMessage) ? _editor.SelectAll(filter) : _editor.GetSelection(selectionOptions, filter);
return selectionResult;
}
public PromptSelectionResult PromptForSelection(PromptSelectionOptions promptSelectionOptions,SelectionFilter filter = null)
{
return _editor.GetSelection(promptSelectionOptions, filter);
}
public void WriteMessage(string message)
{
_editor.WriteMessage(message);
}
public void DrawVector(Point3d from, Point3d to, int color, bool drawHighlighted)
{
_editor.DrawVector(from, to, color, drawHighlighted);
}
}
}
I have a Xamarin application and have managed to download my data from my server to my device. I have also got it set up so that it can take a SqlCipher Encryption key to encrypt the data.
My question is where is the correct location to store my key that I use to encrypt this data? Is it to you KeyStore / KeyChain? Which mono classes should I be looking to use?
Due to the popularity of this question I am going to post my implementation of this:
PCL interface
public interface IAuth
{
void CreateStore();
IEnumerable<string> FindAccountsForService(string serviceId);
void Save(string pin,string serviceId);
void Delete(string serviceId);
}
Android
public class IAuthImplementation : IAuth
{
Context context;
KeyStore ks;
KeyStore.PasswordProtection prot;
static readonly object fileLock = new object();
const string FileName = "MyProg.Accounts";
static readonly char[] Password = null;
public void CreateStore()
{
this.context = Android.App.Application.Context;
ks = KeyStore.GetInstance(KeyStore.DefaultType);
prot = new KeyStore.PasswordProtection(Password);
try
{
lock (fileLock)
{
using (var s = context.OpenFileInput(FileName))
{
ks.Load(s, Password);
}
}
}
catch (Java.IO.FileNotFoundException)
{
//ks.Load (null, Password);
LoadEmptyKeyStore(Password);
}
}
public IEnumerable<string> FindAccountsForService(string serviceId)
{
var r = new List<string>();
var postfix = "-" + serviceId;
var aliases = ks.Aliases();
while (aliases.HasMoreElements)
{
var alias = aliases.NextElement().ToString();
if (alias.EndsWith(postfix))
{
var e = ks.GetEntry(alias, prot) as KeyStore.SecretKeyEntry;
if (e != null)
{
var bytes = e.SecretKey.GetEncoded();
var password = System.Text.Encoding.UTF8.GetString(bytes);
r.Add(password);
}
}
}
return r;
}
public void Delete(string serviceId)
{
var alias = MakeAlias(serviceId);
ks.DeleteEntry(alias);
Save();
}
public void Save(string pin, string serviceId)
{
var alias = MakeAlias(serviceId);
var secretKey = new SecretAccount(pin);
var entry = new KeyStore.SecretKeyEntry(secretKey);
ks.SetEntry(alias, entry, prot);
Save();
}
void Save()
{
lock (fileLock)
{
using (var s = context.OpenFileOutput(FileName, FileCreationMode.Private))
{
ks.Store(s, Password);
}
}
}
static string MakeAlias(string serviceId)
{
return "-" + serviceId;
}
class SecretAccount : Java.Lang.Object, ISecretKey
{
byte[] bytes;
public SecretAccount(string password)
{
bytes = System.Text.Encoding.UTF8.GetBytes(password);
}
public byte[] GetEncoded()
{
return bytes;
}
public string Algorithm
{
get
{
return "RAW";
}
}
public string Format
{
get
{
return "RAW";
}
}
}
static IntPtr id_load_Ljava_io_InputStream_arrayC;
void LoadEmptyKeyStore(char[] password)
{
if (id_load_Ljava_io_InputStream_arrayC == IntPtr.Zero)
{
id_load_Ljava_io_InputStream_arrayC = JNIEnv.GetMethodID(ks.Class.Handle, "load", "(Ljava/io/InputStream;[C)V");
}
IntPtr intPtr = IntPtr.Zero;
IntPtr intPtr2 = JNIEnv.NewArray(password);
JNIEnv.CallVoidMethod(ks.Handle, id_load_Ljava_io_InputStream_arrayC, new JValue[]
{
new JValue (intPtr),
new JValue (intPtr2)
});
JNIEnv.DeleteLocalRef(intPtr);
if (password != null)
{
JNIEnv.CopyArray(intPtr2, password);
JNIEnv.DeleteLocalRef(intPtr2);
}
}
Call Create Store in the main activity of Android app first. - This could possibly be improved and remove CreateStrore() from the interface by checking if ks == null in Save and Delete and calling the method if true
iOS
public class IAuthImplementation : IAuth
{
public IEnumerable<string> FindAccountsForService(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
SecStatusCode result;
var records = SecKeyChain.QueryAsRecord(query, 1000, out result);
return records != null ?
records.Select(GetAccountFromRecord).ToList() :
new List<string>();
}
public void Save(string pin, string serviceId)
{
var statusCode = SecStatusCode.Success;
var serializedAccount = pin;
var data = NSData.FromString(serializedAccount, NSStringEncoding.UTF8);
//
// Remove any existing record
//
var existing = FindAccount(serviceId);
if (existing != null)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
statusCode = SecKeyChain.Remove(query);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not save account to KeyChain: " + statusCode);
}
}
//
// Add this record
//
var record = new SecRecord(SecKind.GenericPassword);
record.Service = serviceId;
record.Generic = data;
record.Accessible = SecAccessible.WhenUnlocked;
statusCode = SecKeyChain.Add(record);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not save account to KeyChain: " + statusCode);
}
}
public void Delete(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
var statusCode = SecKeyChain.Remove(query);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not delete account from KeyChain: " + statusCode);
}
}
string GetAccountFromRecord(SecRecord r)
{
return NSString.FromData(r.Generic, NSStringEncoding.UTF8);
}
string FindAccount(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
SecStatusCode result;
var record = SecKeyChain.QueryAsRecord(query, out result);
return record != null ? GetAccountFromRecord(record) : null;
}
public void CreateStore()
{
throw new NotImplementedException();
}
}
WP
public class IAuthImplementation : IAuth
{
public IEnumerable<string> FindAccountsForService(string serviceId)
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
string[] auths = store.GetFileNames("MyProg");
foreach (string path in auths)
{
using (var stream = new BinaryReader(new IsolatedStorageFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, store)))
{
int length = stream.ReadInt32();
byte[] data = stream.ReadBytes(length);
byte[] unprot = ProtectedData.Unprotect(data, null);
yield return Encoding.UTF8.GetString(unprot, 0, unprot.Length);
}
}
}
}
public void Save(string pin, string serviceId)
{
byte[] data = Encoding.UTF8.GetBytes(pin);
byte[] prot = ProtectedData.Protect(data, null);
var path = GetAccountPath(serviceId);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, store))
{
stream.WriteAsync(BitConverter.GetBytes(prot.Length), 0, sizeof(int)).Wait();
stream.WriteAsync(prot, 0, prot.Length).Wait();
}
}
public void Delete(string serviceId)
{
var path = GetAccountPath(serviceId);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
store.DeleteFile(path);
}
}
private string GetAccountPath(string serviceId)
{
return String.Format("{0}", serviceId);
}
public void CreateStore()
{
throw new NotImplementedException();
}
}
This is an adaptation of the Xamarin.Auth library (Found Here) but removes the dependency from the Xamarin.Auth library to provide cross platform use through the interface in the PCL. For this reason I have simplified it to only save one string. This is probably not the best implementation but it works in my case. Feel free to expand upon this
There is a nuget package called KeyChain.NET that encapsulated this logic for iOs, Android and Windows Phone.
It's open source and you have find sample at its github repository
More info at this blog post
within windows live messenger, it is possible to share the song you are currently listening to. what would i need to do to get this working within c# like libarys etc cannot find the correct documentation on google.
You'll need to use the iTunes SDK to interact with iTunes from .NET. So there's your Google search term. :)
Here's a start:
http://blogs.msdn.com/b/noahc/archive/2006/07/06/automating-itunes-with-c-in-net.aspx
http://blogs.msdn.com/b/dancre/archive/2004/05/08/128645.aspx
Here is a script for LinqPad in C# which does as requested. (see LinqPad.com)
Bonus! Artwork view.
It looks like this:
<Query Kind="Program">
<Namespace>iTunesLib</Namespace>
<Namespace>System.Security.Cryptography</Namespace>
</Query>
void Main()
{
var track = new iTunesApp().CurrentTrack;
if (track == null)
"nothing playing".Dump();
else
new Viewer(track,true).Dump();
}
public class Viewer
{
const string PREFIX = "itlps-";
private IITFileOrCDTrack store;
private bool materialize;
public string album { get { return store.Album; } }
public string band { get { return store.Artist; } }
public string song { get { return store.Name; } }
public string desc { get { return store.Description; } }
public int? artCnt { get {
if (store.Artwork == null) return null;
else return store.Artwork.Count; }
}
public IEnumerable<ImageViewer> art { get {
if (materialize)
{
foreach(var artT in store.Artwork)
{
var art = artT as IITArtwork;
string ext = ".tmp";
switch(art.Format)
{
case ITArtworkFormat.ITArtworkFormatBMP:
ext = ".BMP";
break;
case ITArtworkFormat.ITArtworkFormatJPEG:
ext = ".JPG";
break;
case ITArtworkFormat.ITArtworkFormatPNG:
ext = ".PNG";
break;
}
string path = Path.Combine(Path.GetTempPath(),PREFIX+Path.GetRandomFileName()+ext);
art.SaveArtworkToFile(path);
yield return new ImageViewer(path);
}
}
yield break; }
}
public Viewer(IITFileOrCDTrack t,bool materializeArt = false)
{
store = t;
materialize = materializeArt;
}
public Viewer(IITTrack t,bool materializeArt = false)
{
store = t as IITFileOrCDTrack;
materialize = materializeArt;
}
}
public class ImageViewer
{
public string hash { get { return _hash.Value; } }
static private string _path { get; set; }
public object image { get { return _image.Value; } }
static private SHA1Managed sha = new SHA1Managed();
private Lazy<object> _image = new Lazy<object>(() => {return Util.Image(_path);});
private Lazy<string> _hash = new Lazy<string>(() =>
{
string hash = string.Empty;
using (FileStream stream = File.OpenRead(_path))
{
byte [] checksum = sha.ComputeHash(stream);
hash = BitConverter.ToString(checksum).Replace("-", string.Empty);
}
return hash;
});
public ImageViewer(string path)
{
_path = path;
}
}
last i checked this functionality is included out of the box all you need is to have itunes and windows live messenger installed and activate "what im listening to" and it shows this in your messenger status. if you are looking to create a bot that messages this out to a contact that is a different story tho that you will need to write a script for