이미지가 포함되어 있는 HTML파일을 MHTML파일로 저장시 이미지의 경로에 한글이 포함되면 이미지가 정상적으로 저장되지 않는다.

이미지를 포함해서 MTHML파일로 저장시에는 꼭 영문 경로로 된 곳에 이미지 파일을 놓고 HTML파일에 삽입시켜야 한다.


클래스 라이브러리를 웹에서 다운 받은 후 동적로딩하면 더 좋지 않을까? 란 생각에 다운로드받는 부분도 찾아봤다..

        private void Download(string strModule)
        {
            try {
                WebRequest ttt = WebRequest.Create("http://indra17.mireene.com/Test/" + strModule + ".dll");
                WebResponse mmm = ttt.GetResponse();
                Stream kkk = mmm.GetResponseStream();

                int BUFFER = 1024;
                BinaryWriter bw = null;
                BinaryReader br = new BinaryReader(kkk);
                try
                {
                    Byte[] data = new byte[BUFFER];
                    FileStream fs = new FileStream(System.IO.Path.Combine(m_strSavePath, strModule + ".dll"), FileMode.Create);

                    long total = 0;
                    int recv_size = 0;

                    long prg_value = 0;
                    long time = 0;

                    try
                    {
                        bw = new BinaryWriter(fs);

                        while (true)
                        {
                            recv_size = br.Read(data, 0, BUFFER);

                            if (recv_size <= 0) break;

                            bw.Write(data, 0, recv_size);

                            total += recv_size;
                        }
                        Console.WriteLine("Download Size = {0}", total);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    finally
                    {
                        if (bw != null) bw.Close();
                        if (br != null) br.Close();
                    }
                    fs.Close();

                    kkk.Close();
                    mmm.Close();
                } catch (ArgumentNullException ane) {
                    Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
                } catch (SocketException se) {
                    Console.WriteLine("SocketException : {0}",se.ToString());
                } catch (Exception e) {
                    Console.WriteLine("Unexpected exception : {0}", e.ToString());
                }
            } catch (Exception e) {
                Console.WriteLine( e.ToString());
            }
       }

'develop > windows' 카테고리의 다른 글

MHTML 저장 유의사항  (0) 2011.03.09
C#에서 클래스 라이브러리 동적 로딩  (0) 2010.09.29
C# ActiveX 만들기  (0) 2010.09.29
ActiveX 에서 다른 ActiveX를 생성할 때 주의점  (0) 2010.07.29
IObjectSafety  (1) 2010.02.03

// 클래스 라이브러리 로딩
Assembly assem = Assembly.LoadFile(System.IO.Path.Combine(m_strSavePath, strModule + ".dll"));

//타입 얻기
string strType = strModule.Substring(0, strModule.IndexOf("Library"));
//Type targetType = assem.GetType(strModule + "." + strType);
Type targetType = assem.GetType(strModule + "." + strType);

//객체 생성 - 디폴트 생성자 호출
Object obj = assem.CreateInstance(targetType.FullName);

//멤버에 값 설정 - 마지막 인수 5가 멤버에 값을 설정하는 부분 입니다.
//바인딩 플래그의 마지막이 셋필드임을 확인하실 수 있을 겁니다.
try
{
        strRes = (string)targetType.InvokeMember(strMethod,
        BindingFlags.InvokeMethod | BindingFlags.Instance |
        BindingFlags.Public | BindingFlags.Static, null, obj, new string[] { strParam });
}
catch(Exception e) {
        Console.WriteLine(e.ToString());
}



참고.
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=17&MAEULNo=8&no=82904&ref=82872

MSDN 검색
reflection, Dynamically Loading and Using Types


http://mixy.egloos.com/953406

    /// <summary>
    /// See Internet SDK, IObjectSafety.
    /// </summary>
    [Flags]
    public enum ObjectSafetyFlags : int
    {
        /// <summary>

        /// Caller of interface may be untrusted
        /// </summary>
        INTERFACESAFE_FOR_UNTRUSTED_CALLER = 1,

        /// <summary>
        /// Data passed into interface may be untrusted
        /// </summary>
        INTERFACESAFE_FOR_UNTRUSTED_DATA = 2,

        /// <summary>
        /// Object knows to use IDispatchEx.
        /// </summary>
        INTERFACE_USES_DISPEX = 4,

        /// <summary>
        /// Objects knows to use IInternetHostSecurityManager.
        /// </summary>
        INTERFACE_USES_SECURITY_MANAGER = 8,

        /// <summary>
        /// Flags combination.
        /// </summary>
        SafeForScripting = INTERFACESAFE_FOR_UNTRUSTED_CALLER |
        INTERFACESAFE_FOR_UNTRUSTED_DATA
    }

    [ComImport]
    [Guid("CB5BDC81-93C1-11cf-8F20-00805F3CD064")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        void GetInterfaceSafetyOptions(ref Guid riid, out int supportedOptions, out int enabledOptions);
        void SetInterfaceSafetyOptions(ref Guid riid, int optionSetMask, int enabledOptions);
    }
    [Guid("5E603C7D-4B7C-412a-BAB4-064E5674F97A")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [ComVisible(true)]
    public interface IActiveXControl_Method
    {
        [DispId(1)]
        string dispFunction(string str);
    }

[ProgId("TestServer.ActiveX")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("D2BD9E76-C60B-4724-B44E-986132D8FA7A")]
    public partial class Server : UserControl, IActiveXControl_Method, IObjectSafety
    {
        #region For Registration
        [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            //Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            //Open the CLSID\{guid} key for write access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            //And create the 'Control' key - this allows it to show up in
            //the ActiveX control container
            RegistryKey ctrl = k.CreateSubKey("Control");

            ctrl.Close();

            //Next create the CodeBase entry - needed if not string named and GACced.
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
            inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
            inprocServer32.Close();

            //Finally close the main key
            k.Close();
        }

        [ComUnregisterFunction()]
        public static void UnregisterClass(string Key)
        {
            StringBuilder sb = new StringBuilder(Key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            //Open HKCR\CLSID\{guid} for write access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            //Delete the 'Control' key, but don't throw an exception if it does not exist
            k.DeleteSubKey("Control", false);

            //Next open InprocServer32
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);

            //And delete the CodeBase key, again not throwing if missing
            k.DeleteSubKey("CodeBase", false);

            //Finally close the main key
            k.Close();
        }
        #endregion

        #region IObjectSafety 멤버
        public void GetInterfaceSafetyOptions(ref Guid riid, out int supportedOptions, out int enabledOptions)
        {
            supportedOptions = enabledOptions = (int)ObjectSafetyFlags.SafeForScripting;
        }

        public void SetInterfaceSafetyOptions(ref Guid riid, int optionSetMask, int enabledOptions)
        {
        }
        #endregion

        string m_strSavePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Templates);

        public Server()
        {
            InitializeComponent();
        }

        #region IActiveX_Method
        public string dispFunction(string str)
        {
                       string strRes;

                        return strRes;
        }
        #endregion
  }


App::InitInstance 에서 AfxEnableControlContainer(); 함수를 꼭 호출해주어야 한다.

'develop > windows' 카테고리의 다른 글

C#에서 클래스 라이브러리 동적 로딩  (0) 2010.09.29
C# ActiveX 만들기  (0) 2010.09.29
IObjectSafety  (1) 2010.02.03
BOOST 컴파일 옵션  (0) 2010.02.03
메모리릭 발생 위치에 Breakpoint 설정하기  (0) 2010.02.03

ctrl 해더

#include <ObjSafe.h>

 DECLARE_DYNCREATE(CBTool2Ctrl)


// ObjSafe 시작
 DECLARE_INTERFACE_MAP()

 BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
  STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (
   /* [in] */ REFIID riid,
   /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
   /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions
  );
  STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (
   /* [in] */ REFIID riid,
   /* [in] */ DWORD dwOptionSetMask,
   /* [in] */ DWORD dwEnabledOptions
  );
 END_INTERFACE_PART(ObjSafe);
// ObjSafe 끝

ctrl 코드

// IObjectSafety 용 인터페이스맵입니다

BEGIN_INTERFACE_MAP( CBTool2Ctrl, COleControl )
INTERFACE_PART(CBTool2Ctrl, IID_IObjectSafety, ObjSafe)
END_INTERFACE_MAP()


/////////////////////////////////////////////////////////////
// IObjectSafety member functions

ULONG FAR EXPORT CBTool2Ctrl::XObjSafe::AddRef()
{
 METHOD_PROLOGUE(CBTool2Ctrl, ObjSafe)
 return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CBTool2Ctrl::XObjSafe::Release()
{
 METHOD_PROLOGUE(CBTool2Ctrl, ObjSafe)
 return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CBTool2Ctrl::XObjSafe::QueryInterface(
REFIID iid, void FAR* FAR* ppvObj)
{
 METHOD_PROLOGUE(CBTool2Ctrl, ObjSafe)
 return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

const DWORD dwSupportedBits =
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~ dwSupportedBits;

HRESULT STDMETHODCALLTYPE
CBTool2Ctrl::XObjSafe::GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
 METHOD_PROLOGUE(CBTool2Ctrl, ObjSafe)

 HRESULT retval = ResultFromScode(S_OK);

 // does interface exist?
 IUnknown FAR* punkInterface;
 retval = pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);
 if (retval != E_NOINTERFACE) {  // interface exists
  punkInterface->Release(); // release it--just checking!
 }

 // we support both kinds of safety and have always both set,
 // regardless of interface
 *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;

 return retval; // E_NOINTERFACE if QI failed
}

HRESULT STDMETHODCALLTYPE
CBTool2Ctrl::XObjSafe::SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
 METHOD_PROLOGUE(CBTool2Ctrl, ObjSafe)

 // does interface exist?
 IUnknown FAR* punkInterface;
 pThis->ExternalQueryInterface(&riid,(void**)&punkInterface);
 if (punkInterface) {// interface exists
  punkInterface->Release(); // release it--just checking!
 }
 else { // interface doesn't exist
  return ResultFromScode(E_NOINTERFACE);
 }

 // can't set bits we don't support
 if (dwOptionSetMask & dwNotSupportedBits) {
  return ResultFromScode(E_FAIL);
 }

 // can't set bits we do support to zero
 dwEnabledOptions &= dwSupportedBits;
 // (we already know there are no extra bits in mask )
 if ((dwOptionSetMask & dwEnabledOptions) != dwOptionSetMask) {
  return ResultFromScode(E_FAIL);
 }  

 // don't need to change anything since we're always safe
 return ResultFromScode(S_OK);
}

'develop > windows' 카테고리의 다른 글

C# ActiveX 만들기  (0) 2010.09.29
ActiveX 에서 다른 ActiveX를 생성할 때 주의점  (0) 2010.07.29
BOOST 컴파일 옵션  (0) 2010.02.03
메모리릭 발생 위치에 Breakpoint 설정하기  (0) 2010.02.03
MS Patch API  (0) 2010.02.03

bjam -sTOOLS=msvc-stlport -sBUILD="debug release <runtime-link>static/dynamic" -sSTLPORT_PATH="C:\Program Files\Microsoft Visual Studio\VC98\Include\stlport"

 

--with-library-name

 

--with-regex

--toolset=msvc-8.0

 

bjam --help

 

bjam [options] [install|stage]

 

  1. bjam --build-type=complete --build-dir="c:\boost-build" -sICU_PATH="c:\Project\icu4c-3_8_1-src\icu" -sICU_LINK="c:\Project\icu4c-3_8_1-src\icu\lib" --toolset=msvc --without-mpi --without-python install  

bjam --build-type=complete --build-dir="c:\boost-build" -sICU_PATH="c:\Project\icu4c-3_8_1-src\icu" -sICU_LINK="c:\Project\icu4c-3_8_1-src\icu\lib" --toolset=msvc --without-mpi --without-python install

--without-mpi, --without-python은 상황에 따라 추가하거나 제거하셔도 좋습니다.
--build-type=complete는 디버그, 릴리즈, 정적 라이브러리, 동적 라이브러리, 멀티 스레드등 모든 버젼을 컴파일합니다.

 

 

  나 같은 경우는
  command 창에서
  D:\SDK\boost_1_35_0\bjam debug link=static
  으로 빌드하였다.
  debug는 release, static은 dynamic으로 바꿀 수 있다.

'develop > windows' 카테고리의 다른 글

ActiveX 에서 다른 ActiveX를 생성할 때 주의점  (0) 2010.07.29
IObjectSafety  (1) 2010.02.03
메모리릭 발생 위치에 Breakpoint 설정하기  (0) 2010.02.03
MS Patch API  (0) 2010.02.03
File Drag & Drop  (0) 2010.02.03

메모리릭 발생 위치에 Breakpoint 설정하기

 

메모리릭이 발생하면 디버거를 종료했을 때 이런 메시지가 출력된다.

Detected memory leaks!
Dumping objects ->
{103144} normal block at 0x01C79B18, 12 bytes long.
Data: <            > 18 9B C7 01 18 9B C7 01 CD CD CD CD

왠 만하면 어느 파일의 몇 번째 줄에서 메모리릭이 발생했다고 알려주지만, 이 경우처럼 디버거가 알려주지 못하는 경우도 많고, for문 안에서 메모리릭이 발생하는 경우처럼 위치만 알아서는 정확히 언제 발생하는지 알기 어려울 때도 있다. 이럴 때 사용할 수 있는 것이 중괄호안에 들어있는 숫자다. 이 숫자는 메모리 할당 번호(Memory AlLocation Number)인데, 번호가 103144라는 것은 이 프로그램에서 할당받은 메모리 중에서 103144번째 블록이라는 뜻이다(헉... 내 프로그램이 메모리를 이렇게 많이 할당받았던가 -0-;;).

프로그램 코드의 적당한 위치에

_crtBreakAlloc = 103144; 
라 고 적어주고 디버거를 실행하면 이 메모리를 할당하려고 할 때 프로그램을 Break 시켜준다. 디버그 버전에서는 힙에 메모리를 할당할 때마다 crtdbg 라이브러리(이렇게 표현해도 되나?)가 이 변수를 체크해서 Break 해주는 것이다. 디버깅중에 Watch 윈도우에서 변수 값을 바꿔서 다른 메모리 할당 번호에서 멈출 수도 있다. 전역 변수 값을 변경하는 대신에

_CrtSetBreakAlloc(103144); 
라고 함수를 호출해주어도 마찬가지 효과가 있다.

MSDN 기술문서 중 "Detecting and Isolating Memory Leaks"를 참고했음.
 
//------------------------------------------------------------------------------------
사용 방법 설명
 

Detected memory leaks!
Dumping objects ->
{103144} normal block at 0x01C79B18, 12 bytes long.
Data: <            > 18 9B C7 01 18 9B C7 01 CD CD CD CD

추가 헤더 파일 : #include <crtdbg.h>
 
[MFC]
~App::InitInstance() 함수 상위에 아래와 같이 문제가 발생된 메모리 블럭 설정
    ...
 
    _CrtSetBreakAlloc(103144);
    _CrtMemDumpAllObjectsSince(0);
}
 
