'c#'에 해당되는 글 3건
- 2007/11/07 C#으로 익스플로러 툴바 및 BHO만들기 (10)
- 2007/08/01 ASP.NET 유닛 테스트의 해부학
- 2007/07/30 C# on multicore processor (or multi processor) - 멀티 프로세싱을 위한 C#
사실 익스플로러 툴바, BHO(Browser Helper Object)를 만드는게 여간 힘든일이 아닙니다. COM을 써야할 뿐더러 일반적인 프로그램이 아니기 때문에 정보 조차 잘 없죠.
하지만 C#으로 만들면 정말 쉽습니다.
우선 전 코드 프로젝트를 참고했습니다.
Band Objects - .NET 2.0 Redux
http://www.codeproject.com/csharp/BandObjects20.asp?select=1819328&df=100&forumid=306921&exp=0
위의 소스 파일은 코드 프로젝트의 소스를 사용하기 쉽게 약간 수정한 파일입니다. 기본 구조는 코드 프로젝트 소스와 마찬가지로 BandObject클래스를 상속받는 것입니다.
우선 다음 두 개의 레퍼런스를 추가하도록 합니다. COM의 MSHTML(Microsoft HTML Object Library)과 SHDocVw(Microsoft Internet Controls) 입니다. 두 레퍼런스를 추가하면 Object Browser에서 이들 어셈블리를 볼 수 있습니다.
다음 단계는 BandObject클래스를 상속받아 실제 툴바를 구현하는 단계입니다. 아래 코드는 사용자 참여 웹 툴바에서 사용된 예이며, 툴바와 BHO 구현에 필요한 핵심적인 코드만 적어 놓았습니다. Guid는 자신의 Guid를 적으세요.
UserControl을 상속받으면 Visual Studio에서는 Designer로 폼을 편집할 수 있습니다. View Designer를 클릭해서 나오는 화면이 툴바에 나오게 될 화면입니다. 그 부분은 개발하고자 하는 툴바에 맞춰서 디자인 하시면 됩니다.
마지막 단계는 실제 툴바를 익스플로러에 등록하는 과정입니다. 우선 프로젝트 속성의 Assembly Information에서 Make assembly COM-Visible을 체크하고 컴파일을 합니다. 또 Strong name을 위해 Signing assembly (.snk)가 필요한데 이것 역시 프로젝트 속성에서 만들 수 있습니다.
그리고 빌드 후에 다음 명령을 실행 시킵니다. (Post build event에 등록 해놓으면 되겠죠.)
cd $(TargetDir)
하지만 C#으로 만들면 정말 쉽습니다.
우선 전 코드 프로젝트를 참고했습니다.
Band Objects - .NET 2.0 Redux
http://www.codeproject.com/csharp/BandObjects20.asp?select=1819328&df=100&forumid=306921&exp=0
위의 소스 파일은 코드 프로젝트의 소스를 사용하기 쉽게 약간 수정한 파일입니다. 기본 구조는 코드 프로젝트 소스와 마찬가지로 BandObject클래스를 상속받는 것입니다.
우선 다음 두 개의 레퍼런스를 추가하도록 합니다. COM의 MSHTML(Microsoft HTML Object Library)과 SHDocVw(Microsoft Internet Controls) 입니다. 두 레퍼런스를 추가하면 Object Browser에서 이들 어셈블리를 볼 수 있습니다.
다음 단계는 BandObject클래스를 상속받아 실제 툴바를 구현하는 단계입니다. 아래 코드는 사용자 참여 웹 툴바에서 사용된 예이며, 툴바와 BHO 구현에 필요한 핵심적인 코드만 적어 놓았습니다. Guid는 자신의 Guid를 적으세요.
[Guid("719FAB8A-8E67-4ba6-915D-4EE1AD3A2CEE")]
[BandObject("사용자 참여 웹 툴바", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar, HelpText = "사용자 참여 웹 툴바")]
public class UpwBandObject : BandObject
{
public UpwBandObject()
{
InitializeComponent();
minSize = new Size(100, 27); // 최소 크기를 반드시 적어줘야 합니다.
SetSiteEvent += new SetSiteEventHandler(UpwBandObject_SetSiteEvent);
ShowDWEvent += new ShowDWEventHandler(UpwBandObject_ShowDWEvent);
}
private void UpwBandObject_ShowDWEvent(bool fShow)
{
toolbarVisible = fShow;
RefreshCurrentSite();
}
private void UpwBandObject_SetSiteEvent(object pUnkSite)
{
if (pUnkSite != null)
{
// add events
webBrowserClass.BeforeNavigate2 +=
new DWebBrowserEvents2_BeforeNavigate2EventHandler(webBrowser_BeforeNavigate2);
webBrowserClass.NavigateComplete2 +=
new DWebBrowserEvents2_NavigateComplete2EventHandler(webBrowser_NavigateComplete2);
webBrowserClass.DocumentComplete +=
new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
}
else
{
// remove events
webBrowserClass.BeforeNavigate2 -= new DWebBrowserEvents2_BeforeNavigate2EventHandler(webBrowser_BeforeNavigate2);
webBrowserClass.NavigateComplete2 -= new DWebBrowserEvents2_NavigateComplete2EventHandler(webBrowser_NavigateComplete2);
webBrowserClass.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
}
}
private void webBrowser_BeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName,
ref object PostData, ref object Headers, ref bool Cancel)
{
}
private void webBrowser_NavigateComplete2(object pDisp, ref object URL)
{
}
private void webBrowser_DocumentComplete(object pDisp, ref object URL)
{
}
private void Navigate(string url)
{
object flags = null;
object targetFrameName = null;
object postData = null;
object headers = null;
webBrowserClass.Navigate(url, ref flags, ref targetFrameName, ref postData, ref headers);
}
}
컴파일 전에 System.Windows.Forms, System.Drawing 레퍼런스를 추가하고 다음 using을 코드에 넣습니다.
using System.Windows.Forms;웹 브라우저 클래스의 이벤트들이 바로 BHO부분입니다. 이벤트에 관련된 부분은 Visual Studio의 Object Browser를 보면서 추가할 수 있습니다. 물론 MSDN에도 짧게나마 설명이 있습니다.
using System.Runtime.InteropServices;
using SHDocVw;
using System.Reflection;
using System.Drawing;
using System.ComponentModel;
using Microsoft.Win32;
UserControl을 상속받으면 Visual Studio에서는 Designer로 폼을 편집할 수 있습니다. View Designer를 클릭해서 나오는 화면이 툴바에 나오게 될 화면입니다. 그 부분은 개발하고자 하는 툴바에 맞춰서 디자인 하시면 됩니다.
마지막 단계는 실제 툴바를 익스플로러에 등록하는 과정입니다. 우선 프로젝트 속성의 Assembly Information에서 Make assembly COM-Visible을 체크하고 컴파일을 합니다. 또 Strong name을 위해 Signing assembly (.snk)가 필요한데 이것 역시 프로젝트 속성에서 만들 수 있습니다.
그리고 빌드 후에 다음 명령을 실행 시킵니다. (Post build event에 등록 해놓으면 되겠죠.)
cd $(TargetDir)
"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil" /if Interop.SHDocVw.dll
"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil" /if $(TargetFileName)
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm" /unregister $(TargetFileName)
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm" /codebase $(TargetFileName)
익스플로러를 열면 툴바 영역에서 등록된 툴바가 메뉴에 표시됩니다.
디버깅은 프로퍼티의 Start Action에 externel program으로 익스플로러를 지정하면 됩니다.
혹시 궁금증 있으신 분은 코멘트를 남기시면 답변 드리겠습니다.
'Programming > .NET' 카테고리의 다른 글
| URL 상대 경로, 절대 경로 변환 클래스 (C#) (0) | 2008/03/13 |
|---|---|
| C#으로 익스플로러 툴바 및 BHO만들기 (10) | 2007/11/07 |
| C#에서 unmanaged 함수 호출하기. (0) | 2007/08/31 |
| .NET 2.0 C#의 Configuration Manager (0) | 2007/08/30 |
| C# on multicore processor (or multi processor) - 멀티 프로세싱을 위한 C# (0) | 2007/07/30 |
Visual Studio 2005의 특징 중 하나가 Unit Test입니다. 하지만 팀 버전 이상을 써야 가능하죠. 게다가 이클립스의 JUnit처럼 간단하고 깔끔하게 되는게 아닙니다.
윈폼용 유닛 테스트는 그리 낯설지 않지만, 문제는 ASP.NET의 경우입니다. 아래에선 제가 겪은 몇 가지 단점들 입니다. 일부 이슈에 대해서는 스트레스를 조금이나마 줄일 수 있는 팁을 적어 놓았습니다.
1. 속도
가장 먼저 유닛 테스트를 하게 되면 적잖게 당황하게 되는게, 속도 문제인데, 매우 느립니다. 대략 펜티엄4 3.0기가에서 테스트용 development server가 실행되고 테스트가 완료되는데 까지 거의 10초 이상이 걸립니다.
속도 정도야 애교죠. 유닛테스트가 보우하사 우리 코드를 지킬 수 있다면, 단 몇 초 여유롭게 기다리는게 코더의 노동보다 힘들까요?
2. 엑서서
두번째 문제는 엑서서입니다. 이클립스는 이 경우를 어떻게 해결했는지 잘 기억이 안나지만... (혹시 아시는 분은 리플을 달아주세요) VSTS(visual studio team system)의 유닛테스트는 클래스의 private, protected멤버 등을 접근하기 위해서 엑서서라는 클래스를 별도로 만듭니다. 테스트 프로젝트를 만들면 자동으로 생성되는 vscodegenaccessors.cs 파일이죠. 일반적으로 프라이빗과 프로텍티드 멤버를 외부에서 접근하지 못하는 것은 당연합니다. 아마 vsts에선 유닛테스트를 위해 별도의 편의?를 봐주지 않기 위해서 C#의 언어적 특성으로 이를 해결한 듯 합니다.
아무튼 이런 불편한 래핑 클래스인 엑서서의 등장으로, 프라이빗 메소드를 테스트 하려면 엑서서를 거쳐서 호출해야 합니다.
이 정도야 그냥 넘어갈 수 있다는 분!
만약에 테스트할 메소드의 signature가 수정되었다면 상황이 어떻게 될까요??
컴파일이 안됩니다.
그럼 어떻게 하나요 - 물론 엑서서는 vs에서 자동으로 만들어주긴 하지만, signature의 변경을 일일히 감지해서 알아서 척척 생성해 주지는 않습니다. 프로그래머는 메소드에서 오른쪽 버튼을 누른 후, create private accessor를 눌러서 엑서서가 자동으로 생성되게 해야 합니다.
3. 애트리븃
모든 테스트 메소드에는 아래와 같은 속성이 붙습니다.
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("website", "/pms")]
[UrlToTest("http://localhost/pms")]
public void InsertTaskTest()
덕지덕지 붙은게 여간 지저분한게 아니죠.
여기서 한가지 팁이 있다면, AspNetDevelopmentServerHost에 웹사이트 경로를 써 줘야 테스트가 돌아가는데 msdn에는 첫번째 인자에 full path를 쓰라고 되어있습니다. 하지만 상대경로를 써도 잘 작동합니다. (기본 웹사이트 경로가 vs 디폴트로 되어 있을때 그렇습니다. 만약 다른 폴더라면 옵션에서 바꿔주면 됩니다.)
4. 디버깅
와! 드디어 ASP.NET의 유닛테스트가 $0인 JUnit에 무릎을 꿇을 때가 왔습니다. 속도, 엑서서, 애트리븃에 불편한 인터페이스까지는 다 봐줍시다. 하지만 ASP.NET 유닛테스트의 디버깅을 생각해보면 저는 정말 화가 납니다. 안그래도 버그가 튀어났는데, 디버깅까지 불편하면 얼마나 화가 날까요??
설마 자바스크립트를 alert()으로 디버깅 하는정도 일까요?? 다행이 그 정도는 아닙니다. 하지만 이걸로 디버깅을 해보면 반드시 디버깅 할 일 없이 완벽하게 짜야겠다는 생각이 듭니다.
잡설이 길었습니다. 왜냐하면 윈폼에서는 먹던 start selected test project with debugger버튼이 without debugger와 똑같은 반응을 보이거든요! 즉, 일반적인 방법으로는 디버깅이 되지 않는다는 말입니다.
그럼 어떻게 해야할까요?
제가 이 문제를 봉착했을 때 재밌는 걸 발견했는데,
System.Diagnostics.Debugger.Break()
라는 메소드 입니다. 이 메소드를, 'F9를 눌러 설정하던 그라데이션 입혀진 브레이크 포인트' 대신에 넣으면 됩니다. 그럼 without debugger로 실행했을 때, 저 메소드를 만나면 디버거 선택창이 뜹니다. 여기서 적절한 디버거를 선택해주면 됩니다.
물론 여러분이 기대하는 만큼 온전하게 작동하지는 않습니다.
참고:
How to: Debug while Running a Test in an ASP.NET Solution
http://msdn2.microsoft.com/en-us/library/ms243172.aspx#DebuggingOnCassini
윈폼용 유닛 테스트는 그리 낯설지 않지만, 문제는 ASP.NET의 경우입니다. 아래에선 제가 겪은 몇 가지 단점들 입니다. 일부 이슈에 대해서는 스트레스를 조금이나마 줄일 수 있는 팁을 적어 놓았습니다.
1. 속도
가장 먼저 유닛 테스트를 하게 되면 적잖게 당황하게 되는게, 속도 문제인데, 매우 느립니다. 대략 펜티엄4 3.0기가에서 테스트용 development server가 실행되고 테스트가 완료되는데 까지 거의 10초 이상이 걸립니다.
속도 정도야 애교죠. 유닛테스트가 보우하사 우리 코드를 지킬 수 있다면, 단 몇 초 여유롭게 기다리는게 코더의 노동보다 힘들까요?
2. 엑서서
두번째 문제는 엑서서입니다. 이클립스는 이 경우를 어떻게 해결했는지 잘 기억이 안나지만... (혹시 아시는 분은 리플을 달아주세요) VSTS(visual studio team system)의 유닛테스트는 클래스의 private, protected멤버 등을 접근하기 위해서 엑서서라는 클래스를 별도로 만듭니다. 테스트 프로젝트를 만들면 자동으로 생성되는 vscodegenaccessors.cs 파일이죠. 일반적으로 프라이빗과 프로텍티드 멤버를 외부에서 접근하지 못하는 것은 당연합니다. 아마 vsts에선 유닛테스트를 위해 별도의 편의?를 봐주지 않기 위해서 C#의 언어적 특성으로 이를 해결한 듯 합니다.
아무튼 이런 불편한 래핑 클래스인 엑서서의 등장으로, 프라이빗 메소드를 테스트 하려면 엑서서를 거쳐서 호출해야 합니다.
이 정도야 그냥 넘어갈 수 있다는 분!
만약에 테스트할 메소드의 signature가 수정되었다면 상황이 어떻게 될까요??
컴파일이 안됩니다.
그럼 어떻게 하나요 - 물론 엑서서는 vs에서 자동으로 만들어주긴 하지만, signature의 변경을 일일히 감지해서 알아서 척척 생성해 주지는 않습니다. 프로그래머는 메소드에서 오른쪽 버튼을 누른 후, create private accessor를 눌러서 엑서서가 자동으로 생성되게 해야 합니다.
3. 애트리븃
모든 테스트 메소드에는 아래와 같은 속성이 붙습니다.
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("website", "/pms")]
[UrlToTest("http://localhost/pms")]
public void InsertTaskTest()
덕지덕지 붙은게 여간 지저분한게 아니죠.
여기서 한가지 팁이 있다면, AspNetDevelopmentServerHost에 웹사이트 경로를 써 줘야 테스트가 돌아가는데 msdn에는 첫번째 인자에 full path를 쓰라고 되어있습니다. 하지만 상대경로를 써도 잘 작동합니다. (기본 웹사이트 경로가 vs 디폴트로 되어 있을때 그렇습니다. 만약 다른 폴더라면 옵션에서 바꿔주면 됩니다.)
4. 디버깅
와! 드디어 ASP.NET의 유닛테스트가 $0인 JUnit에 무릎을 꿇을 때가 왔습니다. 속도, 엑서서, 애트리븃에 불편한 인터페이스까지는 다 봐줍시다. 하지만 ASP.NET 유닛테스트의 디버깅을 생각해보면 저는 정말 화가 납니다. 안그래도 버그가 튀어났는데, 디버깅까지 불편하면 얼마나 화가 날까요??
설마 자바스크립트를 alert()으로 디버깅 하는정도 일까요?? 다행이 그 정도는 아닙니다. 하지만 이걸로 디버깅을 해보면 반드시 디버깅 할 일 없이 완벽하게 짜야겠다는 생각이 듭니다.
잡설이 길었습니다. 왜냐하면 윈폼에서는 먹던 start selected test project with debugger버튼이 without debugger와 똑같은 반응을 보이거든요! 즉, 일반적인 방법으로는 디버깅이 되지 않는다는 말입니다.
그럼 어떻게 해야할까요?
제가 이 문제를 봉착했을 때 재밌는 걸 발견했는데,
System.Diagnostics.Debugger.Break()
라는 메소드 입니다. 이 메소드를, 'F9를 눌러 설정하던 그라데이션 입혀진 브레이크 포인트' 대신에 넣으면 됩니다. 그럼 without debugger로 실행했을 때, 저 메소드를 만나면 디버거 선택창이 뜹니다. 여기서 적절한 디버거를 선택해주면 됩니다.
물론 여러분이 기대하는 만큼 온전하게 작동하지는 않습니다.
참고:
How to: Debug while Running a Test in an ASP.NET Solution
http://msdn2.microsoft.com/en-us/library/ms243172.aspx#DebuggingOnCassini
'Programming > Web' 카테고리의 다른 글
| XPath로 HTML문서 접근하는 방법. (0) | 2007/08/13 |
|---|---|
| 비주얼 스튜디오로 자바스크립트 디버깅 하기 (0) | 2007/08/06 |
| ASP.NET 유닛 테스트의 해부학 (0) | 2007/08/01 |
| Ajax - 에이젝스? 아약스? 아작스?? (4) | 2007/07/30 |
| Resolve Relative URLS - URL 상대경로의 처리 (0) | 2007/07/30 |
2007/07/30 21:41
C# on multicore processor (or multi processor) - 멀티 프로세싱을 위한 C#
2007/07/30 21:41 in Programming/.NET

