블로그 이미지
생각처럼

카테고리

전체보기 (209)
TOOL (1)
다이어리 (1)
Bit (200)
android (8)
C&C++ (3)
C# (26)
VB.Net (4)
MFC (0)
Win Ce (5)
아키텍쳐 (4)
WPF (9)
Rom (0)
읽어보기 (25)
Linux (24)
Java (0)
HELP? (0)
Total
Today
Yesterday

달력

« » 2025.1
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

공지사항

태그목록

최근에 올라온 글

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim Test_form As Form2
        Test_form = New Form2()
        Test_form.TopLevel = False  'toplevel 을 false 로 변경하면 panel form 에 docking 가능
        Test_form.Show()
        Me.Panel1.Controls.Add(Test_form)
    End Sub

 

'간단한걸 너무 헤매서...시간낭비를 많이 했음......역시 태크닉보다는 기본에 충실해야 된다는...

Posted by 생각처럼
, |

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

using System.Drawing.Drawing2D;
using System.Drawing.Imaging;


namespace ff
{
 /// <summary>
 /// Form1에 대한 요약 설명입니다.
 /// </summary>
 public class Form1 : System.Windows.Forms.Form
 {
  private System.Windows.Forms.Timer timer1;
  private System.Windows.Forms.Button button1;
  private System.ComponentModel.IContainer components;

  public Form1()
  {
   //
   // Windows Form 디자이너 지원에 필요합니다.
   //
   InitializeComponent();

   //
   // TODO: InitializeComponent를 호출한 다음 생성자 코드를 추가합니다.
   //
  }

  /// <summary>
  /// 사용 중인 모든 리소스를 정리합니다.
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if (components != null) 
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows Form 디자이너에서 생성한 코드
  /// <summary>
  /// 디자이너 지원에 필요한 메서드입니다.
  /// 이 메서드의 내용을 코드 편집기로 수정하지 마십시오.
  /// </summary>
  private void InitializeComponent()
  {
   this.components = new System.ComponentModel.Container();
   this.timer1 = new System.Windows.Forms.Timer(this.components);
   this.button1 = new System.Windows.Forms.Button();
   this.SuspendLayout();
   // 
   // timer1
   // 
   this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
   // 
   // button1
   // 
   this.button1.Location = new System.Drawing.Point(256, 0);
   this.button1.Name = "button1";
   this.button1.TabIndex = 0;
   this.button1.Text = "button1";
   this.button1.Click += new System.EventHandler(this.button1_Click);
   // 
   // Form1
   // 
   this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
   this.ClientSize = new System.Drawing.Size(344, 277);
   this.Controls.Add(this.button1);
   this.Name = "Form1";
   this.Text = "Form1";
   this.Load += new System.EventHandler(this.Form1_Load);
   this.Closed += new System.EventHandler(this.Form1_Closed);
   this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
   this.ResumeLayout(false);

  }
  #endregion

  /// <summary>
  /// 해당 응용 프로그램의 주 진입점입니다.
  /// </summary>
  [STAThread]
  static void Main() 
  {
   Application.Run(new Form1());
  }

  Image b1;
  Image b2;

  private void Form1_Load(object sender, System.EventArgs e)
  {
            b1 = new Bitmap("C:\\Documents and Settings\\won\\My Documents\\My Pictures\\10003307571.gif");
   b2 = new Bitmap(b1.Width*100, b1.Height);
   Graphics g = Graphics.FromImage(b2);
   g.FillRectangle(new SolidBrush(BackColor), 0,0, b2.Width,b2.Height);

   float[][] matrix = {
           new float[]{1,0,0,0,0},
           new float[]{0,1,0,0,0},
           new float[]{0,0,1,0,0},
           new float[]{0,0,0,0f,0},
           new float[]{0,0,0,0,1}
          };
   for(int i=0; i<99; i++)
   {
    ColorMatrix colMatrix = new ColorMatrix(matrix);
    ImageAttributes imgAtt = new ImageAttributes();
    imgAtt.SetColorMatrices(colMatrix, colMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
    
    g.DrawImage(b1, new Rectangle(i*b1.Width, 0, b1.Width, b1.Height), 0, 0, b1.Width, b1.Height,
     GraphicsUnit.Pixel, imgAtt);
    matrix[3][3]+=0.01f;
   }
   g.Dispose();
   timer1.Interval = 300;   
  }

  int p=0;
  private void timer1_Tick(object sender, System.EventArgs e)
  {
   Graphics g = this.CreateGraphics();
   g.DrawImage(b2, new Rectangle(0,0,b1.Width,b1.Height), p*b1.Width, 0, b1.Width, b1.Height, GraphicsUnit.Pixel);
   g.Dispose();
   p++;
  }

  bool timerState = false;
  private void button1_Click(object sender, System.EventArgs e)
  {
   if(timerState) 
   {
    timerState = false;
    timer1.Stop();
   }
   else
   {
    timerState = true;
    timer1.Start();
   }

  }


  private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
  {
   e.Graphics.DrawImage(b2, new Rectangle(0,0,b1.Width,b1.Height), p*b1.Width, 0, b1.Width, b1.Height, GraphicsUnit.Pixel);
  }

  private void Form1_Closed(object sender, System.EventArgs e)
  {
   b1.Dispose();
   b2.Dispose();
  }

 }
}


Posted by 생각처럼
, |
Posted by 생각처럼
, |

SubSonic 설치 방법 및 활용법

SubSonic 2008/07/14 16:37

 

 

0. 본 문서는

0.1 본문서의 목적

