winform 난독화 시, 엑셀 불러오기가 안됩니다.

제목 그대로, winform에서 엑셀파일을 불러오는 기능을 구현했는데
난독화 전에는 정상적으로 동작하지만, 난독화 후에는 아래와 같은 에러메세지가 발생하면서 불러오는데 실패합니다…

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'ProductRankTracker.Form1’에 'ReleaseObject’에 대한 정의가 없습니다.
위치: CallSite.Target(Closure , CallSite , Form1 , Object )
위치: System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
위치: ProductRankTracker.Form1.f(Object A_0, EventArgs A_1)

ReleaseObject에 대한 정의가 없다고 하는데 왜 난독화를 했을때만 정의가 없다고 하는걸까요…

2개의 좋아요

난독화 툴을 어떤것을 사용하시나요?
툴 마다 특정 클래스나 부분 정도를 난독화 하지 않도록 하는 옵션이 있습니다.

혹은 본인이 난독화가 필요하다고 판단되는 부분을 따로 라이브러리 프로젝트로 빼 내어 그 라이브러리 프로젝트만 난독화 시키는 전략도 유용 할 것 같습니다.

난독화와 함께 빌드를 하던 도중 비인딩을 포인팅하는 String 값역시 같이 난독화 되어, 오작동이 이러난 것이 아닐까하는 조심러운 추측을 해봅니다.

4개의 좋아요

난독화 툴은 PreEmptive Dotfuscator를 사용했습니다

아래 코드의 함수가 정의되지 않았다고 하는데, 함수의 위치를 바꿔보기도 해도 안되고 디버그모드로 확인도 못하니 이유가 짐작이 안가네요… ㅠㅠ

/// <summary>
/// 액셀 객체 해제 메소드
/// </summary>
/// <param name="obj"></param>
private void ReleaseObject(object obj)
{
    try
    {
        if (obj != null)
        {
            Marshal.ReleaseComObject(obj);  // 액셀 객체 해제
            obj = null;
        }
    }
    catch (Exception ex)
    {
        obj = null;
        throw ex;
    }
    finally
    {
        GC.Collect();   // 가비지 수집
    }
}
1개의 좋아요

난독화 규칙 어떤것 들을 넣었나요?

규칙에 따라 이슈가 날 수 가 있어서요~

1개의 좋아요

image

답이 조금 늦었네요… 위와같은 속성을 적용했습니다.
제가 툴 사용에 서툴러서그런데 제외해야할 속성이 있을까요??

1개의 좋아요

전부 제거해서 빌드 한번 해보시고
이상이 없다면 하나씩 해보시는것도 나쁘지않을 것 같습니다 :slight_smile:

1개의 좋아요

ReleaseObject 함수를 직접호출하지 않고 dynamic 형식으로 호출하셔서 Expression Tree 형태로 컴파일 된 뒤 난독화 후 해당 메소드를 찾지 못하는 문제 같습니다.
해당 메소드를 Interface로 정의해서 호출해보는 방법도 해결책이 될 것 같습니다.

또는 메소드 정의 위에 [Obfuscation(Feature = "renaming", Exclude = true)]와 같이 특성을 지정하면 해당 메소드에 대한 Rename 난독화 제외를 지정할 수 있는듯 합니다.

[Obfuscation(Feature = "renaming", Exclude = true)]
private void ReleaseObject(object obj)
{
  ...
3개의 좋아요

연휴가 껴있어서 확인이 늦었네요
저도 해당 프로그램을 다시 디컴파일해서 확인해보니까 해당 메소드명이 난독화로 바뀌면서 호출을 못하고
있는 문제를 확인했습니다.

호출은 이렇게 하는데 난독화과정에서 함수명이 바뀌어서 못찾고있더라구요…

Form1.b.d = CallSite<Action<CallSite, Form1, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.InvokeSimpleName | CSharpBinderFlags.ResultDiscarded, "ReleaseObject", (IEnumerable<System.Type>) null, typeof (Form1), (IEnumerable<CSharpArgumentInfo>) new CSharpArgumentInfo[2]
{
    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, (string) null),
    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, (string) null)
}));

그래서 알려주신 해결책대로 해결했습니다
답변 감사합니다!

4개의 좋아요