Zugriff auf SmartCard Reader mit PCSC

Deutschsprachiges X#-Forum – German language forum

Moderator: wriedmann

lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Zugriff auf SmartCard Reader mit PCSC

Post by lagraf »

Chris, thank you for your explanation!
Franz
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Zugriff auf SmartCard Reader mit PCSC

Post by lagraf »

Ich habe inzwischen ein paar Methoden zur Ansprache eines SmartCardReaders aus meiner DLL mittels ILSpy extrahiert und in ein Projekt integriert. Dabei gehe ich wie folgt vor:
  • Ich übertrage die Methode in ein C# Project und bringe sie dort zum Laufen
  • Danach übersetze ich sie nach X#
Nun bin ich aber auf ein Konstrukt gestoßen, das mir gar nichts sagt und das XIDE auch nicht compiliert:

Code: Select all

using System;
using System.Linq;

public class Program
{
	static void Main()
	{
		System.Console.WriteLine("Hello XIDE!");
		System.Console.WriteLine("00A4040007A0000001184543".ToByteArray());
	}

	public static byte[] ToByteArray(this string hex)
	{
		return (from x in Enumerable.Range(0, hex.Length)
			where x % 2 == 0
			select Convert.ToByte(hex.Substring(x, 2), 16)).ToArray();
	}
}
Wie am Bild1.jpg zu sehen ist, kann XIDE ToByteArray nicht mal korrekt darstellen.
Was ist ausserdem mit Extension gemeint?
Bild1.jpg
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Zugriff auf SmartCard Reader mit PCSC

Post by lagraf »

Bild1.jpg
Bild1.jpg (79.38 KiB) Viewed 478 times
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Zugriff auf SmartCard Reader mit PCSC

Post by lagraf »

Ich habs noch ein wenig umgebaut:

Code: Select all

using System;
using System.Linq;
using Project1.Extensions;

namespace Project1
{
	public class Program
	{
		static void Main()
		{
			System.Console.WriteLine("Hello XIDE!");
			System.Console.WriteLine("00A4040007A0000001184543".ToByteArray());
		}
	}
}

namespace Project1.Extensions
{
	public static class Extensions
	{
		public static byte[] ToByteArray(this string hex)
		{
			return (from x in System.Linq.Enumerable.Range(0, hex.Length)
				where x % 2 == 0
				select Convert.ToByte(hex.Substring(x, 2), 16)).ToArray();
		}
	}
}
Jetzt bekomme ich den Fehler:
error CS1069: The type name 'Enumerable' could not be found in the namespace 'System.Linq'. This type has been forwarded to assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. 26,34 Program.cs Project1.Extensions.Project1.Extensions:ToByteArray
Laut ILSpy ist Enumerable.Range in System.Linq vorhanden.
Referenziert habe ich System und System.Linq.
User avatar
wriedmann
Posts: 3754
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Zugriff auf SmartCard Reader mit PCSC

Post by wriedmann »

Hallo Franz,
das ist ein Linq-Ausdruck, und lässt sich problemlos in X# umsetzen.
Warum sich das mit C# auch nicht kompilieren lässt, hat wahrscheinlich mit einem veralteten C#-Compiler auf Deinem System zu tun.
Hast Du den C#-Code per ILSpy ausgelesen oder hattest Du den als Quellcode gefunden?
Wenn das zweite der Fall ist, dann wird der IL-Code nicht richtig nach C# umgesetzt.
Mit LinQ bin ich nicht wirklich fit, da müsste man sich einen Moment damit beschäftigen, aber der Code lässt sich auch ohne Linq schreiben.
Für das Verwenden von Enumerable brauchst Du nicht nur das "using System.Linq", sondern auch in den Abhängigkeiten die System.Linq.dll:
https://docs.microsoft.com/en-us/dotnet ... enumerable
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
wriedmann
Posts: 3754
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Zugriff auf SmartCard Reader mit PCSC

Post by wriedmann »

Hallo Franz,
in X# funktioniert dieser Code:

Code: Select all

function ToByteArray( cHex as string ) as byte[]
local aReturn as byte[]

aReturn := ( from x in System.Linq.Enumerable.Range( 0, cHex:Length ) ;
  where x % 2 == 0                                           ;
  select Convert.ToByte( cHex:Substring( x, 2 ), 16 ) ):ToArray()

return aReturn
Du brauchst Referenzen auf System.Linq und System.Core.
Logischerweise kannst Du das Ganze auch in eine statische Methode, eine Extension-Methode oder eine normale Methode packen, es ändert sich dann nur der Aufruf.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4898
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Zugriff auf SmartCard Reader mit PCSC

Post by Chris »

Guys,

It's the same also in c#, as the error message says, you need to add a reference to the library System.Core (in the app properties window)

.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Zugriff auf SmartCard Reader mit PCSC

Post by lagraf »

Hallo Wolfgang,
kann schon sein dass mein Compiler veraltet ist, ich hab noch W7 drauf. Kann man die Version feststellen oder ihn irgendwie updaten ohne das ganze OS umstellen zu müssen?
Den C# Code habe ich per ILSpy ausgelesen, mit dem X# Plugin sieht er übrigens so aus, muß aber noch probieren was der Compiler dann dazu sagt. Ist aber schon irgendwie komisch mit den Strichpunkten:

Code: Select all

public static method ToByteArray(self hex as string ) as Byte[]
	return (from x in Enumerable.Range(0, hex:Length);
	where x % 2 == 0;
	select Convert.ToByte(hex:Substring(x, 2), 16)):ToArray()
Ich hab die TestApp jetzt so erweitert und das funktioniert:

Code: Select all

using System;
using System.Linq;
using System.Text;
using Project1.Extensions;

namespace Project1
{
	public class Program
	{
		static void Main()
		{
			System.Console.WriteLine("Hello XIDE!");
			System.Console.WriteLine("00A4040007A0000001184543".ToByteArray().ToHexString());
		}
	}	// class
}	// namespace

namespace Project1.Extensions
{
	public static class Extensions
	{
		public static byte[] ToByteArray(this string hex)
		{
			return (from x in System.Linq.Enumerable.Range(0, hex.Length)
				where x % 2 == 0
				select Convert.ToByte(hex.Substring(x, 2), 16)).ToArray();
		}
		public static string ToHexString(this byte[] ba)
		{
			if (ba == null)
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder(ba.Length * 2);
			foreach (byte b in ba)
			{
				stringBuilder.AppendFormat("{0:x2}", b);
			}
			return stringBuilder.ToString();
		}
	}	// class
}	// namespace
Interessant ist aber trotzdem die Anzeige in der XIDE, dürfte sich um einen Fehler handeln, ist beim X# Code identisch:
Bild1.jpg
Bild1.jpg (25.38 KiB) Viewed 478 times
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Zugriff auf SmartCard Reader mit PCSC

Post by lagraf »

Hi Chris and Wolfgang,
with System.Core it runs! How can I find out which usings and references I need if such errors occure?
User avatar
wriedmann
Posts: 3754
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Zugriff auf SmartCard Reader mit PCSC

Post by wriedmann »

Hi Franz,
with System.Core it runs! How can I find out which usings and references I need if such errors occure?
it may sound stupid: read and understand the error message of the compiler. It says it:

Code: Select all

The type name 'Enumerable' could not be found in the namespace 'System.Linq'. This type has been forwarded to assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Post Reply