프로그램에서 엑셀(Excel)을 다루어 보자.(5)

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (3/22/2011 4:19:15 PM) Viewing : 4028

한동안 문제 없이 잘 사용하던 컴포넌트가 문제가 생겼습니다.

저는 아직 VS2008을 사용하고 있어서 몰랐었는데 오늘 팀원(연X정 씨)이 문제 제기를 해와서 살펴 보았습니다.

이전 설명에서도 언급했듯이 apach.poi 라는 어셈블리는 자바 기반입니다.

.net 에서는 j# 으로 컴파일되어 있어서 이를 구동하기 위해서는 j# 재배포 패키지가 필요합니다.

그런데.....

VS 2010에서는 CLR 구조가 바뀌어서...아님..ms에서 j#은 버린건지도 모르겠습니다만...문제가 생깁니다.

vjsnativ.dll 라는 어셈블리를 찾을 수 없다는 메시지를 던집니다.

넵..이런 오류가 되겠습니다.

 

열심히 구글링 해보았습니다.

저와 같은 문제를 가지고 있는 많은 개발자들의 글을 볼 수 있었고 trick 이지만..이에 대한 해결책을 제시한 글을 보았습니다.

http://blogs.windwardreports.com/davidt/2011/02/calling-j-code-from-net-40.html

별거 없습니다.

동적으로 해당 경로의 dll을 읽어 오는게 되겠습니다.

/// 
/// 어셈블리를 가져옵니다.
/// 
/// Name of the lp file.
/// 
[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);

이는 WIN32 API를 PInvoke로 설정한 메서드입니다.

이제 이 메서드를 이용하여 호출합니다.

/// <summary>
/// <para><see cref="ExcelHandler"/>의 정석 생성자입니다.</para>
/// <para>.NET Framework 4.0 이상에서는 J# 불러 올 수 없습니다.</para>
/// <para>아래 코드는 win32 API를 이용하여 직접 어셈블리를 읽어 오는 코드입니다.</para>
/// <para>반드시 J# 재배포 패키지 2.0 이 설치되어 있어야 합니다..</para>
/// </summary>
/// <remarks></remarks>
static ExcelHandler()
{
    if (Environment.Version.Major >= 4)
    {
        string folder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), @"..\Microsoft.NET\Framework\v2.0.50727");
        folder = System.IO.Path.GetFullPath(folder);
        LoadLibrary(System.IO.Path.Combine(folder, "vjsnativ.dll"));
    }
}

위에서 보듯이 정적 생성자에 정의 하였습니다..

한번만 불러 오면 되기 때문이겠죠..

76 행을 보게 되면 버전 체크를 합니다.Major 버전이 4 이상이면 즉 닷넷 프레임워크의 버전이 4 이상이면 아래 루틴을 타겠지요..

^^;;

 

저도 이제 슬슬 VS2010으로 가봐야 할 때가 온거 같기도 하네요..ㅡ.ㅡ;;;


마지막 업데이트 : (3/22/2011 4:26:13 PM)




첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

RPNetworks.Security

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/5/2011 11:40:08 AM) Viewing : 5803

오늘 살펴볼 내용은 암호화입니다.

지원하는 암호화 알고리즘은 크게 3가지입니다.

ARIA 알고리즘, SEED 알고리즘, HASH 알고리즘입니다.

그중에 HASH알고리즘은 MD5, SHA1, SHA256 을 지원합니다.

ARIA 알고리즘과 SEED 알고리즘은 우리나라 표준 알고리즘이며 대칭키 기반 블럭암호화 알고리즘입니다.

우리 나라 표준이기에 공공기관의 프로젝트에서는 반드시 이 2개의 암호화 알고리즘중 한개를 선택해서 사용해야 합니다.

그러나 ARIA에 비해 SEED는 속도가 매우 느립니다. 아마도 먼저 확실하진 않지만 개발되었기에 그렇겠죠?

그렇기에 복호화가 가능한 암호화를 하기 위해서는 ARIA 알고리즘을 써야 합니다.

복호화가 불가능한 HASH 알고리즘은 비밀번호나 주민등록번호 처럼 복호화가 불가능한 데이터에 사용되어 지죠.