[Win32/Console]
main()
{
    ...
    _CrtSetBreakAlloc(103144);
    _CrtMemDumpAllObjectsSince(0);

'develop > windows' 카테고리의 다른 글

IObjectSafety  (1) 2010.02.03
BOOST 컴파일 옵션  (0) 2010.02.03
MS Patch API  (0) 2010.02.03
File Drag & Drop  (0) 2010.02.03
Remote Debugging  (0) 2010.02.03
MS Patch API... 프로그래밍

2008/05/13 18:13

복사 http://blog.naver.com/ships95/120051350941

회사에서 하는 업무중에서 직접적으로 돈과 관련 된 부분이 하나 있다.
고객에게 전달하는 파일의 양이 많을 때 사용하는 기술로
많은 큰파일을 전달할 시에 만약 고객이 이전 버전의 파일이 있다면 그파일과의 차분만 전달하고
그 차분파일(델타파일)을 이용해서 파일을 복구하면 전송시 드는 각종비용(특히 트래픽 사용량)을
줄이는 기술이다.

이 기술의 변형은 굉장히 많지만 이러한 생각이 기본적으로 나오게 된 곳은
웹서버에서 트래픽을 줄이기위한 기술에서 출발했다고 한다.

위의 까지는 서론이었고...

자 회사에서 지금까지 적용해서 사용했던 기술은 다음과 같다.
mspatch API : http://msdn2.microsoft.com/en-us/library/ms811406.aspx
mspatchc.dll 로 델타를 생성하고
mspatcha.dll 로 델타를 적용한다.
그리고 모든 windows OS를 지원하고 unix 계열의 지원은 되지 않는다.

하지만 관련 모듈이 16MB 에서 알려지지 않은 심각한 문제가 발생되었다.
아래 부분에 상세한 코드 및 설명이 있다.

 

-------------------------------------------------------------------------

 

BOOL CMakeDeltaCacheBase::MakeDeltaFile(LPCTSTR szFrom, LPCTSTR szDest, LPCTSTR szDelta, int nDeltaEngineType)

{

             PATCH_OLD_FILE_INFO_A ofi;

             ofi.SizeOfThisStruct = sizeof(PATCH_OLD_FILE_INFO_A);

             ofi.OldFileName                   = szFrom;

             ofi.IgnoreRangeCount = 0;

             ofi.RetainRangeCount = 0;

 

             CFileStatus st;

             CFile::GetStatus(szDest, st);                   

             ULONG lflags = (st.m_size >= 8 * 1024 * 1024) ? (PATCH_OPTION_USE_LZX_BEST | PATCH_OPTION_USE_LZX_LARGE) : PATCH_OPTION_USE_LZX_A;

             if (PATCH_OPTION_USE_LZX_A != lflags)

             {

                           logOutput("File size over 8MB option changed : %s\n", szDest);

             }

 

             BOOL bResult = CreatePatchFileEx(1, &ofi, szDest, szDelta, lflags, NULL, NULL, NULL);

             if(!bResult)

             {

                           DWORD dwError = ::GetLastError();

                           m_strErrorMessage = szarrMSC_ErrMessage[dwError - 0xC00E3101];

                           logOutput("[error] MakeDeltaFile(%s) ErrorCode(0x%08x)\n", szDest, ::GetLastError());

                           return FALSE;

             }

             Return TRUE;

}

 

BOOL CMakeDeltaCacheBase::ApplyDeltaFile(LPCTSTR szFrom, LPCTSTR szDest, LPCTSTR szDelta, int nDeltaEngineType)

{

             BOOL bResult = ApplyPatchToFileEx(szDelta, szFrom, szDest, PATCH_OPTION_USE_LZX_A, NULL, NULL);

             if(!bResult)

             {

                           DWORD dwError = ::GetLastError();

                           m_strErrorMessage = szarrMSA_ErrMessage[dwError - 0xC00E4101];

                           logOutput("[error] ApplyDeltaFile(%s) ErrorCode(0x%08X))\n", szDest, ::GetLastError());

                           return FALSE;

             }

 

             return TRUE;

}

 

위의 두개의 함수를 통해 mspatchc.dll mspatcha.dll 을 사용하는데

CreatePatchFileEx() 함수의 세번째 파라미터에 들어가는 szDest 파일의 크기가 16MB보다 큰 경우 CreatePatchFileEx() 통해서 델타파일이 생성되나

ApplyPatchToFileEx() 함수를 적용하면 ERROR_PATCH_DECODE_FAILURE 에러가 발생됨

 

-------------------------------------------------------------------------

 

이 문제를 MS에 문의 하였으나 깜깜 무소식...
그래서 해당 문제를 해결하기 위해 한동한 google에서 binary delta compression 을 주제로 검색을 하게 되었다.

ms, wikipedia 등등에서 검색을 해보니 다음과 같은 것으로 정리되었다.
1. vcdiff           http://www.faqs.org/rfcs/rfc3284.html
2. xdelta          http://xdelta.org/
3. msdelta       http://msdn2.microsoft.com/en-us/library/bb267312.aspx
4. zdelta         http://cis.poly.edu/zdelta/

간단히 설명하면
1. vcdiff : 델타에 관련된 논문.  아 어렵다...여기까지
2. xdelta : 최신 버전은 xdelta3 로 소스까지 있으며 속도는 가장 빠른 것으로 보인다.
3. msdelta : vista 부터 적용된 업데이트 관련 델타 엔진, ms에서 사용중임
4. zdelta : zlib을 바탕으로 수정된 것으로 매우 빠르고 델타생성 크기가 적절하다!

이중 zdelta는 속도와 델타파일의 크기가 매우 만족스러웠다.
msdelta 는 일단 mspatch API에서 발생되었던 문제 16MB 큰파일에 대한 처리가 해결되었으나 델타생성시 매우 긴 시간이 걸린다.
물론 델타의 크기가 매우 작은 장점이 있다. 델타 적용 속도는 zdelta와 비슷하거나 약간 더 걸리는 정도임.
기존의 mspatch가 평균적으로 봤을 때 크기는 가장 작다.
xdelta는 그냥 평범하다고 하는 편이 나을 것 같다. 물론 이곳에 적지 않는 그 기능상으로 문제가 많은 것들도 많지만 위의 리스트에서 보면 평범하다는 것이다.

그래서 zdelta library를 사용하기로 결정하고 회사내의 모든 파일을 적용해 봤는데...
어라라... 파일크기 1.58MB vxd 파일의 델타비교시 그냥 zip으로 압축한것과 동일한 크기의
델타파일이 생성되는 문제가 있었다.

하도 이상해서 이리저리 테스트 해보고 소스를 봤지만 흐...결코 쉽지 않았다.
그래서 해당 홈피에서 관련자 e메일 주소를 찾아서 이 내용을 영문으로 된 글을 보냈으나...
1MB 이상에서는 아주 비슷한 파일이라도 문제가 발생할 수 있다는 요지의 답변만 받았다.
차기버전이 준비중이지만 언제 나올지 모른다나 ㅜ.ㅜ

관련 소스를 더 보고 있어야 할지 고민중이다.
일단 사내의 모든 파일이 16MB보다 작다면 계속 mspatch API를 써야 할 것 같은데.
unix 로의 적용을 위해서는 zdelta를 적용하고 싶지만 문제가 있을 수 있고...

사내의 분들과 토론해본 결과 일단 해당 문제를 적절하게 해결하고
해당 기술은 보유해야 한다는 결론으로 나고 있다.

시간이 되면 zdelta 의 소스를 좀더 분석해야 할 것 같다.

 

그 이 후에 ...

 

http://dalhee.wowdns.com/tt/somy/trackback/78
에서는 16MB 제한이 있다는 것은 최근에 MS에서 나온 msdelta.dll 관련 문서
http://msdn2.microsoft.com/en-us/library/bb267312.aspx
에서 확인할 수 있었다.
(흠...최신문서에는 파일 크기에 대한 언급이 사라졌군...예전엔 언급이 있었었는데
16MB 제한이 있고 msdelta는 32MB 제한이 있다고...)


하지만 회사에서 잘 사용하던 델타 생성라이브러리 (mspatchc.dll) 이 최근들에
특정파일에 대해서 ERROR_PATCH_ENCODE_FAILURE = 0xC00E3101 오류를
내면서 델타를 만들지 못하는 문제가 심심치 않게 발생되었다.

이것으로 인해 ms 유료서비스를 받았지만 관련 문제에 대해서 이런 저런 답변을 받지
못하고 16MB 제한에 대한 것이 스펙이라는 말만 듣고서는 끝났다.
(하지만 이 DLL로 확인을 해보니 16MB 이상의 파일도 정상적으로 생성되었다!!! 해결!!!)

오늘 일하다가 갑자기 최신버전을 찾아볼까? 라는 생각에 구글신님에게 물어봐도
뾰족한 답을 듣지 못하다가 갑자기 MS SDK 최신버전에 혹시 있지 않을까? 라는 생각에
테스트를 위해서 설치한 VS2008 설치 폴더에 찾아보니!!!

기존에 사용하던 것보다 더 최신인 mspatchc.dll 을 찾을 수 있었다!!!
버전은 6.0.6000.16384 였고 기존에는 5.2.3760.0 였었다.
새로운 파일을 가지고 델타생성에 문제가 있던 셋에 테스트 해보니 성공!!!!!!! (으아앗!!!!!!)
정말 황당 그자체였다!!!

유료서비스를 받아도 못 해결했는데 이렇게 해결이 되다니!!!

버그 수정판이었고 해당 파일은 98에서도 정상적으로 동작함을 확인하였다.

 

출처: http://dalhee.wowdns.com/

[출처] MS Patch API...|작성자 비우꺼

'develop > windows' 카테고리의 다른 글

BOOST 컴파일 옵션  (0) 2010.02.03
메모리릭 발생 위치에 Breakpoint 설정하기  (0) 2010.02.03
File Drag & Drop  (0) 2010.02.03
Remote Debugging  (0) 2010.02.03
HTTP 에러  (0) 2010.02.03

파일 탐색기 등에서 파일을 드래그 & 드롭해서 내가 만든 프로그램에 놓았을 때,

WM_DROPFILES 이벤트가 발생됩니다. 이를 이용하기 위해서는 아래와 같이 코딩하면 됩니다.

 

1. ON_WM_DROPFILES()         // 클래스 위저드에서 WM_DROPFILES를 재정의한다.
2. DragAcceptFiles();

 

BEGIN_MESSAGE_MAP(CLeftView, CTreeView)
//{{AFX_MSG_MAP(CLeftView)
ON_WM_DROPFILES()         // 클래스 위저드에서 WM_DROPFILES를 재정의한다.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CLeftView::OnInitialUpdate() - oncreate()서 해도되고..
{
    CTreeView::OnInitialUpdate();
   

    // 파일 드래그 & 드롭을 위해 불러준다.
    DragAcceptFiles();
}

  

void CLeftView::OnDropFiles(HDROP hDropInfo)
{
    int nFiles;
    char szPathName[MAX_PATH];
    CString strFileName;
   
    // 드롭된 파일의 갯수
    nFiles = ::DragQueryFile( hDropInfo, 0xFFFFFFFF, szPathName, MAX_PATH );
//0xFFFFFF=-1이지?   


    for(int i = nFiles-1 ; i >= 0; i--)
    {
        // 파일의 경로 얻어옴
        ::DragQueryFile(hDropInfo, i, szPathName, MAX_PATH);
        AfxMessageBox( szPathName );
    }
   
    ::DragFinish(hDropInfo);
   
    CTreeView::OnDropFiles(hDropInfo);
}

 

 

 

-Drag기능 활성화
VOID DragAcceptFiles(<HWND hWnd,BOOL fAccept> or <bool>);->인자없이 쓰세요~


-HDROP에 대한 파일 경로를 얻어옴
UINT DragQueryFile(HDROP hDrop,UINT iFile,LPTSTR lpszFile,UINT cch);
hDrop:드랍될 파일들의 구조의 핸들(WParam)
iFile:드래그된 파일들의 인덱스
lpszFile:두번째에서 가리킨 인덱스의 파일 경로
cch:세번째 인자인 파일경로의 사이즈 

'develop > windows' 카테고리의 다른 글

BOOST 컴파일 옵션  (0) 2010.02.03
메모리릭 발생 위치에 Breakpoint 설정하기  (0) 2010.02.03
MS Patch API  (0) 2010.02.03
Remote Debugging  (0) 2010.02.03
HTTP 에러  (0) 2010.02.03

+ Recent posts