    본 문서는 ORM 툴의 일종인 SubSonic을 소개하고 간단한 활용법을 제시하여개발자들로 하여금

데이터베이스 액세스 코드를 작성하는 노력과 시간을 줄여주고본격적인ORM 툴들의(Nhibernate,

iBatis.Net 사용에 친숙해질 수 있도록 안내하기 위함입니다.

 

0.2 작성정보

    작성자 : OOO

    작성일 : 2008년 7월14

   

0.3 문서버전

    - 0.9

 

0.4 목차

  1. SubSonic 이란?

  2. SubSonic 설치

  3. Getting Started

  4. SubSonic을 활용한 CRUD 작업 예제

 

 

 

1. SubSonic 이란?

- SubSonice은 닷넷환경에서 활용할 수 있는 ORM 툴의 일종입니다.

  닷넷 기반에서 활용할 수 있는 ORM 툴의 종류는 대략 다음과 같습니다.

 

Open Source

NHibernate

- Java 버전인 Hibernate의 닷넷 포팅 버전

사용자층이 가장 넓은 정통 ORM 

iBatis.Net

- Java 버전인 iBatis의 닷넷 포팅 버전

- Hibernate와 더불어 사용자층이 넓으며 정통 

  ORM 툴이라기 보다는 Data Mapper에 가까움

- MySpace.com에서 사용됨

SubSonic

현재 Linq To Sql 개발팀의 일원인

Rob Connery에 의해 개발됨

- DAO 소스 자동 생산 기능이 뛰어남

상용

EntitySpaces

사용법은 SubSonic과 유사함

Microsoft

Linq To SQL

- .Net 3.0에서 제공하는 Linq의 일종

Entity Framework

- .Net 3.5 Extension에서 제공

테이블과 객체의 맵핑을 통한 정통 ORM

 

- SubSonict과 같은 ORM 툴을 활용하면

1) Data Access 코드를 작성하는데 들이던 시간과 노력을 줄일 수 있습니다.

2) 객체지향적 언어와 관계지향적 DB의 차이에서 오는 여러가지 문제들을 해결할 수 있습니다.

3) ORM 툴에서 제공해주는 쿼리 캐쉬 기능을 사용하여 퍼포먼스를 향상시킬 수 있습니다.

4) 쿼리를 사용할 때보다 코드가 직관적이 되므로 데이터 집중적인 어플리케이션을 제작할 수 있습니다.

5) ORM을 잘 사용하기 위해서는 근본적으로 DB의 정규화가 잘 이루어져서 조직화되어야 하므로 시간이 흘러도 어플리케이션의 일관성을 유지하는데 도움이 됩니다.

 

- SubSonic은 크게 두가지 기능을 제공합니다객체에 대한 질의를 DB에 대한 쿼리로 변경하여 결과값을 반환하는 역할과 DB의 테이블프로시져 들과 매칭되는DAO 코드를 자동 생산해주는 기능입니다.

 

 

 

2. SubSonic 설치

- SubSonic의 홈페이지는 http://subsonicproject.com/ 입니다.

  2008/7/14 현재 가장 최신 버전은 SubSonic 2.1 Beta3이며http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=subsonic&ReleaseId=11591에서 다운받을 수 있습니다.

 

Setup-SubSonic-2.1-Beta3.exe을 다운로드받은 후에 설치를 시작합니다.

 