MSDN에 의하면 MD5보다는 SHA1이 보안이 강화되었으며 SHA1 보다는 SHA256이 보안이 더 강화되었읍니다.

이미 MD5는 수십년전에 깨진 암호화 알고리즘이며 SHA1 또한 십수년 전에 깨진 알고리즘입니다.

알아서 잘 선택하기 바랍니다.

이제 다시 코드로 돌아 와서 ...지원하는 타입은 아래와 같습니다.

/// 
/// 암호화 타입 Ver 1.0
/// 
/// 
/// 2008.07.08 - ProtoType - 이방은(www.bangsil.net)
/// 
public enum SecurityType
{
    /// 
    /// 아리아 알고리즘입니다.
    /// 
    AriaAlgorithm = 0,
    /// 
    /// 시드 알고리즘입니다.
    /// 
    SeedAlgorithm,
    /// 
    /// 128비트 MD5 알고리즘입니다.
    /// 
    MD5,
    /// 
    /// 128비트 SHA1 알고리즘입니다.
    /// 
    SHA1,
    /// 
    /// 256비트 SHA256 알고리즘입니다.
    /// 
    SHA256
}

암호화를 하기 위해서는 SecuirtyProviderBase 라는 팩토리 클래스를 이용합니다.

각 암호화 클래스의 인스턴스는 이 팩토리 클래스의 CreateInstance 메서드를 통해서만 얻을 수 있습니다.

public static SecurityProviderBase CreateInstance(SecurityType sType, int keySize)
{
    if (sType == SecurityType.AriaAlgorithm)
    {
        if (keySize != 128 && keySize != 192 && keySize != 256)
        {
            throw new ArgumentOutOfRangeException(string.Format
(CommonLocalizedEnumConverter.ConvertToString(ExceptionMessage.OutOfRange)
, keySize.ToString()));
        }
    }
    switch (sType)
    {
        case SecurityType.AriaAlgorithm:
            SecurityProviderBase p = new AriaProvider(keySize);
            p.keySize = keySize;
            return p;
        case SecurityType.SeedAlgorithm:
            return new SeedProvider();
        case SecurityType.MD5:
            return new HashProvider(SecurityType.MD5);
        case SecurityType.SHA1:
            return new HashProvider(SecurityType.SHA1);
        case SecurityType.SHA256:
            return new HashProvider(SecurityType.SHA256);
        default:
            return null;
    }
}

ARIA 알고리즘을 제외하고는 keySize가 필요치 않습니다. 이에 keySize가 없는 메서드도 overload 되어 있습니다.

ARIA 알고리즘은 블럭암호화 알고리즘이며 MASTER KEY 라는 것이 필요합니다. 이 키값은 매우 중요한 값이며 키값이 노출되면 복호화가 가능하게 됩니다.

어쨋든 이 키값을 생성하기 위한 메서드는 CreateMasterKey 라는 메서드입니다.  입력받은 문자열을 인코딩하여 키값을 생성합니다.

이 메서드를 호출하지 않으면 임의로 마스터키를 생성합니다만 직접 생성하기를 권합니다.

이제 암호화 복호화 메서드가 존재합니다.

이 메서드는 각각 2개씩 존재합니다. 인풋 매개변수의 형식 및 리턴 형식이 String 인 메서드와 byte[]  인 메서드가 존재합니다.

 public string EncryptToString(string inputString) 와 public byte[] EncryptToByteArray(string inputString) 은 암호화 메서드가 되겠고
public string DecryptFromString(string inputString) 와 public string DecryptFromByteArray(byte[] inputByteArray) 는 복호화 메서드가 되겠습니다

각각 상황에 맞게 사용하면 되겠네요.

사용법은 너무나 간단합니다.

SecurityProviderBase security=  SecurityProviderBase.CreateInstance(SecurityType.AriaAlgorithm, 128);
security.CreateMasterKey("마스터키");//생략 하면 기본 설정됨.
string 암호화된문자열 = security.EncryptToString("암호화할 문자열");

 

PS : 삽질전문개발자 님 감사합니다.


마지막 업데이트 : (6/14/2011 7:10:02 PM)




첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (6)
삽질전문개발자님의 글 (6/13/2011 11:07:28 PM)
분문 중 "ARIA 알고리즘과 SEED 알고리즘은 우리나라 표준 알고리즘이며 공개키 기반 블럭암호화 알고리즘입니다."

