posted by 방랑군 2012. 1. 8. 01:36

 급하게 테스트시 dataset 을 만들기 위해 xml 이나 db 로딩 말고 수동으로 만들때가 있다..

private DataTable GetDT()
        {
            DataTable dtdataTable = new DataTable();

            DataColumn col = new DataColumn("SEQ", typeof(Int32));

            col.AutoIncrementSeed = 1;
            col.AutoIncrement = true;
            col.AutoIncrementStep = 1;
            col.Caption = "Value ID";
            dtdataTable.Columns.Add(col);

            DataColumn[] Keys = new DataColumn[2];
            Keys[0] = col;
            dtdataTable.PrimaryKey = Keys;

            col = new DataColumn("TITLE", typeof(string));
            dtdataTable.Columns.Add(col);

            col = new DataColumn("CONTENTS", typeof(string));
            dtdataTable.Columns.Add(col);

            //col = new DataColumn("Value", typeof(string));
            //col.MaxLength = 50;
            //dtdataTable.Columns.Add(col);

            //col = new DataColumn("DateTime", typeof(Int32));
            //dtdataTable.Columns.Add(col);

            ArrayList ar = new ArrayList();
            ar.Add(1);
            ar.Add("a");
            ar.Add("b");

            dtdataTable.LoadDataRow(ar.ToArray(), true);

            ar.Clear();
            ar.Add(2);
            ar.Add("c");
            ar.Add("d");

            dtdataTable.LoadDataRow(ar.ToArray(), true);

            return dtdataTable;
            
        } 
posted by 방랑군 2012. 1. 8. 00:22

ASP.NET의 새 기능

ASP.NET은 오류를 처리하고 응답하는 방법에서 여러 가지 고급 기능을 제공합니다. 기존 ASP에서는 "On Error Resume Next"(또는 JScript의 try-catch 블록)로 오류를 처리합니다. 또는 Microsoft Internet Information Services(IIS) 5.0을 실행하는 경우 ASPError 개체를 사용하여 사용자 지정 오류 보고 페이지를 만듭니다. 그러나 이러한 방법에는 제한이 있습니다.

ASP.NET은 ASP.NET 응용 프로그램을 실행할 때 발생할 수 있는 오류를 처리하고 응답하는 방법을 여러 수준으로 제공합니다. ASP.NET은 오류가 발생할 때 오류를 잡고 응답할 수 있는 세 가지 기본 메서드인 Page_Error 이벤트, Application_Error 이벤트 및 응용 프로그램 구성 파일(Web.config)을 제공합니다.

이 문서에서는 ASP.NET 응용 프로그램의 새 기능을 사용하는 방법을 보여 줍니다. 이 문서에서는 ASP.NET과 직접 관련이 있는 사용자 지정 오류 페이지와 일반 오류 보고를 제공하는 방법을 설명하지만 try-catch-finally 블럭과 CLR(공용 언어 런타임) 예외 시스템 같은 기타 오류 처리 방법은 설명하지 않습니다.


Page_Error 이벤트를 사용하는 방법

Page_Error 이벤트는 페이지 수준에서 발생하는 오류를 잡는 방법을 제공합니다. 다음 예제 코드처럼 간단히 오류 정보를 표시하거나 이벤트를 기록하거나 다른 동작을 수행할 수 있습니다.

이 예제는 null 예외를 발생시켜 Page_Load 이벤트에서 강제로 오류가 발생하도록 합니다. 다음 절차에 따라 Page_Error 이벤트를 테스트하는 초기 페이지를 만듭니다.
  1. 다음 단계에 따라 PageEvent.aspx라는 이름의 새 파일을 프로젝트에 추가합니다.
    1. Microsoft Visual Studio .NET을 엽니다.
    2. 솔루션 탐색기에서 프로젝트 노드를 마우스 오른쪽 단추로 누르고 추가를 가리킨 다음 Web Form 추가를 누릅니다.
    3. 이름 텍스트 상자에 PageEvent.aspx를 입력한 다음 열기를 누릅니다.
  2. 아래 코드를 PageEvent.aspx에 추가합니다.
    <script language=C# runat="server">
         void Page_Load(object sender, System.EventArgs e)
         {
              throw(new ArgumentNullException());
         }
    
         public void Page_Error(object sender,EventArgs e)
         {
              Exception objErr = Server.GetLastError();
              string err = "<b>Error Caught in Page_Error event</b><hr><br>" + 
                  "<br><b>Error in: </b>" + Request.Url.ToString() +
                  "<br><b>Error Message: </b>" + objErr.Message.ToString()+
                  "<br><b>Stack Trace:</b><br>" + 
              Server.GetLastError().ToString();
              EventLog.WriteEntry("MyWebform.aspx",err,EventLogEntryType.Error);
              Server.ClearError();
              Response.Redirect("ErrorPage");
         }
    </script> 
  3. 파일 메뉴에서 PageEvent.aspx 저장을 누릅니다.
  4. 페이지를 마우스 오른쪽 단추로 누른 다음 브라우저에서 보기를 눌러 페이지를 실행합니다. 코드 사양에 따라 오류가 발생하고 보고됩니다.
