블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2794)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (11)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

 

한빛네트워크에는 양질의 칼럼들이 많이 있습니다.

다음은 한동훈님의 칼럼 중에 Advanced C#을 주제로 작성된 칼럼들의 링크입니다.

 

Advanced C# 1. UML
http://network.hanbitbook.co.kr/view.php?bi_id=589

 

Advanced C# 2. 인터페이스
http://network.hanbitbook.co.kr/view.php?bi_id=590

 

Advanced C# 3. 디자인 패턴(DP)과 Simple Factory Pattern
http://network.hanbitbook.co.kr/view.php?bi_id=593

 

Advanced C# 4. DP - Monostate, Utility, Singleton Pattern
http://network.hanbitbook.co.kr/view.php?bi_id=595

 

Advanced C# 5. DP - Factory Method
http://network.hanbitbook.co.kr/view.php?bi_id=596

 

Advanced C# 6. DP - Abstract Factory
http://network.hanbitbook.co.kr/view.php?bi_id=594

 

Advanced C# 7. DP - Builder
http://network.hanbitbook.co.kr/view.php?bi_id=600

 

Advanced C# 8. DP - Prototype 패턴
http://network.hanbitbook.co.kr/view.php?bi_id=601

 

Advanced C# 9. 알고리즘 분석(Algorithm Analysis)
http://network.hanbitbook.co.kr/view.php?bi_id=602

 

Advanced C# 10. 분할의 아름다움 - 재귀와 비재귀
http://network.hanbitbook.co.kr/view.php?bi_id=603

 

Advanced C# 11. 방정식, 미적분법 그리고 delegate
http://network.hanbitbook.co.kr/view.php?bi_id=614

반응형
Posted by blueasa
, |
[Korean]

1) CheckBox 생성

2) CheckBox - 속성 - Appearance 값을 Normal -> Button으로 변경

3) 사이즈 조절 하려면 CheckBox - 속성 - AutoSize = false 로 변경



[English]

1) Create CheckBox

2) CheckBox - Attribute(or Preference?) - Appearance Value : Normal -> Button

3) Adjust Size : CheckBox - Attribute(or Preference?) - AutoSize Value : false

반응형

'Programming > C#' 카테고리의 다른 글

sendmessage in C#  (1) 2010.12.27
C# SendMessage Keypress  (1) 2010.12.26
Microsoft Win32 to Microsoft .NET Framework API Map  (0) 2010.12.10
경로명,확장자 분리 함수 등등  (0) 2010.12.09
C# 디폴트 파라미터 따라하기  (0) 2010.12.03
Posted by blueasa
, |
반응형
Posted by blueasa
, |