설치가 끝났으면 자동 소스 생성 기능을 VS2005에서 사용하기 쉽도록 외부 도구 연결합니다.

  1) 메뉴  도구  외부도구 창을 띄운 후 추가 버튼을 클릭한 후 아래처럼 입력합니다.

     제목 : &SubSonic DAL

       명령 : C:\Program Files\SubSonic\SubSonic 2.1 Beta 3\SubCommander\sonic.exe

       인수 : generate /out Service

       초기디렉토리 : $(ProjectDir)

       인수확인 체크박스 체크!

       [명령항목의 값은 설치 경로에 따라 달라질 수 있습니다. [인수항목에서Service는 자동

       생산된 코드들이 위치할 폴더입니다.

 

  이것으로 SubSonic을 사용할 준비가 끝났습니다.

 

 

 

3. Getting Started

설치가 끝났으면 DB에 접속해서 데이터를 가져오는 간단한 어플리케이션을 만들어 보겠습니다예제는 윈폼기반 어플리케이션이며웹폼도 이와 별반 다르지 않으며 오히려 더욱 간단할 수도 있습니다.

 

1) MySubSonic 이라는 이름으로 윈폼어플리케이션을 만듭니다. DataGridView가 올려진 폼을 하나 만듭니다여기에 데이터를 출력하는 간단한 어플리케이션을 만들것입니다.

 

 

2) 아래의 라이브러리들을 참조 추가 합니다.

  - SubSonic.dll (기본경로에 설치하셨다면 C:\Program Files\SubSonic\SubSonic 2.1 Beta 3\SubSonic 폴더에 있을 것입니다. )

  - System.configuratiol

  - System.Web (윈폼일지라도 필수적으로 추가해야 합니다.)

 

3) App.Config를 추가한 후 아래의 내용을 삽입합니다.

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>

    <section name="SubSonicService" type="SubSonic.SubSonicSection, SubSonic"requirePermission="false" />

  </configSections>

  <appSettings/>

  <connectionStrings>

    <clear />

    <add name="AdventureWorks" connectionString="Data Source=(local);Initial Catalog=AdventureWorks;Persist Security Info=True;User ID=dbuserid;Password=dbpassword" />

  </connectionStrings>

  <SubSonicService defaultProvider="AdventureWorks">

    <providers>

      <clear/>

      <add name="AdventureWorks"

           type="SubSonic.SqlDataProvider, SubSonic"

           connectionStringName="AdventureWorks"

           generatedNamespace="Service"

           includeTableList="*"

           excludeTableList=""

           />

    </providers>

  </SubSonicService>

</configuration>

 

  여기엔 DB 커넥션 정보가 기재되어 있는데 여기에 기재된 DB의 테이블과 프로시져들을 기반으로 자동 소스 생성 작업이 진행됩니다. SQL Server 2005에서 제공하는 AdventureWorks 데이터베이스를 사용합니다위에서 generatedNamespace는 생설될 클래스의 네임스페이스 이름입니다여기선 Service 폴더에 생성 시킬것이므로 폴더명과 동일하게 주었습니다.

 

  - AdventureWorks DBhttp://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=4004 에서 다운받을 수 있습니다.

 

4) 다음엔 이전에 추가셔켰던 외부 도구로 가셔서 소스 생성만 시키면 됩니다.

 

 

5) 확인 버튼을 클릭합니다.

 

 

6) DB의 테이블과 프로시져에 대한 소스자동 생성 작업이 시작됩니다.

 

 

7) 소스 생성 작업이 끝나면 프로젝트를 선택하여 모든 파일 표시 버튼을 클릭한 후 Service 폴더를 프로젝트에 포함 시킵니다전체 솔루션 빌드 합니다.

 

8) 각 테이블마다 3개의 클래스가 생성됩니다.

 

9) 그럼폼의 Shown 이벤트에 간단히 테이터를 가져와서 데이터 그리드뷰에 바인딩해 보겠습니다.

 

10) Form1 Shown 이벤트에 아래의 소스를 입력합니다Product 는 테이블명입니다각자의 DB에 맞는 테이블명을 기재하시면 됩니다.

private void Form1_Shown(object sender, EventArgs e)

        {

            IDataReader reader = Product.FetchAll();

            DataTable dt = new DataTable("Product");

            dt.Load(reader);

            dataGridView1.DataSource = dt;

      }

 

11) Service 네임스페이스를 using에 추가합니다.

using Service;

 

12) 위의 과정을 별문제 없이 따라하셨다면 어플리케이션을 실행시킨후 목적하신 테이블의 데이터가 그리드에 바인딩되었을 겁니다코드를 보면 아시겠지만테이블에 맵핑된 Product 객체를 통해서 간단히 모든 데이터를 가져올 수 있습니다.

 

 

 

4. SubSonic을 활용한 CRUD 작업 예제

4.1 SELECT

    아래는 SubSonic 웹사이트에서 발췌한 것으로서 SELECT 형태의 쿼리에 사용할 수 있는 다양한 방법들을 소개하고 있습니다.

 