코드는 Server.ClearError를 호출합니다. 이렇게 하면 Application_Error 이벤트를 계속 처리하는 오류가 방지됩니다.

참고: .aspx 페이지에서 Page_Load 이벤트와 같은 이벤트를 사용할 때 AutoEventWireup 특성 설정을 알고 있어야 합니다. Visual Studio .NET을 사용하는 경우 Visual Studio .NET이 기본적으로 추가하는 템플릿 코드에 이 특성이 @ Page 지시문과 함께 나열됩니다. AutoEventWireup 특성은 기본적으로 False로 설정됩니다. AutoEventWireupTrue로 설정되어 있지 않으면 Page_Load 코드는 절대 호출되지 않으며 그 결과 브라우저는 빈 페이지를 렌더링합니다.

또한 @ Page 지시문에서 Inherits 특성을 주목해야 합니다. Inherits가 설정된 경우 페이지를 탐색하기 전에 프로젝트를 빌드해야 합니다. 먼저 프로젝트를 빌드하지 않으면 다음과 같은 오류 메시지가 나타납니다.

"Project.PageEvent"는 유효한 형식이 아닙니다.

Application_Error 이벤트를 사용하는 방법

Page_Error 이벤트와 비슷하게 Application_Error 이벤트를 사용하여 응용 프로그램에서 발생하는 오류를 잡을 수 있습니다. 이벤트가 적용되는 응용 프로그램의 범위가 넓으므로 응용 프로그램 오류 정보를 기록하거나 다른 응용 프로그램 수준 오류를 처리할 수 있습니다.

다음 예제는 앞의 Page_Error 이벤트 코드 예제를 기반으로 하며 Page_Error 이벤트가 Page_Load 이벤트의 오류를 잡지 못하는 경우 실행됩니다. Application_Error 이벤트는 응용 프로그램의 Global.asax 파일에 지정됩니다. 이 절에서는 간단하게 새로운 페이지를 만들어 예외를 발생시키고, Global.asax 파일의 Application_Error 이벤트에서 오류를 잡고, 이벤트 로그에 기록하는 절차를 설명합니다. 다음 단계는 Application_Error 이벤트를 사용하는 방법을 보여 줍니다.

  1. AppEvent.aspx라는 이름의 새 파일을 프로젝트에 추가합니다.
  2. 아래 코드를 AppEvent.aspx에 추가합니다.
    <script language=C# runat="server">
        void Page_Load(object sender, System.EventArgs e)
        {
             throw(new ArgumentNullException());
        }
    </script>
  3. 파일 메뉴에서 AppEvent.aspx 저장을 누릅니다.
  4. Application_Error 이벤트를 Global.asax 파일에 추가하여 AppEvent.aspx 페이지의 Page_Load 이벤트에서 발생하는 오류를 잡습니다. 이벤트 로그를 사용하려면 System.Diagnostics 네임스페이스에 대해 다른 using 문을 Global.asax에 추가해야 합니다.

    아래 코드를 Global.asax 파일에 추가합니다.
    using System.Diagnostics;
    
    protected void Application_Error(object sender, EventArgs e)
    {
         Exception objErr = Server.GetLastError();
         string err = "<b>Error Caught in Application_Error event</b><hr><br>" + 
     "<br><b>Error in: </b>" + Request.Url.ToString() +
     "<br><b>Error Message: </b>" + objErr.Message.ToString()+ 
     "<br><b>Stack Trace:</b><br>" + 
     Server.GetLastError().ToString();
          EventLog.WriteEntry("Project.AppEvent.aspx",err,EventLogEntryType.Error);
          Server.ClearError();
    }
  5. Global.asax 파일을 저장합니다.
  6. Visual Studio .NET의 빌드 메뉴에서 빌드를 누릅니다.
  7. 페이지를 마우스 오른쪽 단추로 누른 다음 브라우저에서 보기를 누릅니다. 오류 메시지가 Application_Error 이벤트를 참조하고 이전 Page_Error 이벤트 예제와는 약간 다른 스택 추적을 표시합니다.