c#에선 단순히 스레드만 여러개 만든다고 멀티 프로세싱이 되진 않는다. 스레드가 어느 프로세서에서 실행될 수 있는지를 지정해줘야 한다.
public static void ThreadProc(object threadId)
{
int id = (int)threadId;
while(true)
{
int sum = 0;
for (int i = 0; i < 1000000; i++)
{
sum += i;
}
Console.Out.Write(string.Format("{0} ", id));
}
}
static void Main(string[] args)
{
const int NumOfThread = 4;
Thread[] threads = new Thread[NumOfThread];
for (int i = 0; i < NumOfThread; i++)
{
threads[i] = new Thread(ThreadProc);
threads[i].Start(i);
}
Process currentProcess = Process.GetCurrentProcess();
foreach (ProcessThread processThread in currentProcess.Threads)
{
processThread.ProcessorAffinity = currentProcess.ProcessorAffinity;
}
for (int i = 0; i < NumOfThread; i++)
{
threads[i].Join();
}
}
currentProcess.ProcessorAffinity는 현재 프로세스가 실행될 수 있는 프로세서에 대한 비트마스크이다. 예를들어 프로세서가 4개라면 프로그램은 프로세서1부터 4까지 프로세서 중 하나에서 실행될 수 있다. 이 비트마스크를 10진수로 표현하면 15이다.
반면 processThread.ProcessorAffinity는 기본적으로 해당 프로세스가 돌아가는 프로세서 내에서만 동작할 수 있게 되어있다. 이 값을 모든 프로세서안에서 실행될 수 있게 바꿔주는 것이다.'Programming > .NET' 카테고리의 다른 글
| URL 상대 경로, 절대 경로 변환 클래스 (C#) (0) | 2008/03/13 |
|---|---|
| C#으로 익스플로러 툴바 및 BHO만들기 (10) | 2007/11/07 |
| C#에서 unmanaged 함수 호출하기. (0) | 2007/08/31 |
| .NET 2.0 C#의 Configuration Manager (0) | 2007/08/30 |
| C# on multicore processor (or multi processor) - 멀티 프로세싱을 위한 C# (0) | 2007/07/30 |


Toolbar.zip
Prev
Rss Feed