ARIA와 SEED는 대칭키(비밀키) 블럭 암호화 알고리즘이며, 공개키 기반 암호화라 함은 비밀키/공개키의 키 쌍을 갖는 암호화 방법을 뜻합니다. 즉, 본문의 표현을 인용하여 이야기하면 '마스터키' 방식의 암호화는 공개키 기반 암호화 알고리즘일 수 없습니다.

* 기술 블로그의 부정확한 내용은 후학들과 대중에게 불량 씨앗을 나눠주는 것과 같습니다. 본문을 정정하시면 이 댓글은 삭제하셔도 무방합니다



방실이님의 글 (6/14/2011 7:08:17 PM)
대칭키이군요..^^; 감사합니다.



이세기님의 글 (9/26/2011 8:13:50 PM)
정말 난감했는데 많은 도움이 되었습니다 감사합니다.



방실이님의 글 (9/27/2011 2:18:05 PM)
감사합니다..^^



고은애님의 글 (8/8/2012 2:01:21 PM)
감사합니다^^



김성수님의 글 (7/16/2013 10:23:04 PM)
좋은 공부가 되었습니다. 감사합니다.



댓글 쓰기

RPNetworks.Resources - 03

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/4/2011 11:59:35 AM) Viewing : 2190

마지막글이 되겠네요.

리소스 작업을 하다 보니까 자주 쓰이는 것들이 눈에 띄게 되었습니다.

첫 글에도 언급했듯이 대부분 인증관련 내용이나 게시판 관련 내용이 되겠습니다.

자주쓰는 TEXT 를 미리 리소스로 만들어 놓으면 사용하기에 참 용이할 것 같다는 생각이 들었습니다.

그러나 이 구조는 단위 네임스페이스당 하나의 리소스 형식이라 공용으로 뽑기에는 코드를 좀 수정해야 했죠.

어쨋든 그래서 생성한 클래스가 CommonLocalizedEnumConverter 입니다.

namespace RPNetworks.Resources 
{ 
    public class CommonLocalizedEnumConverter : ResourceEnumConverter 
    { 
        public CommonLocalizedEnumConverter(Type type) 
            : base(type) 
        { 
            base.ResourceManager = new CustomResourceManager(ResourceType.String).ResourceManager; 
        } 
    } 
}

네임스페이스를 보면 알겠지만 이 클래스는 ResoruceEnumConverter를 상속 받았지만 네임스페이스는 현재 위치 그대로 입니다.

그리고 자주 쓸만한 열거형을 모아서 한번 만들어 보았습니다.(근데 이게...참 까탈스럽더군요..ㅡ.ㅡ;;;;)

AuthMessage 나 BoardMessage 같은 열거형이 바로 그것입니다.

이것을 사용하기 위한 방법은 아래 코드와 같습니다.

this.lblCommon.Text = CommonLocalizedEnumConverter.ConvertToString(BoardMessage.BoardCreated);

뭐 별거 없네요..ㅋ~

샘플을 한번 만들어 보았습니다..

아주..귀찮네요..ㅡ.ㅡ;;;;; 그래도 글빨이 안서는 지라.....


마지막 업데이트 : (1/5/2011 5:09:08 PM)




첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

RPNetworks.Resources - 02

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/4/2011 11:48:41 AM) Viewing : 2356

이전 글에 이어서 이번에는 열거형을 이용한 리소스관리를 해 보도록 하겠습니다.

이 내용은

http://www.codeproject.com/csharp/LocalizingEnums.asp

게시물의 코드를 참조했습니다.

열거형의 값을 리소스화 시켜 다국어로 보여 주는 게 되겠습니다. 참 기가막히도록 참신한 아이디어네요..

메인 클래스는 CustomResourceConverter 라는 클래스입니다.

코드 설명은 제가 만든게 아니기 때문에 생략 (ㅡ.ㅡ;;;) 합니다.

어쨋든 이 클래스를 이용하여 작업을 해보도록 하겠습니다.

이전 글에서 살펴 보았던 IShop.Resources 를 계속 사용해 보도록 하겠습니다.

아래와 같은 열거형이 있다고 가정합니다.

public enum Message
{
    Ok,
    Cancel,
    Yes,
    No
}