Web.config 파일을 사용하는 방법

Server.ClearError를 호출하지 않거나 Page_Error 또는 Application_Error 이벤트에서 오류를 잡지 않은 경우 오류는 Web.config 파일의 <customErrors> 구역에 있는 설정에 따라 처리됩니다. <customErrors> 구역에서 리디렉션 페이지를 기본 오류 페이지(defaultRedirect)로 지정하거나 발생하는 HTTP 오류 코드를 기반으로 특정 페이지를 지정할 수 있습니다. 또한 나타나는 오류 메시지를 사용자 지정할 수 있습니다.

오류가 발생하였는데 응용 프로그램의 이전 수준에서 잡지 못한 경우 사용자 지정 페이지가 표시됩니다. 이 절에서는 Server.ClearError가 절대 호출되지 않도록 Global.asax 파일을 수정하는 방법을 보여 줍니다. 결과적으로 오류를 잡는 마지막 지점인 Web.config 파일에서 오류가 처리됩니다.
  1. 이전 예제에 나타난 Global.asax 파일을 엽니다.
  2. Server.ClearError 줄을 주석으로 처리하여 Web.config 파일에 오류가 발생할 수 있도록 합니다.
  3. 변경 내용을 Global.asax에 저장합니다. 이제 코드는 다음과 비슷하게 나타납니다.
    using System.Diagnostics;
    
    protected void Application_Error(object sender, EventArgs e)
    {
         Exception objErr = Server.GetLastError();
         string err = "<b>Error Caught in Application_Error event</b><hr><br>" + 
               "<br><b>Error in: </b>" + Request.Url.ToString() +
               "<br><b>Error Message: </b>" + objErr.Message.ToString()+ 
               "<br><b>Stack Trace:</b><br>" + 
               Server.GetLastError().ToString();
         EventLog.WriteEntry("Project.AppEvent.aspx",err,EventLogEntryType.Error);
         //Server.ClearError();
    }
  4. 다음 코드를 <customErrors> 구역에 추가하여 사용자를 사용자 지정 페이지로 리디렉션합니다.
    <customErrors defaultRedirect
    ="http://hostName/applicationName/errorStatus.htm" mode="On"> </customErrors>
    참고: 관련 웹 서버와 응용 프로그램 이름을 참조하도록 defaultRedirect 특성에서 파일 경로를 수정해야 합니다.
  5. 이 수준에서 잡힌 오류는 기본 오류 페이지로 보내지기 때문에 ErrorStatus.htm이라는 이름의 오류 페이지를 만들어야 합니다. 사용자에게 표시하는 내용을 제어하기 위해 이 방법을 사용하는 것이므로 이 예제에서는 오류 페이지로 .htm 페이지를 사용합니다. 다음 코드를 ErrorStatus.htm에 추가합니다.
    <HTML>
    <HEAD>
    <TITLE></TITLE>
    <META NAME="GENERATOR" Content="Microsoft Visual Studio 7.0">
    </HEAD>
    <BODY>
         <b>Custom Error page!</b>
         <br>
         You have been redirected here from the &lt;customErrors&gt; 
    section of the Web.config file. </BODY> </HTML>
  6. 코드를 테스트하려면 파일을 저장하고 프로젝트를 빌드한 다음 브라우저에서 AppEvent.aspx를 봅니다. 오류가 발생하면 ErrorStatus.htm 페이지로 리디렉션됩니다.
<customErrors> 구역에 있는 defaultRedirect 특성의 값으로 기본 오류 페이지를 참조할 수 있지만 HTTP 오류 코드를 기반으로 하는 특정 페이지로 리디렉션하도록 지정할 수 있습니다. <error> 자식 요소는 이 옵션을 허용합니다. 예를 들면 다음과 같습니다.
<customErrors 
defaultRedirect="http://hostName/applicationName/errorStatus.htm" mode="On"> <error statusCode="404" redirect="filenotfound.htm" /> </customErrors>
참고: <customErrors> 구역의 defaultRedirect에 지정된 페이지는 .htm 파일입니다. Page_ErrorApplication_Error 예제 처럼 .aspx 페이지에서 GetLastError를 사용하려면 리디렉션이 발생하기 전에 세션 변수나 다른 방법에서 예외를 저장해야 합니다.