- Simple Select with string columns

            int records = new Select("productID").

                 From("Products").GetRecordCount();

 

- Simple Select with typed columns

            int records = new Select(Product.ProductIDColumn, Product.ProductNameColumn).

                From<Product>().GetRecordCount();

 

- Returning a Single object

            Product p = new Select().From<Product>().

               Where("ProductID").IsEqualTo(1).ExecuteSingle<Product>();

 

- Returning all columns

            int records = new Select().From("Products").GetRecordCount();

 

- Simple Where

            int records = new Select().From("Products").

                Where("categoryID").IsEqualTo(5).GetRecordCount();

 

- Simple Where with And (as Collection)

            ProductCollection products =

                DB.Select().From("Products")

                    .Where("categoryID").IsEqualTo(5)

                    .And("productid").IsGreaterThan(50)

                    .ExecuteAsCollection<ProductCollection>();

 

- Simple Inner Join

            SubSonic.SqlQuery q = new Select("productid").From(OrderDetail.Schema)

                .InnerJoin(Product.Schema)

                .Where("CategoryID").IsEqualTo(5);

 

- Simple Join With Table Enum

SubSonic.SqlQuery q = new Select().From(Tables.OrderDetail)

                .InnerJoin(Tables.Product)

                .Where("CategoryID").IsEqualTo(5);

 

- Multiple Joins As Collection

            CustomerCollection customersByCategory = new Select()

                .From(Customer.Schema)

                .InnerJoin(Order.Schema)

                .InnerJoin(OrderDetail.OrderIDColumn, Order.OrderIDColumn)

                .InnerJoin(Product.ProductIDColumn, OrderDetail.ProductIDColumn)

                .Where("CategoryID").IsEqualTo(5)

                .ExecuteAsCollection<CustomerCollection>();

 

- Left Outer Join With Generics

            SubSonic.SqlQuery query = DB.Select(Aggregate.GroupBy("CompanyName"))

                .From<Customer>()

                .LeftOuterJoin<Order>();

 

- Left Outer Join With Schema

            SubSonic.SqlQuery query = DB.Select(Aggregate.GroupBy("CompanyName"))

                .From(Customer.Schema)

                .LeftOuterJoin(Order.CustomerIDColumn, Customer.CustomerIDColumn);

 

- Left Outer Join With Magic Strings

            SubSonic.SqlQuery query = DB.Select(Aggregate.GroupBy("CompanyName"))

                .From("Customers")

                .LeftOuterJoin("Orders");

 

- Simple Select With Collection Result

            ProductCollection p = Select.AllColumnsFrom<Product>()

                .ExecuteAsCollection<ProductCollection>();

 

- Simple Select With LIKE

            ProductCollection p = DB.Select()

                .From(Product.Schema)

                .InnerJoin(Category.Schema)

                .Where("CategoryName").Like("c%")

                .ExecuteAsCollection<ProductCollection>();

 

- Using Nested Where/And/Or

            ProductCollection products = Select.AllColumnsFrom<Product>()

                .WhereExpression("categoryID").IsEqualTo(5).And("productid").IsGreaterThan(10)

                .OrExpression("categoryID").IsEqualTo(2).And("productID").IsBetweenAnd(2, 5)

                .ExecuteAsCollection<ProductCollection>();

            ProductCollection products = Select.AllColumnsFrom<Product>()

                .WhereExpression("categoryID").IsEqualTo(5).And("productid").IsGreaterThan(10)

                .Or("categoryID").IsEqualTo(2).AndExpression("productID").IsBetweenAnd(2, 5)

                .ExecuteAsCollection<ProductCollection>();

 

- Simple Paged Query

            SubSonic.SqlQuery q = Select.AllColumnsFrom<Product>().

               Paged(1, 20).Where("productid").IsLessThan(100);

 

- Paged Query With Join

            SubSonic.SqlQuery q = new Select("ProductId", "ProductName", "CategoryName").

                From("Products").InnerJoin(Category.Schema).Paged(1, 20);

 

- Paged View

            SubSonic.SqlQuery q = new Select().From(Invoice.Schema).Paged(1, 20);

 

- Simple IN Query

            int records = new Select().From(Product.Schema)

                .Where("productid").In(1, 2, 3, 4, 5)

                .GetRecordCount();

          

- Using IN With Nested Select

            int records = Select.AllColumnsFrom<Product>()

                .Where("productid")

                .In(

                new Select("productid").From(Product.Schema)

                    .Where("categoryid").IsEqualTo(5)

                )

                .GetRecordCount();Using Multiple INs

 

            SubSonic.SqlQuery query = new Select()

                .From(Product.Schema)

                .Where(Product.CategoryIDColumn).In(2)

                .And(Product.SupplierIDColumn).In(3);

 

 

 