string str = @"E:\JAVA\Sample\X509Test\minMain.java.bak";

            System.Diagnostics.Debug.WriteLine("경로명:" + System.IO.Path.GetDirectoryName(str));
            System.Diagnostics.Debug.WriteLine("확장자:" + System.IO.Path.GetExtension(str));
            System.Diagnostics.Debug.WriteLine("파일명:" + System.IO.Path.GetFileName(str));

            System.Diagnostics.Debug.WriteLine("분리자:" + System.IO.Path.AltDirectorySeparatorChar);
            System.Diagnostics.Debug.WriteLine("확장자유무:" + System.IO.Path.HasExtension(str).ToString());
            System.Diagnostics.Debug.WriteLine("순파일명:" + System.IO.Path.GetFileNameWithoutExtension(str));
            System.Diagnostics.Debug.WriteLine("root:" + System.IO.Path.GetPathRoot(str));
            System.Diagnostics.Debug.WriteLine("랜덤파일명:" + System.IO.Path.GetRandomFileName());
            System.Diagnostics.Debug.WriteLine("임시파일:" + System.IO.Path.GetTempFileName());
            System.Diagnostics.Debug.WriteLine("임시경로:" + System.IO.Path.GetTempPath());

 

            //---------------------------------------------------------------------------
            int n= str.LastIndexOf(@"\");
            System.Diagnostics.Debug.WriteLine("파일명:" + str.Substring(0, n));
            System.Diagnostics.Debug.WriteLine("경로명:" + str.Substring(n + 1, str.Length - n - 1));

반응형
Posted by blueasa
, |
예제 XML 파일 
1.<!--?xml version="1.0" ?-->     <myapp>        <welcome>Welcome to MyApp</welcome>        <farewell>Thank you for using MyApp</farewell>              <windows>         <windowname="MainFrame" w="400" h="250"y="15" x="5">       </window></windows>       <connectiontimeout="123.456000"ip="192.168.0.1">       </connection></myapp>

파일에서 읽을때
1.TiXmlDocument document;        document.LoadFile(_File_Name_);

문자열로 읽을때
1.TiXmlDocument document;        document.Parse(szXML);

Node와 Element를 가져올때
1.TiXmlElement* pRoot = document.FirstChildElement("MyApp");        if( NULL == pRoot ) return FALSE;        char* szRootName = pRoot->Value(); //Value()를 사용하면 Node의 이름을 알수있다

각 태그의 속성값 읽어올때 
여기에선 위예제의 windows 태그의 속성을 읽어본다.
1.TiXmlElement* pElement = pRoot->FirstChildElement("Windows");        char* szName = pElement->Attribute("name");         char* szX = pElement->->Attribute("x");         char* szY = pElement->->Attribute("y");         char* szW = pElement->->Attribute("w");         char* szH = pElement->->Attribute("h");

정수형으로 읽고 싶으면~
1.int x;pElement->Attribute("x", &x);

모든 속성값을 한번에 읽어올때
1.TiXmlElement* pElement = pRoot->FirstChildElement("Windows");          TiXmlAttribute* attrib = pElement ->FirstAttribute(); //pElement의 속성을 받아온다.     while(attrib)   {           const char* szAttribute = attrib->Value();             attrib = attrib->Next();         }

Child Node를 순회 할때
1.TiXmlElement* pRoot = doc.RootElement();        TiXmlElement* pChild;        for(pChild = pRoot ->FirstChildElement() ; pChild != 0 ; pChild = pChild->NextSiblingElement())        { //Node를 돌면서..        }

Save XML 
Xml 형식선언할때
1.TiXmlDocument doc;   TiXmlElement* msg; TiXmlDeclaration* decl = newTiXmlDeclaration( "1.0""""" );   doc.LinkEndChild( decl );      //결과값 : <!--?xml version="1.0" ?-->

서브 노드를 추가할때
1.TiXmlElement * root = new TiXmlElement( "MyApp" );   doc.LinkEndChild( root );

주석문장을 추가할때
1.TiXmlComment * comment = new TiXmlComment();comment->SetValue(" Settings for MyApp " );  root->LinkEndChild( comment );

Message 서브노드와 하위 노드및 데이터를 추가할때
1.TiXmlElement * msgs = new TiXmlElement( "Messages" );       root->LinkEndChild( msgs );       msg = new TiXmlElement( "Welcome");       msg->LinkEndChild( new TiXmlText( "Welcome to MyApp"));       msgs->LinkEndChild( msg );       msg = new TiXmlElement("Farewell" );       msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" ));       msgs->LinkEndChild( msg );

노드를 추가하고 Attribute를 설정할때 레벨을 맞추기 위해서 root의 하위로 추가 한것을 주의 깊게 봐야 한다.
1.TiXmlElement * windows = new TiXmlElement( "Windows" );       root->LinkEndChild( windows );       TiXmlElement * window;     window =new TiXmlElement( "Window" );       windows->LinkEndChild( window );       window->SetAttribute("name""MainFrame");     window->SetAttribute("x", 5);     window->SetAttribute("y", 15);     window->SetAttribute("w", 400);     window->SetAttribute("h", 250);

Double 값 (소수점 값) 을 설정할때
1.TiXmlElement * cxn = new TiXmlElement( "Connection" );       root->LinkEndChild( cxn );       cxn->SetAttribute("ip","192.168.0.1");     cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib

Xml파일로 저장할때
1.// 파일로 저장      doc.SaveFile("text.xml");     //문자열로..     TiXmlPrinter printer;     printer.SetStreamPrinting();     Doc.Accept( &printer );      char* pAA = printer.CStr();                    // char* 를 반환한다.     std::string str = printer.Str();                  // std::string으로 반환한다.

반응형

'Programming > TinyXML' 카테고리의 다른 글

TinyXML Read  (2) 2010.12.08
TinyXML Write  (0) 2010.12.08
XML introduce(XML 문법 설명)  (0) 2010.04.27
Tiny XML 링크  (0) 2010.04.27
Posted by blueasa
, |

TinyXML Read

Programming/TinyXML / 2010. 12. 8. 14:43

C++용 XML 라이브러리가 몇가지 있다. MSXML 라이브러리, TinyXML 라이브러리가 있다.
작고 빠르다고 알려진 TinyXML 라비브러리를 알아 본다.

내가 사용한 버전은 TinyXML 2.5.3 버전이다. xmltet.cpp는 메모장에서 파일 인코딩을
UTF-8로 열고 유니코드 인코딩으로 재 저장하여 문자가 깨지지 않도록 한다.

TinyXML의 NodeType

TinyXml의 NodeType은 XML의 노드 타입과 대부분 비슷 하다.
XML 서적이나 문서를 보면 주석, 속성, TEXT, Element들의 최소단위는 노드이다. 
엘리먼트와 노드를 혼동하지 않도록 한다. 
TinyXML에서는 TiXmlElement노드가 TiXmlNode를 상속하고 있다.  

COMMENT 노드: 주석을 표현 하는 노드

ELEMENT 노드: 엘리먼트를 표현 하는 노이다.
              Test.xml에서는 root, food, name, country가 엘리먼트이다.
              (test.xml 파일은 아래에 나온다.)

TEXT 노드: 트리 구조상 최말단 노드로 문자 데이터를 표현하는 노드이다.

Attribute node: TinyXml 노드 타입에는 존재하지 않지만 TinyXml에서는 속성을 얻어                 올수 있는 메소드를 제공한다.

나머지 node 타입은 문서를 참고한다.

 

헤더 파일 포함

TinyXML 내부에서 자체 string 클래스 대신 std::string 클래스를 사용 할려면,
TIXML_USE_STL을 선언한다.
STL 사용에 필요한 헤더를 포함 시킨다.

#define TIXML_USE_STL    // TinyXML의 string대신 std::string을 사용할 경우.

#include “tinyxml.h”

 

#ifdef TIXML_USE_STL

    #include <iostream>

    #include <sstream>

    using namespace std;

#else

    #include <stdio.h>

#endif

 

라이브러리 링크

TIXML_USE_STL에 따라 라이브러리 링크를 다르게 설정한다.

//lib 파일 링크

 

#ifdef TIXML_USE_STL

 

#ifdef _DEBUG

#pragma comment(lib, "tinyxmld_STL")

#else

#pragma comment(lib, "tinyxml_STL")

#endif

 

#else

 

#ifdef _DEBUG

#pragma comment(lib, "tinyxmld")

#else

#pragma comment(lib, "tinyxml")

#endif

 

#endif

test.xml

읽을려는 XML 파일이다.

<?xml version="1.0" encoding="euc-kr"?>

<root>

  <!--각국의 대표 음식들이다.-->

  <food num="1">

      <name>김치</name>

      <country>대한민국</country>

  </food>

  <food num="2">

    <name>햄버그</name>

    <country>미국</country>

  </food> 

</root>

파일을 통해 읽을려면

    TiXmlDocument doc;

    doc.LoadFile("test.xml");

문자열을 통해 읽을려면

    TiXmlDocument doc;

    doc.Parse(szXML);

root 엘리먼트 노드를 읽는다.

TiXmlElement* rootElement = doc.FirstChildElement( "root" );

"root"의 자식 "food" 엘리먼트 노드를 읽는다.

    TiXmlElement*  element = doc.FirstChildElement( "root" )->FirstChildElement("food");

"food" 엘리먼트 노드를 반복해서 출력 한다.

    1     while( element )

    2     {

    3         //Value()는 현재 Node의 문자열을 넘겨준다.

    4         //GetText()는 현재 Text 타입 Node의 문자열을 넘겨 준다.

    5         //element->FirstChildElement()->Value()는 "name"을 넘겨준다.

    6         const char* num = element->Attribute( "num" );

    7         std::cout << "num Attribute: " << num << std::endl;

    8         std::cout << "name: " << element->FirstChildElement("name")->GetText() << std::endl;

    9         std::cout << "country: " << element->FirstChildElement("country")->GetText() << std::endl;

   10         element = element->NextSiblingElement( "food" );

   11     }

1: "food" 엘리먼트가 있을 때 까지 반복한다.

6: "num" 속성의 문자열을 읽어 온다.

속성을 정수로 읽을려면 다음과 같이 한다.
TiXmlAttribute* attr = element->FirstAttribute();
int n = attr->IntValue();

7: "name" 엘리먼트의 값을 읽는다.

8: "country" 엘리먼트의 값을 읽는다.

10: 다음 "food" 엘리먼트로 이동 한다.

 

XML 전체 파싱

ShowXML()은 XML을 파싱하여 보여주는 함수이다.
코드 설명은 생략....

void ShowXml(TiXmlNode *pNode)

{

       if(pNode)

       {

              switch(pNode->Type())

              {

              case TiXmlNode::COMMENT:

                    std::cout << "COMMENT: " << pNode->Value() << std::endl;

                    break;

              case TiXmlNode::DECLARATION:

                    std::cout << "DECLARATION: " << std::endl;

                    break;

 

              case TiXmlNode::ELEMENT:

                  {

                      std::cout << "ELEMENT: [" << pNode->ToElement()->Value() << "]" << std::endl;

                      TiXmlAttribute *pAttr = pNode->ToElement()->FirstAttribute();

                      while(pAttr)

                      {

                         std::cout << pAttr->Name() << "=\"" << pAttr->Value() << "\"" << std::endl;

                         pAttr = pAttr->Next();

                      }

                  }

                  break;

 

              case TiXmlNode::TEXT:

                   TiXmlText* pText = pNode->ToText();

                   if(pText)

                       std::cout << "TEXT:  " << pText->Value() << std::endl;

                   break;

              }

 

              for(TiXmlNode *pNext = pNode->FirstChild(); pNext; pNext = pNext->NextSibling())                     ShowXml(pNext);

       }

}

소스

tinyxml.zip

참조:

http://hanburn.tistory.com/7

http://hanburn.tistory.com/8


출처 : http://dolphin.ivyro.net/file/algorithm/etc/tinyXml_read.html

반응형

'Programming > TinyXML' 카테고리의 다른 글

TinyXml 사용법 요약  (0) 2010.12.08
TinyXML Write  (0) 2010.12.08
XML introduce(XML 문법 설명)  (0) 2010.04.27
Tiny XML 링크  (0) 2010.04.27
Posted by blueasa
, |

TinyXML Write

Programming/TinyXML / 2010. 12. 8. 14:36

TinyXML Read의 test.xml과 같은 포맷으로 XML 파일을 저장해 보자.
저장될 파일은 다음과 같다.

test_write.xml

<?xml version="1.0" encoding="euc-kr" ?>

<root>

    <!--각국의 대표 음식들이다.-->

    <food num="1">

        <name>김치</name>

        <country>대한민국</country>

    </food>

</root>

XML 형식 선언

TiXmlDocument doc; 

TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "euc-kr", "" ); 

doc.LinkEndChild( decl );

우리나라 문자셋의 1.0 버전이 만들어 진다.

서브 노드 추가

TiXmlElement * root = new TiXmlElement( "root" ); 

doc.LinkEndChild( root );

"root" 엘리먼트를 추가한다. TinyXML에서 노드를 추가 할 때, new로 생성한 엘리먼트는
내부에서 자동으로 삭제 되기 때문에 해제 할 필요가 없다.

주석 추가

TiXmlComment * comment = new TiXmlComment();

comment->SetValue( "각국의 대표 음식들이다." ); 

root->LinkEndChild( comment );

root의 자식으로 "food" 서브 노드 추가

TiXmlElement *food = new TiXmlElement( "food" ); 

root->LinkEndChild( food );

root의 자식이 되는 "food" 서브 노드를 추가한다.

food의 Attribute로 "num" 추가

food->SetAttribute("num", 1);   //food->SetAttribute("num", "1")와 동일

food->SetAttribute( "num", "1" )도 동일한 결과이다.

food의 자식으로 name 서브 노드와 값 추가

TiXmlElement *name = new TiXmlElement( "name" ); 

food->LinkEndChild( name ); 

name->LinkEndChild( new TiXmlText( "김치" ));

food의 자식 노드로 "name"을 추가하고 값은 "김치"이다.

food의 자식 노드로 country 서브 노드와 값 추가

TiXmlElement *country = new TiXmlElement( "country" ); 

food->LinkEndChild( country ); 

country->LinkEndChild( new TiXmlText( "대한민국" ));

food의 자식 노드로 "country"를 추가하고 값은 "대한민국"이다.

저장 하기

doc.SaveFile("test_write.xml");

SaveFile()을 통해 원하는 파일명으로 값을 저장한다.

전체 소스

void WriteXml()

{

    //형식 선언

    TiXmlDocument doc; 

    TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "euc-kr", "" ); 

    doc.LinkEndChild( decl );

 

    //서브 노드 추가

    TiXmlElement * root = new TiXmlElement( "root" ); 

    doc.LinkEndChild( root ); 

 

    //주석 추가

    TiXmlComment * comment = new TiXmlComment();

    comment->SetValue( "각국의 대표 음식들이다." ); 

    root->LinkEndChild( comment ); 

 

    //root의 자식으로 food 서브 노드 추가

    TiXmlElement *food = new TiXmlElement( "food" ); 

    root->LinkEndChild( food ); 

 

    //food의 Attribute로 "num" 추가

    food->SetAttribute("num", 1);   //food->SetAttribute("num", "1")와 동일

 

    //food의 자식으로 name 서브 노드와 값 추가

    TiXmlElement *name = new TiXmlElement( "name" ); 

    food->LinkEndChild( name ); 

    name->LinkEndChild( new TiXmlText( "김치" ));

 

    //food의 자식으로 country 서브 노드와 값 추가

    TiXmlElement *country = new TiXmlElement( "country" ); 

    food->LinkEndChild( country ); 

    country->LinkEndChild( new TiXmlText( "대한민국" ));

 

    doc.SaveFile("test_write.xml");

}

콘솔 창으로 XML 파일 보여주기

void PrintXml()

{

    TiXmlDocument doc( "test.xml" );

    doc.LoadFile();

 

    //문자열로..

    TiXmlPrinter printer;

    printer.SetStreamPrinting();

    doc.Accept( &printer );

    const char* pStr = printer.CStr();        // char* 를 반환한다.

    printf( pStr );

#ifdef  TIXML_USE_STL

    const std::string str = printer.Str();    // std::string으로 반환한다.

#endif

}

XML 파일을 콘솔 창으로 보여준다...

소스:

tinyxml.zip

참조:

http://hanburn.tistory.com/7

http://hanburn.tistory.com/8


출처 : http://dolphin.ivyro.net/file/algorithm/etc/tinyXml_write.html

http://dolphin.ivyro.net/file/algorithm/etc/tinyXml_write.html

반응형

'Programming > TinyXML' 카테고리의 다른 글

TinyXml 사용법 요약  (0) 2010.12.08
TinyXML Read  (2) 2010.12.08
XML introduce(XML 문법 설명)  (0) 2010.04.27
Tiny XML 링크  (0) 2010.04.27
Posted by blueasa
, |
반응형
Posted by blueasa
, |
배포시에는 Dependency Walker(depends.exe)와 같은 도구를 사용하여 종속 DLL의 목록을 확인한다. 또한 2005이상의 VS(Visual Studio)는 manifest를 꼭 확인해서 사용한 dll과 버전을 확인해야한다. 

VC++ Library
그림 1(VS2005 기준)

그림은 VS2005를 기준으로 하고 있지만 다른 버젼도 위와 같은 규칙으로 명명되고 있다. xx는 각각의 버전을 나타내며 플랫폼 별로 x86,ia64,x64용이 따로 있다. u는 Unicode버전을 나타내고 m은 managed code를 사용했을때 사용되며 배포시 .NET Framework이 필요하다. 배포폴더에 manifest가 존재하면 같이 배포한다.

참고
Visual C++ Libraries as Shared Side-by-Side Assemblies - MSDN

64-bit 모드(IA64, X64)에 관해서


컴파일러와 라이브러리의 버젼을 나타내는 매크로

Predefined Macros - MSDN

_MSC_VER(MS 컴파일러)

  Visual Studio 4.0  1000
  Visual Studio 5.0  1100
  Visual Studio 6.0  1200
  Visual Studio .NET 2002  1300
  Visual Studio .NET 2003  1310
  Visual Studio 2005  1400
  Visual Studio 2008  1500

_MFC_VER(MFC 버젼)

 Visual Studio 6.0   0x0600
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900

_ATL_VER(ATL 버젼)

 Visual Studio 6.0   0x0300
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900


VC 6 이하(~ VS6)
VC6관련 DLL은 98이후부터는 운영체제에 포함되어 있다. 그러므로 현재는 배포시에 거의 문제될게 없다.

참고
ActiveX 배포를 위한 cab파일(MS) - inf파일에 링크를 추가해준다.
Vcredist.exe로 Visual C++ 응용 프로그램용 최신 런타임 구성 요소가 설치된다 - MSDN고객지원

VC 7.1(VS 2003)
VC7.1관련 DLL은 최신 운영체제라고 해서 더는 기본 내장을 해주지않기 때문에 응용 프로그램이 알아서 자기 디렉터리나 윈도우 시스템 디렉터리에다 구비해야 한다.

 vcredist_x86_2003.zip


VC 8이후(VS 2005~) 

Side by Side Asembly
2005부터는 side by side asembly라는 기술이 도입되어 VC관련 라이브러리들이 Windows 디렉토리 밑에 WinSxS (Windows Side-by-Side)라는 공유 폴더(native assembly cache)로 관리된다. side by side asembly는 DLL 충돌문제를 해결해서 각각의 어플리케이션에게 독립적인 DLL환경을 제공하기 위한것으로 여러버젼의 DLL들이 등록될수 있다. 복잡한 이과정을 간단하게 해결하는 방법으로 VC8부터는 재배포 패키지(Redistributable Package)라는 배포용 설치파일이 도입되어 공용 라이브러리를 자동으로 설치/등록해준다. 또한 프로젝트에서 자동 생성해주는 Manifest Flie에 사용된 DLL과 버전이 자동으로 입력되니 배포시는 꼭 확인하도록 한다. 
프로그래머나 사용자입장에선 관련 DLL을 포함만 하면 되는 기존 작업과 달리 설치파일이 하나 더생겼으니 귀찮은 작업이지만 최신 운영체제의 기본 관리 방법이기도 하고 .Net의 기술과도 무관하니 지금 정리하도록 하자.


최신 라이브러리를 Manifest에 기술하기(VC9)
배포방법을 알아보기 전에 알아두어야 할사항이 있다. VC9는 VC8과 달리 sp1같은 최신 라이브러리를 개발자PC에 설치했다고 해도 프로젝트가 최신라이브러리를 사용한다고 명시해주지 않으면 기존라이브러리를 기본으로 사용하므로 주의해야한다. 이것은 개발자가 sp1을 설치했어도 프로젝트는 기존 DLL버전을 사용하므로 배포시 sp1용 재배포 패키지를 사용하면 제대로 실행될 수 없음을 나타낸다. 방법은 아래와 같다.

'_BIND_TO_CURRENT_VCLIBS_VERSION'를 프로젝트 설정에서 선언해준다.
-> stdafx.h의 상단에 #define으로 입력해도 일반적인 프로젝트에선 상관없지만 프리컴파일드 헤더를 사용안하거나 외부라이브러리가 프로젝트에 미리 세팅되었을 경우 두개의 버전을 중복 사용하는 경우가 발생할 수 있으므로 프로젝트 설정에서 선언하길 권장한다. 이값은 CRT,MFC,ATL,OPENMP 4개의 '_BIND_TO_CURRENT...' 선언을 다 쓰겠다고 선언하는것이고 _BIND_TO_CURRENT_VCLIBS_VERSION의 기본값은 0으로 세팅되어있다.

Manifest File(2008 기준)


참고

응용 프로그램 재배포 및 특정 라이브러리에 바인딩 - MSDN

최신 라이브러리를 메니페스트에 기술하기


배포방법
그림1과 참고에 MSDN링크가 2005의 공용DLL 목록과 설명이다. side by side asembly로 인해 배포문제가 좀 복잡해져서 depends 만을 확인해서 관련 DLL을 포함한다고 제대로 실행된다는 보장을 받을 수 없게되었다. 일반적인 방법과 재배포 패키지를 사용하는 방법을 알아보자.

1. 정적 라이브러리(Static Library)를 사용한다.
실행파일이 커지긴 하나 제일 간단하다. MFC 라이브러리를 사용시는 MFC라이브러리를 정적으로 포함하면 CRT도 자동으로 /MT로 변경된다. 용량은 기본 MFC 다이얼로그 프로젝트가 52k정도에서 308k 정도로 커진다.
ATL과 OPENMP까지 사용한다면 웹에서 배포되는 ActiveX 같은 상황이면 용량때문에 고민해봐야할 문제이고 정적라이브러리도 동적라이브러리와 똑같다고는 하지만 몇가지 버그가 있으므로 주의하자.

참고
MFC Static으로 소켓사용시..

2. Manifest를 참조해서 기본 DLL을 배포한다.(Private Assembly)
배포방법이 바뀌었다곤 하나 관련 DLL을 포함해서 배포할수도 있다. VS의 설치폴더에 있는 공용DLL(Private Assembly)을 같이 배포하면 된다. 우선 Manifest로 사용한 DLL을 확인한후 "..\Microsoft Visual Studio X\VC\redist\"에서 관련 DLL(그림1참고)을 프로젝트 폴더에 포함한다. 이방법도 쉬운편이긴 하나 3MB정도의 크기인 재배포 패키지에 비하면 사용하는 라이브러리가 많을 수록 용량이 너무 큰편이다.(기본 CRT와 MFC라이브러리만 4.76MB - 2008sp1 기준)

3. 인스톨쉴드(Install Shield), 설치 프로젝트를 이용해서 재배포 패키지가 자동으로 설치되게 한다.
 -> 모든 프로젝트를 이렇게 만들긴 좀 귀찮다;;

4. .Net Framework(최신)를 설치한다.
.Net Framework를 설치하면 CRT관련 DLL만 같이 설치된다.(fx 3.5설치시 8.0과 9.0이 같이 설치됨)
managed로 컴파일했다면 .Net Framework는 필수이므로 고민할 문제가 아니지만 용량이 100메가도 훨씬 넘는다..;;

5. 재배포 패키지 - 아래에서 따로 설명한다.

위 방법 외에도 몇가지가 더 있으며 아래링크를 참조하기 바란다. 
RedistributingVisualCppRunTimeLibrary
Bootstrapper for the VC++ 2005 Redists (with MSI 3.1) - codeproject

재배포 패키지(Redistributable Package)
재배포 패키지는 Windows Installer 3.1을 필요로 하는 인스톨 파일이다. 한번 실행하기만 하면 자동으로 설치되지만 사용자 입장에선 불편한 사항이다. 하지만 Windows Installer의 Command line을 이용해서 몰래설치하는 방법이 있다. 이를 이용해서 런처형식의 프로그램을 만들면 Windows Installer 3.1의 설치유무와 재 배포 패키지 자동 설치를 하고 프로그램을 실행하게 할 수 있다. 좀더 범용적으로 사용하면 파일로 설치필요 설정값을 받아와서 COM관련 등록이나 웹배포시 ActiveX등록등을 자동으로 하게 만들수도 있다. 관련 소스가 정리되는 대로 블로그에 올리도록 하고 우선 VC6으로 재배포 패키지의 설치유무와 자동 실행하기 위한 코드를 설명하겠다.

1) 재배포 패키지 설치 유무 확인
재배포 패키지는 설치폴더에서 받거나(..\Microsoft Visual Studio X\SDK\v2.0\BootStrapper\Packages\vcredist_x86) 아래 링크를 통해 MS의 다운로드에서 받는다. 

2-1) 일반 적인 인스톨러 사용처럼 추가/제거 목록에 표시되므로 레지스트리 값으로 확인할 수 있다.
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ProductCode"

2-2) MsiQueryProductState API를 이용해서 확인한다.
리턴값으로 INSTALLSTATE_DEFAULT인지만 확인하면 설치유무를 판단할 수 있다.

위 2개의 방법에서 모두 필요한 ProductCode는 아래와 같다.

Visual C++ 2005 runtime files

Visual C++ 2005 SP1 runtime files

Visual C++ 2008 runtime files

Visual C++ 2008 SP1 runtime files

위코드는 영문 버전이고 한글버전은 다르고 설치시 중복될수 있다. ProductCode와 추가/제거에 표시되는 이름외에 다른점은 없다. 참고로 2008 sp1 x86 한글버전은 {887868A2-D6DE-3255-AA92-AA0B5A59B874}이다.
Window7에서도 테스트 했음.

참고
How to detect the presence of the VC 8.0 runtime redistributable package
How to detect the presence of the Visual C++ 9.0 runtime redistributable package
NSIS로 VC8.0 Redistributables 체크방법
MsiQueryProductState를 통한 VC 2005 Redistribute 라이브러리 설치체크 방법


2) 재배포 패키지 몰래 설치하기(Command Line)
명령행으로 실행시 Windows Installer 로 만들어진 패키지는 /?로 명령어 종류를 볼수 잇다.

Windows Installer V3.0.1.4001.5512 기준으로 캡쳐한화면


VS2005
VC2005의 경우는 재배포 패키지가 VS기본 폴더에 존재하는 설치파일과 웹에서 받은 파일이 좀 다른데 웹에서 받은 재배포 패키지의 경우 압축이 한번더 되어있어서 인자값 설정 방법이 다르다. 또한 압축이 몇번에 걸쳐 되어있으므로 한글로 계정이 되어있어 한글 경로가 있을 경우 잘 설치가 안될수도 있다. 필자는 2008을 사용하므로 2005에 대한 사항은 관련 링크로 정확한 정보를 얻자.
How to perform a silent install of the Visual C++ 8.0 runtime files (vcredist) packages 
- VS기본 폴더에 포함된 재배포 패키지 설치
VC 8.0 런타임 (vcredist) 패키지 몰래 인스톨하기 - 웹에서 받은 재배포 패키지 설치(번역)
Visual C++ 2005 재배포 패키지가 설치안될때



VS2008
2008에서는 
<full path>\vcredist_x86.exe /qb
<full path>\vcredist_x86.exe /qb!
<full path>\vcredist_x86.exe /q   -> 화면에 전혀 보이지 않음
위 3가지 방법중 선택해서 사용하면 되며 Vista이상의 경우는 /q로 설정해도 UAC가 보이므로 필자는 /qb!를 사용한다. 직접 사용해보고 판단하자.

참고
How to perform a silent install of the Visual C++ 2008 redistributable packages

99%'s Code
위 재배포 패키지 몰래설치하기 코드를 간단하게 정리했음.

1. 설치유무 판단후 재배포 패키지를 설치하고 원하는 파일을 실행한다.
01. // 2008 sp1
02.    CString csProduct = "{887868A2-D6DE-3255-AA92-AA0B5A59B874}";  
03.//{9A25302D-30C0-39D9-BD6F-21E6EC160475}
04. 
05.    INSTALLSTATE t = MsiQueryProductState(csProduct);
06.    if(INSTALLSTATE_DEFAULT != t)
07.    {
08.        AfxMessageBox("재배포 패키지를 설치하겠습니다.");
09. //    WinExec("vcredist_sp1_x86.exe /q",SW_SHOW);
10.        WinExec("vcredist_sp1_x86.exe /qb!",SW_SHOW);
11.        AfxMessageBox("설치 완료");
12. // xp에선 설치완료후 정확하게 뜨지만 Windows7에선 완료되지 않았는데 뜬다.
13.    }
14.    else
15.        AfxMessageBox("이미 설치됨");
16.    
17.    // 아래 레지스트리값의 유무로 판단할수도 있다.(win7에서도 똑같다.)
18.    //HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{887868A2-D6DE-3255-AA92-AA0B5A59B874}
19.    
20.    while(INSTALLSTATE_DEFAULT != MsiQueryProductState(csProduct))
21.        Sleep(30);
22.    WinExec("test.exe",SW_SHOW);    // 원하는 프로그램 실행

2. 제거
    WinExec("vcredist_sp1_x86.exe /qu",SW_SHOW);
    AfxMessageBox("제거 완료");

 
반응형
Posted by blueasa
, |

기본적으로 C#에서는 C++의 디폴트 매개변수 방법을 지원하지 않는 것 같다.

 

void func(int a, int b=1 ){ ... }

 

이런 함수가 있을 떄 디폴트 매개변수를 지원 안하면 같은 소스더라도 2배가 되기 때문에

 

디폴트 매개변수를 지정하는 것이 편할 때가 많았다.

 

하지만  C#에서는 지원을 따로 안하기 때문에 새로운 방법을 써야 한다.

 

public void func(int a){ func(a, 1); }

public void func(int a, int b){ ... }

 

이렇게 디폴트 파라미터가 필요없는 부분의 오버로딩시켜서 새로 호출 시키는 방법을 사용한다.

 

함수에 리턴값이 있을 경우는...

 

public int func(int a){ return func(a, 1); }

public int func(int a, int b){ ... }

반응형
Posted by blueasa
, |