Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

CelikNET: LGPL CLR Interop Wrapper za CelikAPI

[es] :: .NET :: CelikNET: LGPL CLR Interop Wrapper za CelikAPI
(TOP topic, by mmix)
Strane: << < .. 2 3 4 5 6 7

[ Pregleda: 51267 | Odgovora: 127 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

nesomis
Nova Varoš

Član broj: 36830
Poruke: 8
95.180.73.*

Jabber: nesomis
Sajt: www.vaznesenjska.rs


Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI24.05.2020. u 12:30 - pre 6 meseci
Citat:
bokinet: @nesomis
Sta je sporno? U cemu se sastoji problem?
Pre svega, da li MUP Celik app radi na vasem racunaru?


@bokinet
Sporno je to što ne mogu da koristim CelikNET ni na jednoj mašini ma koji OS ili VS imao. Verovatno negde grešim u koracima i više ne znam šta da radim. Ukoliko ste raspoloženi da pomognete pošaljite mi privatnu poruku pa da se dogovorimo kada možete da se povežete i pogledate sami kako stvari stoje. Pokazaću Vam šta sam sve pokušavao.

Ono što meni treba je mogućnost iščitavanja ličnih karata u C# i VB preko najnovijeg CelikAPI-ja.
Hristos Voskrese !!!
 
Odgovor na temu

nesomis
Nova Varoš

Član broj: 36830
Poruke: 8
95.180.73.*

Jabber: nesomis
Sajt: www.vaznesenjska.rs


Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI25.05.2020. u 20:31 - pre 6 meseci
Moram da se zahvalim bokinetu na nesebičnoj pomoći, odvojenom vremenu i rešenju koje mi je prosledio, a koje ću moći da iskoristim u svom projektu.
Ja ću nastaviti da istražujem dalje. Čim dođem do svog rešenja za koje mislim da mi je pred nosom, podeliću ga svima koji budu zaintersovani za njega.

Hristos Voskrese !!!
 
Odgovor na temu

andrija032
programer
AndrijaSoft
Čačak

Član broj: 343657
Poruke: 2
*.static.isp.telekom.rs.



Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI03.06.2020. u 10:22 - pre 6 meseci
Pokusavam već nekoliko dana da pokrenem Windows aplikaciju u kojoj zelim da citam licnu kartu i svaki put kad probam pa procitam licnu kartu, dobijam sledecu gresku:

Could not load file or assembly 'CelikNET.dll' or one of its dependencies. is not a valid Win32 application.

Probao sam na nekoliko racunara i nista.

Da li bi neko mogao da mi pomogne, koristim VS 2017

Pozdrav.
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Član broj: 37636
Poruke: 1229



+92 Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI04.06.2020. u 10:03 - pre 6 meseci
Postoje tu dva dll-a, jedan je CelikApi.dll u kome je sva funkcionalnost, a drugi je CelikNET.dll koji olakšava korišćenje ovog prvog u .NET aplikacijama. Taj CelikApi.dll mora da stoji na sistemskoj putanji. Ta putanja je PATH variabla, ako si nekad čuo za to. Neki vole da iskopiraju CelikApi.dll u C:\Windows\System32 folder, ali Mikrosoft to ne preporučuje.

Preporučeni način je da iskopiraš fajl negde u C:\Program Files, recimo u folder C:\Program Files\Common Files\andrija032. I onda taj folder dodaš u PATH (idi u Control Panel\All Control Panel Items\System, klikni na Advanced system settings, u novom prozoru u tabu Advanced klikni na Environment Variables, odaberi variablu Path, klikni Edit, i dodaj putanju do željenog foldera (putanje su međusobno razdvojene znakom tačka-zarez (;)).
 
Odgovor na temu

andrija032
programer
AndrijaSoft
Čačak

Član broj: 343657
Poruke: 2
*.com
Via: [es] mailing liste



Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI04.06.2020. u 10:21 - pre 6 meseci
>
 
Odgovor na temu

nesomis
Nova Varoš

Član broj: 36830
Poruke: 8
95.180.73.*

Jabber: nesomis
Sajt: www.vaznesenjska.rs


Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI05.06.2020. u 00:52 - pre 6 meseci
Novi dan, novi problem.

1. Preuzeo sam Source fajl iz prvog posta i nisam menjao ništa u kodu i nisam menjao verziju CelikAPI-ja. Znači sve je ostalo
2. Napravio sam folder na c disku i dodao putanju u Environment Variables i restartovao komp da bi putanja bila vidljiva operativnom sistemu. U ovaj folder sam smestio CelikAPI.dll i CelikNet.dll
3. U VS 2019 sam pokrenuo projekat i retargetirao ga na ( Windows SDK Version 10.0 )
4. Ostavio sam .NET Framework na V4.0
5. CelikNet na platormi Win32
6. ConsoleTester na platformi x86
7. Solution na platformi x86
8. Kada pokrenem aplikaciju na konzoli se ispiše "Podaci o licnoj karti ---------------------------------" i dolazi do prekida sa greškom CelikNET.CelikException: 'ReadDocumentData nije izvrsen'

Šta dalje?


Hristos Voskrese !!!
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Član broj: 37636
Poruke: 1229



+92 Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI05.06.2020. u 11:16 - pre 5 meseci
Pokaži nam svoj kod. Uzgred, nadam se da si u projekat iz prve strane topika implementirao i izmene napisane u postu od 18.09.2014.
 
Odgovor na temu

nesomis
Nova Varoš

Član broj: 36830
Poruke: 8
95.180.73.*

Jabber: nesomis
Sajt: www.vaznesenjska.rs


Profil

icon Re: CelikNET: LGPL CLR Interop Wrapper za CelikAPI05.06.2020. u 19:33 - pre 5 meseci
Evo koda za CelikNET. Promenjena je samo 163 linija

Code:
/*  
    This file is part of CelikNET.

    CelikNET is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    CelikNET is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License along with CelikNET.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"

#pragma once

using namespace System;
using namespace System::Text;
using namespace System::Drawing;
using namespace System::IO;
using namespace System::Runtime::InteropServices;

namespace CelikNET {

    public ref class CelikException sealed: Exception 
    {
    public: 
        CelikException(String^ message, int ErrorCode): Exception(message), _EIDErrorCode(ErrorCode) {}
        property int EIDErrorCode { int get() { return _EIDErrorCode; }; }
        property String^ EIDErrorDescriptionEn { 
            String^ get() 
            {
                switch(EIDErrorCode) 
                {
                    case EID_OK: return "Operation completed succesfully"; 
                    case EID_E_GENERAL_ERROR: return "General error";
                    case EID_E_INVALID_PARAMETER: return "Invalid parameter";
                    case EID_E_VERSION_NOT_SUPPORTED: return "Version not supported";
                    case EID_E_NOT_INITIALIZED: return "Not initialized";
                    case EID_E_UNABLE_TO_EXECUTE: return "Unable to execute";
                    case EID_E_READER_ERROR: return "Reader error";
                    case EID_E_CARD_MISSING: return "Card missing";
                    case EID_E_CARD_UNKNOWN: return "Card unknown";
                    case EID_E_CARD_MISMATCH: return "Card mismatch";
                    case EID_E_UNABLE_TO_OPEN_SESSION: return "Unable to open session";
                    case EID_E_DATA_MISSING: return "Data missing";
                    case EID_E_CARD_SECFORMAT_CHECK_ERROR: return "Card security format check error";
                    case EID_E_SECFORMAT_CHECK_CERT_ERROR: return "Security format check certificate error";
                    default: return "Unknown error, consult documentation";
                }
            }; 
        }
        property String^ EIDErrorDescriptionSr { 
            String^ get() 
            {
                switch(EIDErrorCode) 
                {
                    case EID_OK: return L"Operacija uspešno završena"; 
                    case EID_E_GENERAL_ERROR: return L"Opšta greška";
                    case EID_E_INVALID_PARAMETER: return L"Neispravan parametar";
                    case EID_E_VERSION_NOT_SUPPORTED: return L"Ova verzija API-a nije podržana";
                    case EID_E_NOT_INITIALIZED: return L"Biblioteka nije inicijalizovana";
                    case EID_E_UNABLE_TO_EXECUTE: return L"Biblioteka ne može izvršiti operaciju";
                    case EID_E_READER_ERROR: return L"Greška u čitaču kartica";
                    case EID_E_CARD_MISSING: return L"Kartica nije prisutna u čitaču";
                    case EID_E_CARD_UNKNOWN: return L"Nepoznata kartica u čitaču";
                    case EID_E_CARD_MISMATCH: return L"Pogrešna kartica u čitaču";
                    case EID_E_UNABLE_TO_OPEN_SESSION: return L"Biblioteka ne može da otvori sesiju";
                    case EID_E_DATA_MISSING: return L"Podaci nisu prisutni na kartici";
                    case EID_E_CARD_SECFORMAT_CHECK_ERROR: return L"Sigurnosna greška u formatu kartice";
                    case EID_E_SECFORMAT_CHECK_CERT_ERROR: return L"Greška pri proveri sertifikata na kartici";
                    default: return L"Nepoznata greška, konsultujte dokumentaciju";
                }
            }; 
        }

    private:
        int _EIDErrorCode;
    };


    // data strukture
    // --------------------------------------------------------------------------------------------------

    /// <summary>
    /// Sadrzi osnovne informacije o licnoj karti
    /// </summary>
    public ref struct DocumentData
    {
    public:
        String^ docRegNo;
        String^ issuingDate;
        String^ expiryDate;
        String^ issuingAuthority;
    };
    /// <summary>
    /// Sadrzi osnovne informacije o nosiocu licne karte
    /// </summary>
    public ref struct FixedPersonalData
    {
    public:
        String^ personalNumber;
        String^ surname;
        String^ givenName;
        String^ parentGivenName;
        String^ sex;
        String^ placeOfBirth;
        String^ stateOfBirth;
        String^ dateOfBirth;
        String^ communityOfBirth;
    };

    /// <summary>
    /// Sadrzi dodatne informacije o nosiocu licne karte
    /// </summary>
    public ref struct VariablePersonalData
    {
    public:
        String^ state;
        String^ community;
        String^ place;
        String^ street;
        String^ houseNumber;
        String^ houseLetter;
        String^ entrance;
        String^ floor;
        String^ apartmentNumber;
    };

    // interop klasa
    // --------------------------------------------------------------------------------------------------

    public ref class CelikInterop sealed
    {
    private:
        /// <summary>
        /// nested klasa koja sluzi kao global destructor/finalizer
        /// </summary>
        ref class CelikInteropCleaner sealed
        {
        internal:
            static CelikInteropCleaner^ _instance = gcnew CelikInteropCleaner();
            static property CelikInteropCleaner^ singleton { CelikInteropCleaner^ get() { return _instance; } }
        private:
            CelikInteropCleaner() {}
            ~CelikInteropCleaner() { this->!CelikInteropCleaner(); }
            !CelikInteropCleaner() 
            {
                // ovaj exception ako bude bice na kraju same aplikacije, ostavljen je zbog debug sesija
                int err;
                if ((err = EidCleanup()) != EID_OK) throw gcnew CelikException("Cleanup nije izvrsen", err);
            } 
        };

        static CelikInteropCleaner^  _cleaner;
        /// <summary>
        /// Globalni konstruktor za Celik Interop wrapper. Inicijalizuje Celik API, poziva se "skriveno" samo jednom
        /// </summary>
        /// <exception cref="CelikNET::CelikException">Bacen ukoliko Celik Startup nije prosao kako treba, kod greske je ukljucen u tekst exceptiona</exception>
        static CelikInterop() 
        {
            int err;
            if ((err = EidStartup(2)) != EID_OK) throw gcnew CelikException("Startup nije izvrsen", err);
            // startup je ok, kreiraj cleaner "singleton" ciji teardown ce ugasiti celik za slucaj da korisnik zaboravi
            _cleaner = CelikInteropCleaner::singleton;
        }

        // static dummy
        static int _dummy = 123;

    public:
        /// <summary>
        /// Globalni cleanup za Celik Interop wrapper. Ovo je poslednji CelikNET poziv u aplikaciji, posle njega vise nece raditi instanciranje i pozivanje CelikNET objekata/metoda. Alternativno mozete pustiti aplikaciju da se sama ocisti
        /// </summary>
        /// <exception cref="CelikNET::CelikException">Bacen ukoliko Celik Cleanup nije prosao kako treba, kod greske je ukljucen u tekst exceptiona</exception>
        static void Cleanup() 
        {
            //manuelni tear down celika, ako je cleaner inicijalizovan ovo ce deterministicki pozvadi dispose patern i uraditi zatvaranje 
            delete _cleaner;
        }

        /// <summary>
        /// Konstruktor za Celik Interop wrapper. Inicijalizuje Read operaciju kroz EidBeginRead i omogucava poziv blok komandi
        /// </summary>
        /// <exception cref="CelikNET::CelikException">Bacen ukoliko BeginRead nije prosao kako treba, kod greske je ukljucen u tekst exceptiona</exception>
        CelikInterop() 
        {
            // pipni staticko polje da bi naterao kompajler da pozove sttaicki konstruktor prvi put
            // http://connect.microsoft.com/V...or-not-called-in-release-build
            int dummy = CelikInterop::_dummy;
            // init read
            int err;
            if ((err = EidBeginRead("")) != EID_OK) throw gcnew CelikException("BeginRead nije izvrsen", err);
        }

        ~CelikInterop() 
        {
            // dispose pattern, pozovi finalizer
            this->!CelikInterop();
        }


        /// <summary>
        /// Ucitava osnovne podatke sa licne karte
        /// </summary>
        /// <returns>Instanca <see cref="CelikNET::FixedPersonalData">CelikNET::FixedPersonalData</see> klase u kojoj su podaci</returns>
        /// <exception cref="CelikNET::CelikException">Bacen ukoliko ReadFixedPersonalData nije prosao kako treba, kod greske je ukljucen u tekst exceptiona</exception>
        FixedPersonalData^ ReadFixedPersonalData() 
        {
            msclr::lock l(CelikInteropCleaner::singleton); // thread global sync
            int err;
            PEID_FIXED_PERSONAL_DATA p = new EID_FIXED_PERSONAL_DATA;
            if ((err = EidReadFixedPersonalData(p)) != EID_OK) throw gcnew CelikException("ReadFixedPersonalData nije izvrsen", err);
            FixedPersonalData^ fpd = gcnew FixedPersonalData;
            fpd->personalNumber = decodeUTF8Buffer(p->personalNumber, p->personalNumberSize);
            fpd->surname = decodeUTF8Buffer(p->surname, p->surnameSize);
            fpd->givenName = decodeUTF8Buffer(p->givenName, p->givenNameSize);
            fpd->parentGivenName = decodeUTF8Buffer(p->parentGivenName, p->parentGivenNameSize);
            fpd->sex = decodeUTF8Buffer(p->sex, p->sexSize);
            fpd->placeOfBirth = decodeUTF8Buffer(p->placeOfBirth, p->placeOfBirthSize);
            fpd->stateOfBirth = decodeUTF8Buffer(p->stateOfBirth, p->stateOfBirthSize);
            fpd->dateOfBirth = decodeUTF8Buffer(p->dateOfBirth, p->dateOfBirthSize);
            fpd->communityOfBirth = decodeUTF8Buffer(p->communityOfBirth, p->communityOfBirthSize);
            return fpd;
        }


        /// <summary>
        /// Ucitava dodatne podatke sa licne karte
        /// </summary>
        /// <returns>Instanca <see cref="CelikNET::VariablePersonalData">CelikNET::VariablePersonalData</see> klase u kojoj su podaci</returns>
        /// <exception cref="CelikNET::CelikException">Bacen ukoliko ReadVariabelPersonalData nije prosao kako treba, kod greske je ukljucen u tekst exceptiona</exception>
        VariablePersonalData^ ReadVariablePersonalData() 
        {
            msclr::lock l(CelikInteropCleaner::singleton); // thread global sync
            int err;
            PEID_VARIABLE_PERSONAL_DATA p = new EID_VARIABLE_PERSONAL_DATA;
            if ((err = EidReadVariablePersonalData(p)) != EID_OK) throw gcnew CelikException("ReadVariablePersonalData nije izvrsen", err);
            VariablePersonalData^ vpd = gcnew VariablePersonalData;
            vpd->state = decodeUTF8Buffer(p->state, p->stateSize);
            vpd->community = decodeUTF8Buffer(p->community, p->communitySize);
            vpd->place = decodeUTF8Buffer(p->place, p->placeSize);
            vpd->street = decodeUTF8Buffer(p->street, p->streetSize);
            vpd->houseNumber = decodeUTF8Buffer(p->houseNumber, p->houseNumberSize);
            vpd->houseLetter = decodeUTF8Buffer(p->houseLetter, p->houseLetterSize);
            vpd->entrance = decodeUTF8Buffer(p->entrance, p->entranceSize);
            vpd->floor = decodeUTF8Buffer(p->floor, p->floorSize);
            vpd->apartmentNumber = decodeUTF8Buffer(p->apartmentNumber, p->apartmentNumberSize);
            return vpd;
        }
                
        /// <summary>
        /// Ucitava osnovne podatke sa licne karte
        /// </summary>
        /// <returns>Instanca <see cref="CelikNET::DocumentData">CelikNET::DocumentData</see> klase u kojoj su podaci</returns>
        /// <exception cref="CelikNET::CelikException">Bacen ukoliko ReadDocumentData nije prosao kako treba, kod greske je ukljucen u tekst exceptiona</exception>
        DocumentData^ ReadDocumentData() 
        {
            msclr::lock l(CelikInteropCleaner::singleton); // thread global sync
            int err;
            PEID_DOCUMENT_DATA p = new EID_DOCUMENT_DATA;
            if ((err = EidReadDocumentData(p)) != EID_OK) throw gcnew CelikException("ReadDocumentData nije izvrsen", err);
            DocumentData^ dd = gcnew DocumentData;
            dd->docRegNo = decodeUTF8Buffer(p->docRegNo, p->docRegNoSize);
            dd->issuingDate = decodeUTF8Buffer(p->issuingDate, p->issuingDateSize);
            dd->expiryDate = decodeUTF8Buffer(p->expiryDate, p->expiryDateSize);
            dd->issuingAuthority = decodeUTF8Buffer(p->issuingAuthority, p->issuingAuthoritySize);
            return dd;
        }


        /// <summary>
        /// Ucitava sliku sa licne karte
        /// </summary>
        /// <returns>Instanca <see cref="System::Drawing::Bitmap">System.Drawing.Bitmap</see> klase u kojoj je slika licne karte</returns>
        /// <exception cref="CelikNET::CelikException">Bacen ukoliko ReadPortrait nije prosao kako treba, kod greske je ukljucen u tekst exceptiona</exception>
        Bitmap^ ReadProfileImage() 
        {
            msclr::lock l(CelikInteropCleaner::singleton); // thread global sync
            // izvuci bajtove portreta
            int err;
            PEID_PORTRAIT p = new EID_PORTRAIT;
            if ((err = EidReadPortrait(p)) != EID_OK) throw gcnew CelikException("ReadPortrait nije izvrsen", err);
            // iskopiraj sliku u managed space
            array<byte>^ managedArray = gcnew array<byte>(p->portraitSize);
            Marshal::Copy((IntPtr)p->portrait, managedArray, 0, p->portraitSize);
            // instanciraj bitmap sa jpeg nizom
            MemoryStream^ ms = gcnew MemoryStream(managedArray);
            return gcnew Bitmap(ms);
        }

    private:
        String^ decodeUTF8Buffer(char* buffer, int length) 
        {
            array<byte>^ managedArray = gcnew array<byte>(length);
            Marshal::Copy((IntPtr)buffer, managedArray, 0, length);
            return Encoding::UTF8->GetString(managedArray, 0, length);
        }

    protected:
        !CelikInterop() 
        {
            int err;
            if ((err = EidEndRead()) != EID_OK) throw gcnew CelikException("EndRead nije izvrsen", err);
        } 
    };
}


Kod za ConsolTester Program.cs (ništa nije promenjeno)

Code:
/*  
    This file is part of CelikNET.

    CelikNET is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    CelikNET is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License along with CelikNET.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace ConsoleTester
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.GetEncoding(1251) ;
            try
            {
                using (CelikNET.CelikInterop x = new CelikNET.CelikInterop())
                {
                    Console.WriteLine("Podaci o licnoj karti ------------------------------------------");
                    CelikNET.DocumentData d3 = x.ReadDocumentData();
                    Console.WriteLine("docRegNo: {0}", d3.docRegNo);
                    Console.WriteLine("issuingDate: {0}", d3.issuingDate);
                    Console.WriteLine("expiryDate: {0}", d3.expiryDate);
                    Console.WriteLine("issuingAuthority: {0}", d3.issuingAuthority);

                    Console.WriteLine("Fiksni podaci ------------------------------------------");
                    CelikNET.FixedPersonalData d1 = x.ReadFixedPersonalData();
                    Console.WriteLine("personalNumber: {0}", d1.personalNumber);
                    Console.WriteLine("surname: {0}", d1.surname);
                    Console.WriteLine("givenName: {0}", d1.givenName);
                    Console.WriteLine("sex: {0}", d1.sex);
                    Console.WriteLine("placeOfBirth: {0}", d1.placeOfBirth);
                    Console.WriteLine("stateOfBirth: {0}", d1.stateOfBirth);
                    Console.WriteLine("dateOfBirth: {0}", d1.dateOfBirth);
                    Console.WriteLine("communityOfBirth: {0}", d1.communityOfBirth);

                    Console.WriteLine("Variablini podaci ------------------------------------------");
                    CelikNET.VariablePersonalData d2 = x.ReadVariablePersonalData();
                    Console.WriteLine("state: {0}", d2.state);
                    Console.WriteLine("community: {0}", d2.community);
                    Console.WriteLine("place: {0}", d2.place);
                    Console.WriteLine("street: {0}", d2.street);
                    Console.WriteLine("houseNumber: {0}", d2.houseNumber);
                    Console.WriteLine("houseLetter: {0}", d2.houseLetter);
                    Console.WriteLine("entrance: {0}", d2.entrance);
                    Console.WriteLine("floor: {0}", d2.floor);
                    Console.WriteLine("apartmentNumber: {0}", d2.apartmentNumber);

                    Console.WriteLine("Slika ------------------------------------------");
                    Bitmap c = x.ReadProfileImage();
                    Console.WriteLine("Ucitana slika {0}x{1}", c.Width, c.Height);
                }
                Console.ReadLine();
            }
            catch (CelikNET.CelikException ex)
            {
                Console.WriteLine("EXCEPTION: {0} {1}", ex.EIDErrorCode, ex.EIDErrorDescriptionEn);
                Console.ReadLine();
                throw ex;
            }

        }
    }
}

Hristos Voskrese !!!
 
Odgovor na temu

[es] :: .NET :: CelikNET: LGPL CLR Interop Wrapper za CelikAPI
(TOP topic, by mmix)
Strane: << < .. 2 3 4 5 6 7

[ Pregleda: 51267 | Odgovora: 127 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.