4.2 INSERT

 데이터를 입력하는 여러가지 방법을 지원하지만 아래의 두가지 방법이 자주 사용됩니다.

 

// #1  테이블과 1:1 맵핑된 클래스를 이용하는 방법

                UserInfo u = new UserInfo();

                u.Id = "사용자아이디";

                u.KrNm = "사용자이름";

                u.Save();

 

 

                // #2  Insert 클래스를 이용하는 방법

                DB.Insert()

                .Into(UserInfo.Schema, new string[] { "ID""KR_NM" })

                .Values("사용자아이디""사용자이름")

                .Execute();

 

 

4.3 UPDATE

 데이터를 수정하는 방법은 여러가지를 제공하지만 아래의 방법이 자주 사용됩니다.

SqlQuery qry = new Update(UserInfo.Schema)

                                    .Set(UserInfo.KrNmColumn.ColumnName).EqualTo("노홍철")

                                    .Where(UserInfo.IdColumn.ColumnName).IsEqualTo("22401");

 

                int row = qry.Execute();

 

 

4.4 DELETE

 데이터를 삭제하는 방법도 여러가지 제공하지만 아래의 방법이 자주 사용됩니다.

SqlQuery qry = new Delete(UserInfo.Schema)

.Where(UserInfo.IdColumn.ColumnName).IsEqualTo("22401");

 

                int row = qry.Execute();

Posted by 생각처럼
, |
시나리오
Windows기반 응용 프로그램을 만든 다음, 설치하는 동안에 바로가기 및 파일 연결을 설정하고, 레지스트리에 엔트리를 추가하고, 사용자 지정 대화 상자를 표시하고, Internet Explorer 의 버전을 확인하는 설치 관리자를 만들어 보겠습니다.

1. 응용프로그램 만들기

배포프로그램을 만들 윈도우 폼 프로젝트를 생성합니다.
* 배포할 본인의 프로젝트를 열어도 상관 없습니다.
2. 배포 프로젝트 만들기
1.파일 - 2.추가 - 3.새 프로젝트 - 4.기타 프로젝트 형식 - 5.설치 및 배포 선택 - 6.템플릿에서 설치프로젝트 - 7.이름을 입력하고 확인버튼을 클릭한다. - 8.솔루션 탐색기에 지정한 이름의 프로젝트가 생성된다.
* 솔루션 탐색기에서 지정한 이름의 프로젝트를 선택 후 속성중에 ProductName 속성은 폴더 이름 및 프로그램 추가/제거 대화상자에 표시될 해당 응용 프로그램의 이름을 지정해 줍니다.


3. 응용프로그램이 설치될 경로 지정하기
솔루션 탐색기에서 - 프로젝트에서 오른쪽버튼을 클릭 후 - 보기 - 파일시스템 - 파일시스템 편집기에서 응용 프로그램 폴더를 선택 후 속성창에서 DefaultLocation을 수정해 주면 된다.



4. Windows 기반 응용 프로그램을 설치 관리자에 추가하기
1.솔루션 탐색기에서 지정한 이름의 프로젝트를 선택 - 2.가운데의 파일 시스템 편집기에 있는 응용 프로그램 폴더에서 오른쪽 버튼 클릭 - 3.추가 - 4.프로젝트 출력 선택한다. - 5.목록에서 “기본출력” 선택 후 확인버튼 클릭

응용프로그램을 설치하면 다음과 같이 생성됩니다.
* 저 응용프로그램이 나중에 인스톨하였을때 실행화일이 되는 것 입니다.


5-1. Windows 기반 응용 프로그램의 바로 가기 만들기
1.솔루션 탐색기에서 지정한 이름의 프로젝트를 선택 - 2.파일 시스템 편집기에서 “지정한 이름의 기본 출력(활성)”을 선택 오른쪽 버튼 클릭 후 - “지정한 이름의 기본출력(활성)의 바로 가기 만들기”를 클릭한다. - 3.그러면 “지정한 이름의 기본출력(활성)의 바로 가기” 가 추가된다. - 4.이름을 “지정한 이름의 바로가가” 로 변경한다. - 5.그리고 생성된 바로가기 노드를 좌측의 “사용자 바탕 화면” 으로 끌어다 놓는다.