<customErrors> 구역은 On으로 설정된 mode 특성을 포함하고 있습니다. mode 특성은 오류 리디렉션이 발생하는 방법을 제어하는 데 사용됩니다. 예를 들어, 응용 프로그램을 개발 중이라면 대부분 사용자에게 익숙한 오류 페이지로 리디렉션되는 것보다 실제 ASP.NET 오류 메시지를 표시하는 것이 더 낫습니다. mode 특성을 다음과 같이 설정할 수 있습니다.
  • On: 처리되지 않은 예외는 지정된 defaultRedirect 페이지로 사용자를 리디렉션합니다. 이 모드는 주로 프로덕션 환경에서 사용됩니다.
  • Off: 예외 정보가 표시되고 defaultRedirect 페이지로 리디렉션되지 않습니다. 이 모드는 주로 개발 환경에서 사용됩니다.
  • RemoteOnly: localhost를 사용하여 로컬 컴퓨터에 있는 사이트에 액세스하는 사용자에게만 예외 정보가 표시됩니다. 다른 모든 사용자는 defaultRedirect 페이지로 리디렉션됩니다. 이 모드는 주로 디버깅에 사용됩니다.

출처: 닷넷 (.NET) 프로그래머 모임 (http://cafe.daum.net/aspdotnet)

posted by 방랑군 2012. 1. 7. 21:56

출처 : http://blog.naver.com/umjunil?Redirect=Log&logNo=140035839239

정말 간만에 다시 글을 쓰게 되었네여~

세월아~ 네월아~~

오늘은 자동가입방지, 또는 자동댓글/글쓰기 방지를 위해 뭐좀 하나 만들어 보았습니다.

이번 방법은 제네릭 처리기를 이용하려고 합니다.

우선 다음과 같이 제네릭 처리기를 새항목 추가 합니다.

제네릭 처리기가 뭘까 해서 MSDN 을 보니…. 안나왔더군요~

우선 제네릭 처리기를 생성해 보기로 하겠습니다.

<![endif]>

.. 단순히 IHttpHandler 를 상속하였네요~

친절하게도 Hello World 와 함께 말이져~

요놈은 IIS C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll 과 같이 매핑이 되어있으며, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\Web.Config

<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory"

validate="true" /> 과 같이 핸들러가 등록 되어 있군요~,

결론은 IHttpHandler 를 구현하라는 것이네요.

그럼 ConfirmBitmapHandler.ashx 의 소스를 보여드립니다.

<%@ WebHandler Language="C#" Class="ConfirmBitmapHandler" %>

using System;

using System.Web;

using System.Drawing;

using System.Drawing.Imaging;

using System.Drawing.Drawing2D;

using System.Web.SessionState;

public class ConfirmBitmapHandler : IHttpHandler, IRequiresSessionState {

public void ProcessRequest (HttpContext context) {

context.Response.ContentType = "image/jpeg";

// 이미지 사이즈

int lenX = 80, lenY = 30;

Bitmap bm = new Bitmap( lenX, lenY );

Graphics g = Graphics.FromImage( bm );

// 배경으로 그라데이션 처리

LinearGradientBrush bgGr = new LinearGradientBrush(

new Point(0,0),

new Point(lenX, lenY),

Color.Blue,

Color.Black);

g.FillRectangle( bgGr, 0, 0, lenX, lenY );

// 5자리 숫자의 난수를 발생하여 텍스트를 만든다

string text = string.Empty;

Random rnd = new Random();

for(int i=0; i<5; i++)

{

text += rnd.Next(9).ToString();

}

// 텍스트를 그린다.

Brush textBrush = new SolidBrush( Color.White );

g.DrawString( text, new Font("굴림", 15), textBrush, 10, 5, StringFormat.GenericDefault );

// 스트림에 비트맵을 쓴다.

bm.Save( context.Response.OutputStream, ImageFormat.Jpeg );

// 5자리 숫자를 세션에 담는다.

context.Session["ValidateString"] = text;

}

public bool IsReusable {

get {

return false;

}

}

}

그럼 이제 우리가 만든 ConfirmBitmapHandler.ashx 를 브라우져 보기를 통해 실행해 보십시오

실행결과>>>

<![endif]>

오오~~~~~ 짝짝짝~~ 잘 실행이 되었네여~

그럼 다음으로 방금 만든 전처리기를 이용하여 웹어플케이션을 만들어 봅시다.

소스 ( Default.aspx )

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

private void Page_Load(object sender, EventArgs e)

{

}

protected void lnkValidate_Click(object sender, EventArgs e)

{

string validateString = (string)Session["ValidateString"] ?? string.Empty;

if (txtValidateString.Text == validateString )

lblResult.Text = "오케이~~ 통과~!";

else

lblResult.Text = "틀렷삼~~~~~ ";

}

</script>

<script type="text/javascript">

function checkEnter()

{

if( event.keyCode == 13 )

{

__doPostBack('lnkValidate','');

}

else

return true;

}

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>제목 없음</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<img src="ConfirmBitmapHandler.ashx" />

<p></p>

<asp:TextBox ID="txtValidateString" runat="server" onkeypress="return checkEnter()"></asp:TextBox>&nbsp;&nbsp;&nbsp;

<asp:LinkButton ID="lnkValidate" runat="server" OnClick="lnkValidate_Click">확인</asp:LinkButton>

<p></p>

<asp:Label ID="lblResult" runat="server"></asp:Label>

</div>

</form>

</body>

</html>

이 소스는 대부분 어렵지 않게 보실 수 있을 것 같아서 특별히 주석은 안달았습니다.

[출처] 제네릭 처리기를 이용하여 자동가입방지 폼 구현|작성자 땡초 
posted by 방랑군 2012. 1. 7. 21:01

출처 :  http://blog.naver.com/PostView.nhn?blogId=inidu2&logNo=110032861546&categoryNo=0&parentCategoryNo=33&viewDate=&currentPage=4&postListTopCurrentPage=1&userTopListOpen=true&userTopListCount=10&userTopListManageOpen=false&userTopListCurrentPage=4


인터넷이 연결이 되었는지를 체크하기위한 코드..

마이크로 소프트의 SmartClient Application Building Block 중에서 온라인 체크및 각종 기능이 있다는데.. 
간단히 코드로 확인하는방법이 ..

 

출처 : http://www.c-sharpcorner.com/Code/2003/Aug/CheckInternetConnection.asp

 

using System ;
using
 System.Runtime ;
using System.Runtime.InteropServices ;
 

public class InternetCS
{

//Creating the extern function...
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState( out int Description, intReservedValue ) ;

//Creating a function that uses the API function...
public static bool IsConnectedToInternet( )
{

int Desc ;
return InternetGetConnectedState( out Desc, 0 ) ;

}

}

 
 
인터넷이 끊어지는 상황이 발생 중간중간 연결 여부를 체크할 필요가 있어졌다.
연결이 되어 있을때만 실행. 
posted by 방랑군 2012. 1. 7. 21:00

출처 :  http://blog.naver.com/PostView.nhn?blogId=inidu2&logNo=110033716625&categoryNo=0&parentCategoryNo=33&viewDate=&currentPage=4&postListTopCurrentPage=1&userTopListOpen=true&userTopListCount=10&userTopListManageOpen=false&userTopListCurrentPage=4

 

플로우 차트만 보면 무척 간단하다.

업데이트할 내용이 있는지 검사해서 있으면 하고 없으면 말고. 이게 끝이다.

 

자동업데이트 기능은 인터넷의 혜택으로 인해 요즘 프로그램에선 필수 이다.

예제 보고 간단하게 함 따라 해봤는데 나름대로 구미에 맞게 수정하다 보니 제법 그럴싸해졌다.

첨엔 ini 파일을 사용했는데 그거보단 레지스트리가 난거 같아서 레지스트리에 업데이트 정보를 저장해서 사용한다.

DB와 연동해서 프로그램별로 버전관리가 가능하게 했다.

 

 

업데이트 관리 DB – 업데이트 프로그램 통합 관리

3개의 테이블 사용 – 프로그램 관리업데이트 관리업데이트 로그

프로그램 아이디로 구분 하나의 자동업데이트 프로그램을 이용해 모든 프로그램에 적용하여 사용할 수 있다.

설정파일의 프로그램 아이디로 업데이트 관리 테이블을 검색하고 업데이트 내용을 가져와서 해당 파일들을 다운로드 받은 후 업데이트 결과를 업데이트 로그 테이블에 저장해준다.

각 프로그램 단위로 업데이트 상황을 파악할 수 있다.

 

업데이트 파일 검색

버전 정보를 날짜 형식으로 지정해서 현재 버전 보다 높은 버전이 있는지 검색

SELECT TOP 1 IDX, ID, VERSION, CONTENTS FROM UPDATE_LIST WHERE ID=@ID AND VERSION>@VERSION ORDER BY VERSION ASC

업데이트 로그 등록

업데이트할 모든 파일을 다운로드 받은 후 로그 기록

INSERT INTO UPDATE_LOG (UPDATE_IDX, IP, DOWN_DATE) VALUES (@IDX, @IP, GETDATE())

 

 

 

 

 

DB는 아무거나 상관없다.

처음에는 프로그램에서 직접 디비에 접속을 했는데 업데이트 로그 기록하려고 클라이언트의 IP정보를 어떻게 받아오나 고민하다가

좀더 효과적인 방법을 찾았다.

프로그램에서 디비에 직접 접속하는게 아니고 특정 웹페이지로 접속을 해서 업데이트 정보를 가져온다.

가져온 정보로 업데이트 하고 다시 웹페이지를 접속해서 로그를 저장하면 된다.

이렇게 하면 우선 프로그램에 디비 접속 정보가 없어도 되기 때문에 좀더 보안에 안전하다.

그리고 약간의 유연성이 더 있을 것 같다.

 

프로그램이 처음 실행될때 업데이트를 체크하도록 했는데 시작 프로그램에 등록해 놓으니 프로그램이 먼저 시작하고 나서 나중에

인터넷에 연결이 되는 상황이 발생한다.

인터넷 연결이 나중에 되더라도 프로그램이야 잘 돌아가지만 업데이트는 전혀 안되는 상황이 생길 수 있다.

그래서 프로그램 실행 중간에 한번씩 업데이트 체크하는 부분을 추가해야 된다.

 

 

08.08.06 보완사항

메인 프로그램에서 10초에 한번씩 작업을 진행하는데 타이머 위치가 잘못 되서 특정 예외 상황 발생시 거의 무한 루프에 빠져버리는 문제점을 발견했다.

몇일 쉬다가 다시 코드를 보니 원인 찾는데 넘 오래 걸렸다.

타이머 시작 위치 변경 해서 해결 했다.

 

40대의 컴에서 동시에 작업을 하다 보니 디비 서버가 뻗어버렸다.

디비서버 동시 접속수 늘려주고 디비 작업 후 연결 닫는 구문을 모두 추가해주었다.

 

메인 프로그램에서 자동업데이트 체크하는 부분하고 마무리 작업 처리하는 부분만 추가해주면 일단 마무리.

 

 

 

 

자동업데이트 소스

using System;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Web;
using Microsoft.Win32;
using System.Data.SqlClient;
using MySql.Data.MySqlClient;
using System.ComponentModel;

namespace Keyword_Search_Starter
{
    public partial class Starter : Form
    {
        private string sLocalFilePath;          // 실행 경로
        private string sServerFilePath;         // 다운받을 서버주소
        private string sResultMsg;              // 업데이트 체크 결과 메세지(Error, OK)
        private string sID = null;              // 프로그램 아이디
        private string sIDX = null;             // 업데이트 리스트 키값
        private string sAuto = null;            // 자동업데이트 유무(1, 0)
        private string sVersion = null;         // 업데이트 버전 - 6자리날짜(080803)
        private string sStartProgram = null;    // 업데이트 후 실행할 프로그램
        private string sUserIP = null;          // 접속 아이피 로그기록
        private int iUpdateCount = 0;           // 파일 다운로드 숫자 - 전송완료 될 때마다 증가함

        private string sRegKey = "Software\\Pharos";
        private string sUpdateAddr = "http://blog.naver.com/inidu2/Upload/UpdateListView.aspx";

        
        public Starter()
        {
            InitializeComponent();
        }


        #region Starter_Load 레지스트리 정보 읽기
        private void Starter_Load(object sender, EventArgs e)
        {
            sLocalFilePath = AppDomain.CurrentDomain.BaseDirectory;

            // 레지스트리 설정 내용 확인
            RegistryKey reg = Registry.LocalMachine;
            reg = reg.CreateSubKey(sRegKey);

            sID = (string)reg.GetValue("ID", null);
            sStartProgram = (string)reg.GetValue("StartProgram", null);
            sVersion = (string)reg.GetValue("Version", null);
            sAuto = Convert.ToString(reg.GetValue("Auto", null));
            if (reg.GetValue("UpdateAddr", null) != null)
            {
                sUpdateAddr = Convert.ToString(reg.GetValue("UpdateAddr", null));
            }

            lbTitle.Text += " ID : " + sID;

            GetUpdateList();
        }
        #endregion



        #region GetUpdateList() 업데이트 리스트 가져오기
        private void GetUpdateList()
        {
            string path = sUpdateAddr + "?id=" + sID + "&version=" + sVersion;

            try
            {
                HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(path);
                HttpWebResponse hwrp = (HttpWebResponse)hwr.GetResponse();

                Stream strm = hwrp.GetResponseStream();
                StreamReader sr = new StreamReader(strm);

                listView1.Items.Clear();
                int line = 1, n = 1;
                string temp = null;
                while (sr.Peek() > -1)
                {
                    temp = sr.ReadLine();

                    switch (line)
                    {
                        case 1: sResultMsg = temp; break;       // 결과 메시지
                        case 2: sUserIP = temp; break;          // 접속 IP
                        case 3: sIDX = temp; break;             // 업데이트 리스트 키
                        case 4: sVersion = temp; break;         // Version
                        case 5: sServerFilePath = temp; break;  // Path
                        default:                                // File List
                            listView1.Items.Add(n.ToString());
                            listView1.Items[n - 1].SubItems.Add(temp);
                            listView1.Items[n - 1].SubItems.Add("전송대기");
                            n++;
                            break;
                    }

                    line++;
                }
                sr.Close();
                strm.Close();
            }
            catch { }
            finally { }

            // 업데이트 항목이 없으면 무시하고 프로그램 실행
            if (listView1.Items.Count == 0)
            {
                AppStart();
            }
            else
            {
                btnStart.Enabled = false;
                DownLoad();
            }
        }
        #endregion

        

        #region DownLoad() 다운로드
        protected void DownLoad()
        {
            this.Cursor = Cursors.WaitCursor;
            // 다운로드할 파일이 있으면 다운로드
            if (listView1.Items.Count > 0)
            {
                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    string serverFile = sServerFilePath + listView1.Items[i].SubItems[1].Text;
                    string localFile = sLocalFilePath + listView1.Items[i].SubItems[1].Text;
                    try
                    {
                        WebClient webClient = new WebClient();
                        listView1.Items[i].SubItems[2].Text = "전송중";
                        webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                        webClient.DownloadFileAsync(new Uri(serverFile), @localFile);
                        listView1.Items[i].SubItems[2].Text = "전송완료";
                    }
                    catch (Exception ex)
                    {
                        listView1.Items[i].SubItems[2].Text = "전송에러";
                        MessageBox.Show(serverFile + "\r\n" + ex.Message + "\r\n" + ex.StackTrace);
                    }
                }
            }
            this.Cursor = Cursors.Default;
        }
        #endregion



        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            lbState.Text = e.ProgressPercentage.ToString() + "%";
        }



        #region Completed 전송완료
        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            iUpdateCount++;
            if (iUpdateCount == listView1.Items.Count)
            {
                this.UpdateLog();
                this.AppStart();
            }
        }
        #endregion



        #region AppStart() 프로그램 실행
        private void AppStart()
        {
            try
            {
                string AppPath = AppDomain.CurrentDomain.BaseDirectory;
                System.Diagnostics.Process ps = new System.Diagnostics.Process();
                ps.StartInfo.FileName = AppPath + sStartProgram;
                ps.Start();

                // 타이머 작업으로 업데이트 감시
                Application.Exit();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }
        }
        #endregion
        


        #region UpdateLog() 업데이트 로그 작성 및 버전 정보 업데이트
        private void UpdateLog()
        {
            // 레지스트리 설정 내용 확인
            RegistryKey reg = Registry.LocalMachine;
            reg = reg.CreateSubKey(sRegKey);

            reg.SetValue("Version", sVersion);
            reg.SetValue("LastUpdate", DateTime.Now);



            // 업데이트 로그
            string path = sUpdateAddr + "?mode=log&idx=" + sIDX;

            HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(path);
            HttpWebResponse hwrp = (HttpWebResponse)hwr.GetResponse();

        }
        #endregion
        


        private void btnStart_Click(object sender, EventArgs e)
        {
            DownLoad();
        }

    }
}