사용자 화면에는 Ok 의 경우 "확인" 으로 보여 주고 싶다고 합니다. 그럼 작업을 시작해 보지요.

먼저 IShop.Resources 에 아래와 같은 클래스를 생성합니다.

namespace IShop.Web
{
    public class LocalizedEnumConverter : ResourceEnumConverter
    {
        public LocalizedEnumConverter(Type type) : base(type)
        {
            base.ResourceManager = new CustomResourceManager(ResourceType.String
                              , typeof(LocalizedEnumConverter)).ResourceManager;
        }
    }
}

앞서 방법과 마찬가지로 네임스페이스 이름에 주의 하시기 바랍니다.

이제 리소스 파일을 생성해 보도록 하겠습니다.

이전에 글에서 생성하였던 리소스파일을 계속 사용합니다.

IShop.Web.String.Resources 라는 파일이 생성되었지요?

이 파일을 계속 사용합니다. 참..깜박 한 것이 있는데 이 파일의 경로는 반드시 Resources 라는 폴더에 위치해야 합니다.

즉 IShop.Resources 프로젝트에서 /Resources/IShop.Web.String.Resources 가 되겠습니다.

리소스 파일을 열고 Key 와 Value 를 입력합니다.

key:Message_Ok, value:확인
key:Message_Cancel, value:취소
key:Message_Yes, value:예
key:Message_No, value:아니오

"열거형의 이름_열겨형의 값" 형식이 됩니다.

그리고 마지막으로 열거형에 TypeConverter 특성을 붙여 줍니다.

[TypeConverter(typeof(LocalizedEnumConverter))]
public enum Message
{
    Ok,
    Cancel,
    Yes,
    No
}

이제 다 되었습니다.

이 값을 사용하기 위한 코드는 아래와 같습니다.

string ok = LocalizedEnumConverter.ConvertToString(Message.Ok);
//ok = "확인"

간단하지욤???


마지막 업데이트 : (1/5/2011 5:10:34 PM)




Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

RPNetworks.Resources - 01

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/3/2011 9:34:48 PM) Viewing : 2211

이번에 알아 볼 것은 리소스 관리 입니다.

이미 예전에 리소스 관련된 글을 쓴적이 있습니다.

http://bangsil.net/MyPosts/DotNet/1a654797-8893-4c7c-9e93-c979ad67b2fa

기본적으로 리소스는 하나의 프로젝트의 Properties 라는 폴더의 하위에 위치하게 됩니다.

이 리소스는 이미지나 문자열 아이콘 파일등등 어느 것이든 가능합니다.

여러개의 프로젝트가 있는 솔루션의 경우에는 각 프로젝트마다 그 프로젝트에 해당되는 리소스가 존재하게 될테고 이를 관리 하는 것은 참 까탈스럽습니다.

그래서 이렇게 뿔뿔이 흩어져 있는 리소스를 하나의 프로젝트로 모아서 관리 할 수 있는 방법은 없을까 하고 고민하게 되었습니다.

기본적인 샘플은 위 링크에서 다운 받아서 테스트 해 보시기 바랍니다.

그리고 위 링크에서 사용되었던 버전과 달라진 점이라면 자주쓰는 데이터는 CommonMessage 형태로 따로 뽑아 두었습니다. 대부분 인증이나 게시판 관려 메시지가 되겠네요..

우선 하나씩 살펴 보도록 하겠습니다.

public enum ResourceType
{
    /// 
    /// 아이콘 타입입니다.
    /// 
    Icon = 0,
    /// 
    /// 문자열 타입입니다.
    /// 
    String,
    /// 
    /// 이미지 타입입니다.
    /// 
    Image,
    /// 
    /// Object 타입입니다.
    /// 
    Object
}

이 어셈블리를 이용하여 사용할 수 있는 리소스 형식은 위와 같습니다.

 이 어셈블리에는 중요한 클래스가 2개가 있습니다.

그중 하나는 CommonLocalizedEnumConvertoer 이며 또 하나는 CustomResourceManager 클래스입니다.

전자의 경우에는 열거형을 지역화 하는 경우에 사용하는 클래스입니다. 후자의 경우는 열거형이 아닌 경우에 사용하는 클래스입니다.