* 이렇게 하면 설치 후 바탕화면에 응용프로그램의 바로가기가 생성됩니다.
"지금 Windows Installer의 기본 출력(활성) 바로 가기" 라고 되어있는데 이렇게 되면 나중에 설치하고 바탕화면에 이 이름 고대로 바로가기 아이콘이 생기게 됩니다. "Windows Installer 바로가기" 이렇게 간단하게 자기가 원하는데로 이름을 바꿀 수 있습니다.
5-2. 시작메뉴에 바로가기 만들기
1.”파일 시스템”창에서 “사용자 프로그램 메뉴”에서 오른쪽 버튼 클릭 - 2.추가 - 3.폴더 - 4.이렇게 하면 새 폴더 #1이라는 하위 메뉴가 생성이 됩니다. 이것은 이제 시작메뉴에서 폴더로 나오게 됩니다. 
- 5.이름을 프로그램 이름으로 변경 한다. - 6.”응용 프로그램 폴더”의 “지정한 이름의 기본 출력(활성)”에서 오른쪽 버튼 클릭 후 “test의 기본 출력(활성) 바로 가기”를 클릭한다. 7. 바로가기의 이름 지정 후 아까 만든 “사용자 프로그램 메뉴”의 하위 폴더에 끌어다 놓는다.
*이렇게 하면 나중에 응용프로그램 설치 후 시작 메뉴에 하위폴더의 이름으로 폴더가 생기고 바로가기가 들어가 있습니다.
* 전 "새 폴더 #1"의 이름을 WindowsInstaller프로그램 이라고 바꿨습니다.
* 나중에 인스톨을 하면 위에보시는 "Microsoft Windows SDK v6.0A" 부분과 같이 "WindowsInstaller프로그램"이라는 폴더가 생깁니다.
"Windows Installer의 기본 출력(활성) 바로가기"를 "WindowsInstaller프로그램"폴더로 드래그 앤 드롭 합니다.
6. Windows 기반 응용 프로그램에 대한 파일 연결하기
1.솔루션 탐색기에서 프로젝트를 선택하고 오른쪽버튼 클릭하여 - 보기 - 파일 형식을 클릭한다. - 파일 형식 편집기에서 “대상 컴퓨터의 파일 형식”노드를 선택하고 오른쪽 버튼을 클릭하여 - 파일 형식 추가를 클릭한다. 

* 파일 형식을 추가하게 되면 이미지 파일을 클릭하면 알씨 프로그램이 실행되는 것처럼 그 확장자의 파일을 실행하면 지금 설치한 프로그램에서 파일이 열리게 됩니다.

---------------------------------------------- 여기부터 다시 설명 -----------------------------------------------

7. Windows 기반 응용 프로그램에 레지스트리 항목 추가하기
*레지스트리 키와 값을 추가합니다. 응용 프로그램 코드에서 이 레지스트리 키를 참조하여 런타임에 사용자별 정보를 검색할 수 있습니다.
8. 사용자 지정 설치 대화 상자 추가하기(설치하는 동안 표시되는 사용자 지정 사용자 인터페이스 대화 상자를 추가하고 구성합니다.)
*프로그램에대한 샘플파일을 같이 설치할 것인지 물어보고 설치한다는 체크박스를 체크하면 샘플파일을 설치하는 실습을 하겠습니다.
1.솔루션 탐색기에서 프로젝트를 선택한다 - 마우스 오른쪽 버튼을 누른 후 - 보기 - 사용자 인터페이스 클릭한다. - 사용자 인터페이스 편집기에서 “시작”에서 오른쪽버튼 - 대화 상자 추가클릭 - 확인란 (A) 선택 후 확인 - 마우스로 “환영”밑으로 가져온다. - “확인란 (A)”에서 오른쪽 버튼 누른 후 “속성창”을 선택한다. - 속성창에서 “BannerText” 속성을 “샘플”로 설정 한다. - “BodyText”속성을 “샘플 설치 확인란은 샘플 파일의 설치 여부를 제어합니다. 확인란을 선택하지 않는 경우 샘플 파일은 설치되지 않습니다.” 으로 설정 - CheckBox1Label 속성을 “샘플을 설치하겠습니까?”로 설정 - 나머지 Checkbox2Visible등등의 속성을 False로 설정한다.
*이젠 “샘플을 설치하겠습니까?”라는 체크박스를 선택하면 샘플파일이 들어갈 폴더를 만들어 보겠습니다.

9. 샘플 폴더 추가하기(응용 프로그램 폴더 아래에 설치될 샘플이라는 하위 폴더 만든다.)
파일시스템 창에서 “응용 프로그램 폴더” 에서 오른쪽버튼을 누른 후 “샘플”이라는 폴더를 만든다.

10. 응용 프로그램의 샘플 파일 만들기
메모장을 이용하여 확장자가 jms인 파일을 만든다.