[출처] 자동 업데이트|작성자 파로스


 
posted by 방랑군 2012. 1. 7. 17:28
A
1. WebApplication or WebSite 에서는
this.Context 로 HttpContext 로 제어.

=> this.Context.Request.PhysicalApplicationPath

2. Windows 에서는 HttpRequest 에서 호출으로 제어.

-> Application.StartupPath
 

'PP > TIP' 카테고리의 다른 글

제네릭 처리기를 이용하여 자동가입방지 폼 구현  (0) 2012.01.07
C# 인터넷 연결 체크하기  (0) 2012.01.07
자동 업데이트  (0) 2012.01.07
this.Invoke 관련  (0) 2012.01.06
String <-> byte[] 변환  (0) 2012.01.06
posted by 방랑군 2012. 1. 6. 17:51

1.  // 소켓에 관련된 스레드가 돌고 있으므로 application 스레드와의 충돌을 피하기 위해 델리게이트를 이용 

        // 어플리케이션의 스레드에 포함되기 위해 델리게이트 이용
        public void LogWrite(string msg)
        { 
            // 소켓에 관련된 스레드가 돌고 있으므로 application 스레드와의 충돌을 피하기 위해 델리게이트를 이용합니다.
            LogWriteDelegate deleLogWirte = new LogWriteDelegate(AppendLog);
            // 생성한 델리케이트를 이용하여 invoke를 실행합니다.
            this.Invoke(deleLogWirte, new object[] { msg });
        }

        // 로그를 찍고 스크롤된 위치에 위치하도록 합니다.
        public void AppendLog(string msg)
        {
            try
            {
                txtOutput.AppendText(msg + "\r\n");
                txtOutput.Focus();
                txtOutput.ScrollToCaret();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        } 

2.
private void Form1_Load(object sender, EventArgs e)
{
            Thread t1 = new Thread(new ThreadStart(Listen));
            t1.Start();
} 

public void Listen()
{
            adtx ad = new adtx(textBox1.AppendText);
           
            IPAddress addr = new IPAddress(0);
            TcpListener server = new TcpListener(addr, 5425);
            server.Start();


            Invoke(ad, "서버시작");

            ...

}

 

Listen() 메소드는 별도의 작업자 쓰레드가 실행하는 메소드입니다.

 

즉, Listen() 메소드는 메인 쓰레드가 아닌 다른 쓰레드에서 실행됩니다.

 

그러므로,

 

Listen() 메소드의 코드는 별도의 작업자 쓰레드 상에서 실행되며,

 

메인 쓰레드에서 생성된 컨트롤에는 접근할 수 없습니다.

 

그렇지만,

 

           Invoke(ad, "서버시작");

메소드 호출을 통해, 간접적으로 메인 쓰레드의 컨트롤에 접근할 수 있습니다.

 

위의 문장은

 

           this.Invoke(ad, "서버시작");

다음과 같습니다.

 

여기서, this 참조는 Form 개체를 가리키는 것이지요.

 

별도의 쓰레드에서 메인 쓰레드의 컨트롤에 접근하려면,

 

Form 개체의 Invoke() 메소드를 호출하면 되는 구나~~

 

하고 알고 계시면 되겠습니다. 
posted by 방랑군 2012. 1. 6. 15:36

출처 :  http://blog.naver.com/lcsco?Redirect=Log&logNo=120136771146 

String -> byte[] 로 변환하는 방법

 

String str = "string test data " ;

byte[] result = System.Text.Encoding.Default.GetBytes( str );

 

 

- byte[] -> String   로 변환하는 방법

byte[]  byte1 = System.Text.Encoding.Default.GetBytes( "byte test data" );

String result = System.Text.Encoding.Default.GetString( byte1 );


 

ps) 상황에 따라 엔코딩 방벙에는 Default, Unicode, UTF8, UTF16, UTF32등으로 사용 할 수 있다 .