후자의 경우에는 별도로 Proxy 클래스가 필요로 합니다. 이 글의 첫 링크에 있는 예제는 바로 후자의 것이 되겠네요.

우선 CumstomResourceManager 클래스를 이용하는 법을 알아 봅시다.

public CustomResourceManager(ResourceType resourceType, Type type)
{
    bool hasResource = false;
    Assembly asm = Assembly.GetCallingAssembly();
    string resourceName = asm.GetName().Name + ".Resources." 
                        + type.Namespace + "." + resourceType.ToString();
    foreach (string reName in asm.GetManifestResourceNames())
    {
        if (reName.Substring(0, reName.LastIndexOf('.')) == resourceName)
        {
            hasResource = true;
            break;
        }
    }
    if (!hasResource)
    {
        throw new MissingManifestResourceException("해당 타입의 리소스를 찾을 수 없습니다.");
    }
    else
    {
        rm = new ResourceManager(resourceName, asm);
    }
}

ResourceType은 앞서 보았던 열거형입니다.
즉 매개변수로 해당 리소스 파일이 있는지 찾고 찾게 되면 ResourceManger 의 인스턴스를 생성하는 코드가 되겠습니다.

이 룰에 적합하게 하기 위해서는 리소스파일의 경우 {네임스페이스}.String.{CultureCode(생략가능)}.resources  형식이 되어야 합니다.

또 다른 생성자는 각 네임스페이스의 리소스가 아니라 공용리소스를 생성하기위한 생성자입니다.

이 클래스에는 리소스를 가져오는 여러 메서드가 있습니다만 대동소이합니다.

예를 들어 리소스를 문자열로 가져오기 위해서는 GetString 메서드를 호출합니다 코드는 아래와 같습니다.

public string GetString(string key)
{
    if (key.Length == 0)
    {
        return null;
    }
    try
    {
        return rm.GetString(key);
    }
    catch
    {
        return null;
    }
}

이제 실제로 사용해보도록 하겠습니다.

앞서 잠깐 언급했듯이 이 클래스를 이용하기 위해서는 Proxy 클래스가 필요합니다.

예를 들어 I-Shop  이라는 쇼핑몰 프로젝트를 한다고 칩니다.

그러면 이 솔루션에 해당되는 리소스를 담당하는 하나의 프로젝트를 생성합니다.

예를 들면 IShop.Resources 라는 프로젝트가 되겠습니다.

이 프로젝트는 RPNetworks.Resources 어셈블리를 참조해야 합니다.

프로젝트를 생성했으면 우선 리소스 파일을 생성합니다. 리소스 파일은 Resourcer.net 을 이용하면 편리합니다.

예를 들어 IShop.Web 이라는 프로젝트의 리소스 파일을 생성한다고 칩시다.

리소스 파일의 이름은 IShop.Web.String.resources 가 되겠습니다. 만약 영문이라면 IShop.Web.String.en.resources 가 될테고 문자열리소스가 아니라 이미지 리소스 라면 ISHop.Web.Image.resources 가 될것입니다.

이제 이 프로젝트에 proxy 클래스를 만들어 보겠습니다.

namespace IShop.Web
{
    public class StringProxy
    {
        private static CustomResourceManager rm;

        /// 
        ///  클래스의 정적 생성자입니다.
        /// 
        static StringProxy()
        {
            rm = new CustomResourceManager(ResourceType.String, typeof(StringProxy));
        }
        public static string Download_Migration_01
        {
            get { return rm.GetString("Download_Migration_01"); }
        }
    }
}

1행을 보면 IShop.Web 입니다.

네임스페이스는 현재 네임스페이스가 아니라 이 리소스를 사용할 곳의 네임스페이스를 지정해 주어야 합니다.
IShop.Web 이라는 프로젝트의 문자열 리소스 Proxy 클래스라는 의미가 되겠습니다.

이렇게 proxy 클래스를 생성하게 되면 코드에서는 StringProxy.Download_Migration_01 처럼 사용할 수 있게 됩니다.

간단하지욤?

다음에는 열거형을 사용하는 법을 알아 보도록 하겠습니다.


마지막 업데이트 : (1/5/2011 5:12:26 PM)




첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기



<< < 1 2 3 4 5 6 7 8 > >>