11. 설치 관리자에 샘플을 추가하기
파일시스템 창에서 - 응용 프로그램 폴더 - 샘플을 오른쪽버튼을 클릭한 후 - 추가 - 파일 - 그다음 아까 만든 jms파일을 추가한다. - 추가된 jms파일을 선택하고 속성창에서 “Condition”속성을 CHECKBOXA1=1 로 준다.
*바로가기 만들어서 추가해주기!”

12. Internet Explorer 버전 확인하는 시작 조건 추가하기
솔루션 탐색기에서 프로젝트를 선택하고 - 보기 - 시작조건 을 클릭한다. - 시작 조건 편집기에서 “대상 컴퓨터의 요구 사항”노드를 선택하고 오른쪽 버튼을 누른 후 “파일 시작 조건 추가”를 클릭합니다. 그럼 “대상 컴퓨터 검색” 노드 아래에 “파일 1 검색”노드가 추가되고 “시작 조건”노드 아래에 조건1 노드가 추가됩니다. - “파일 1 검색”의 이름을 “Internet Explorer 검색”으로 바꿉니다. - 그리고 속성 창에서 FileName속성을 “Iexplore.exe”으로 설정하고, Folder속성을 “[ProgramFilesFolder]”로 설정한다. 그리고 Depth속성을 2로 설정하고(파일을 검색할 하위 폴더의 수준을 지정해준다.) MinVersion속성을 5.00으로 설정한다. - 시작조건에 있는 “조건1”노드를 선택하고 Message속성을 “이 프로그램은 Microsoft Internet Explorer5.0 이상이 필요합니다. Internet Explorer를 설치하고 인스톨파일을 다시 실행해 주세요”라고 작성한다.
*이렇게 하고 테스트를 할 때 “대상컴퓨터검색”의 “Internet Explorer 검색”의 FileName속성을 “Iexplorer1.exe”로 바꿔준다. 그리고 “조건1”의 속성중 InstallUrl에 http://www.ehclub.net 으로 준다.
그러면 설치할 때 오류가 날 것이고 http://www.ehclub.net의 홈페이지가 열릴것이다.

13. 필수 구성 요소의 속성 설정하기
이번에는 대상 컴퓨터에 올바른 버전의 .net framework가 없을 경우에 .net framwork를 자동으로 설치하는 속성을 설정할 것 입니다. 
프로젝트에서 오른쪽 버튼 클릭 후 속성을 선택합니다. 속성페이지에서 “설치 URL”에서 응용 프로그램 및/또는 필수 구성 요소를 설치할 서버나 웹 사이트의 URL을 지정합니다. 그리고 필수 구성 요소 단추를 클릭합니다. 필수 구성 요소 대화 상자의 설치할 필수 구성 요소 선택에서 .Net Framework가 선택되어 있는지 확인 후 적용한다.
*필수 구성 요소를 설치하기 위한 설치 프로그램 만들기
  - 종속성 순서에 따라 응용 프로그램보다 필수 구성 요소가 먼저 설치되도록 응용 프로그램의 설치 프로그램(setup.exe)에 필수 구성 요소를 포함합니다. 이 옵션은 기본적으로 선택되어 있습니다. 이 옵션을 선택하지 않으면 Setup.exe 파일이 만들어지지 않습니다.

14. 버전을 통한 프로그램 설치하기
먼저 프로그램을 한번 설치를 한다. 그리고 다시 설치하는 모습을 보여준다. 그러면 제거할 것인지 복구할 것인지를 물어본다. 이것을 확인 한 후 - 솔루션 탐색기에서 프로젝트를 선택하고 속성창에서 Version을 1.0.1로 선택한다. - 그리고 RemovePreviousVersion을 True로 한다. 이렇게 하면 새버젼이 설치될 때 전버젼을 지우게 된다. 이렇게 해서 새로 빌드를 한 후에 다시 설치를 해보면 복구/제거라는 메시지가 안나오고 바로 설치하는 모습을 볼 수 있다.
 Windows Installer.docx 
Posted by 생각처럼
, |

treevew node 펼치기

Bit/C# / 2012. 2. 3. 17:06
전체 노드를 펼치기 : treeview1.ExpandAll();
특정 노드 펼치기    : treeview1.Nodes[0].Expand();
노드 펼침여부       : if(treeview1.Nodes[0].IsExpanded ==false)
                            {
treeview1.Nodes[0].Expand();
                             }
Posted by 생각처럼
, |

한글 깨짐 문제

Bit/C# / 2012. 2. 3. 17:04
Posted by 생각처럼
, |
Posted by 생각처럼
, |

I have an MDI application that allows me to open different types of child windows. I can open multiple (but different) instances of the same type of child window. (Example: I can open 3 instances of child window type A and 2 instances of child window type B. All 5 windows are distinct entities and do not share data until unless the user explicitly drags the same data onto multiple windows.) Each child window has a ToolStripContainer with one or more ToolStrips. How do I prevent:

  1. the user from dragging a ToolStrip from a child window of type A to a ToolStripContainer in a child window of type B?
  2. the user from dragging a ToolStrip from one instance of child window A to a ToolStripContainer in another instances of the same type of window?

I'm trying to prevent the user from dragging a ToolStrip from instance 1 of type A to instance 2 of type A, selecting some stuff on instance 2, and then clicking a button on the toolbar only to have something weird happen to some other window. Similarly it doesn't make sense to drag a ToolStrip from a window of type A to a window of type B -- the actions don't apply to that type, but to the user it looks like everything is fine because I let them do the drag.

Is it as simple as adding my own handler for the ControlAdded event or is there a better way to do this? I'm using WinForms in .NET 3.0.

edit: Steps to reproduce

  1. Create a new Windows Application project.
  2. Add a new user control. Give the control a ToolStripContainer that contains one ToolStrip with a single button.
  3. Repeat step 2, giving you a UserControl2 class.
  4. Compile the solution so UserControl1 and UserControl2 show up in your toolbox.
  5. Drag UserControl1 and UserControl2 onto the form. Set the borders so you know where the boundaries are.
  6. Run the app.
  7. It's now possible to drag the ToolStrip from the container in UserControl1 and drop it into the container in UserControl2 (leaving zero ToolStrips in UC1 and two ToolStrips in UC2.)
  8. Now imagine you only have access to the code in UserControl1. How do you prevent the user from dragging the ToolStrip out of that instance of the ToolStripContainer?
link|edit|flag

40% accept rate
I tried to reproduce the problem that you are having but I can't seem to get it to work. Once I create two instances of the same form I can't drag the toolbar from one to the other in the first place – Nathan W Nov 18 '08 at 22:39

This feels like a hack, but it works (kind of) (sorry, vb.net not c#):

Public Class UserControl2

   
Private Sub tsMainMenu_BeginDrag(ByVal sender As Object, ByVal e As System.EventArgs) Handles tsMainMenu.BeginDrag

        tsMainMenu
.Tag = tsMainMenu.Parent

   
End Sub

   
Private Sub ToolStrip1_EndDrag(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsMainMenu.EndDrag


       
If Not tsMainMenu.Parent.Parent.Equals(CType(tsMainMenu.Tag, ToolStripPanel).Parent) Then

           
CType(ToolStrip1.Tag, ToolStripPanel).Controls.Add(tsMainMenu)
       
End If

   
End Sub

End Class

simply put; when the control is finished being dragged, if its parent ToolStripContainer is not the same as it was when it started dragging, move the toolstrip back to where it was.

im sure this could be rolled into a control so that you dont have to write it for every toolbar.

Edit: You could put all this code into a control that inherits from ToolStripContainer, and have it do all the work for you, meaning a nice encapsulated solution.

Posted by 생각처럼
, |

윈폼에 엑셀 출력

Bit/C# / 2012. 2. 3. 17:02

엑셀의 경우 메크로 기능을 사용하면
거의 모든 프로그램이 가능하다.

아주 대단한 개발툴이 될수 있는것이다.

엑셀은 통계도 좋고, 프린트 하기도 아주 좋고. 뭐 두루두루 뛰어난다는거~^^

그런 엑셀을 엑셀 폼에 뛰우지 않고 윈도어플리케이션안에 띄어서 사용을 할경우 
필요할수 있을것 같다.

방법은 2가지 정도로 압축을 할수 있을것 같다

엑셀 Process를 윈도어플에 넣어주는 방법이 있을것이고
WebBrowser객체 안에 엑셀을 띄워 Browser를 WinApp에 넣어주면 될것이다.

첫번째 방법은
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

panContents.SuspendLayout();
runProcess = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = fileName;
info.WindowStyle = ProcessWindowStyle.Normal;
//info.Arguments = "10492";
runProcess = Process.Start(info);

SetParent(runProcess.MainWindowHandle, panContents.Handle);

panContents.ResumeLayout();

을 사용해서 가능할것이고

두번째 방법은
WebBrowser webBro = new WebBrowser();
 webBro.Dock = DockStyle.Fill;

webBro.Navigate(fileName);
panContents.Controls.Add(webBro);

이런식으로 처리를 하면 될것이다.

물론 더 좋은 방법도 있겠지만 내가 찾아낸 방법은 요정도..ㅎㅎ

Posted by 생각처럼
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함