728x90
자료출처 : http://blog.naver.com/ansysda

동일한 프로그램을 한번만 실행할 수 있도록 합니다.

static void Main()
{
   System.Diagnostics.Process[] myProc = System.Diagnostics.Process.GetProcessesByName("WindowsApplication10");  
   // 여기서 Mulpumi는 프로젝트 속성의 프로젝트 이름
           
   if(myProc.Length < 2)
   {
       Application.Run(new Form1());        
   }
   else
   {
       MessageBox.Show("이미 실행중입니다.");
       Application.Exit();      
   }
}

또 다른 방법

프로세스간 동기화 개체인Mutex 클래스를 이용하면 현재의 프로세스가 최초 실행된 프로세스인지를 판별할 수 있습니다. Mutex 객체를 생성시 초기 소유권을 부여 하도록 하며 3번째 아웃풋 파라미터의 값으로 소유권이 부여되었는지를 판단합니다. 메인 메서드에 대한 소스는 아래와 같습니다.

/// <summary>

/// 해당 응용 프로그램의 주 진입점입니다.

/// </summary>

[STAThread]

static void Main()

{

      bool createdNew;

      Mutex mutex = new Mutex(true, Application.ProductName, out createdNew);

      if (createdNew)

      {

              Application.Run( new Form1());

      }

}

프로그램을 실행할 때 이미 실행되어 있는 프로그램이면 활성화를 시켜주어야 할 때가 있습니다. 해당 프로세스의 윈도우를 활성화시켜주는 방법이 닷넷 프레임워크에는 존재하지 않습니다. Win32 API 함수를 플랫폼 호출하여야 합니다. 아래의 소스처럼 inner class로 만듭니다.

internal class NativeMethods

{

      /// <summary>

      /// The SetForegroundWindow function puts the thread that created the specified window

      /// into the foreground and activates the window. Keyboard input is directed to the window,

      /// and various visual cues are changed for the user. The system assigns a slightly higher

      /// priority to the thread that created the foreground window than it does to other threads.

      /// </summary>

      [DllImport("user32.dll")]

      internal static extern

              bool SetForegroundWindow(IntPtr hWnd);

      /// <summary>

      /// The ShowWindowAsync function sets the show state of a window created by a different thread.

      /// </summary>

      [DllImport("user32.dll")]

      internal static extern

              bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

      /// <summary>

      /// The IsIconic function determines whether the specified window is minimized (iconic).

      /// </summary>

      [DllImport("user32.dll")]

      internal static extern

              bool IsIconic(IntPtr hWnd);

      // Activates and displays the window. If the window is minimized or maximized, the system

      // restores it to its original size and position. An application should specify this flag

      // when restoring a minimized window.

      internal static int SW_RESTORE = 9;

}

메인 메서드를 아래와 같이 수정합니다. 두 번째 인스턴스가 실행되는 시점에서 해당 프로그램 명에 대한 프로세스는 2개가 있으며, 그 중 현재의 프로세스 아이디와 같지 않은 프로세스가 최초 실행된 프로세스입니다. 그 프로세스가 아이콘화(최소화) 되어 있는지를 검사(IsIconic 메서드)해서 아이콘화 되어 있으면 비동기로 해당 윈도우를 활성화(ShowWindowAsync 메서드)시켜야 합니다. 그리고 z order의 맨 앞으로 보내도록(SetForegroundWindow 메서드) 합니다.

/// <summary>

/// 해당 응용 프로그램의 주 진입점입니다.

/// </summary>

[STAThread]

static void Main()

{

      bool createdNew;

      Mutex mutex = new Mutex(true, Application.ProductName, out createdNew);

      if (createdNew)

      {

              Application.Run( new Form1());

      }

      else

      {

              Process[] viewProcesses =

                      Process.GetProcessesByName(Application.ProductName);

              if (viewProcesses != null && viewProcesses.Length == 2)

              {

                      Process view = viewProcesses[0].Id == Process.GetCurrentProcess().Id ?

                            viewProcesses[1] : viewProcesses[0];

                      IntPtr hWnd = view.MainWindowHandle;

                      if (NativeMethods.IsIconic(hWnd))

                      {

                            NativeMethods.ShowWindowAsync(hWnd, NativeMethods.SW_RESTORE);

                      }

                      NativeMethods.SetForegroundWindow(hWnd);

              }

      }

}

이상으로 Mutex 클래스와 Process 클래스, 그리고 몇몇 API 함수를 이용해서 하나의 인스턴스만 실행되도록 하고 두 번째 실행 시에는 해당 프로그램이 활성화되도록 하는 방법을 살펴보았습니다.

- taihikim


728x90

파일 읽기는 자주 사용하실 것인데..
CFile::Read를 사용하여도 되지만 속도 문제때문에
메모리 맵 파일을 이용한 파일 읽기 방법을 올려 들립니다..
 
  1. BOOL OpenFiles(LPCSTR lpszPathName)   
  2. {   
  3. DWORD dwFileSize;   
  4. HANDLE hFile, hFileMap;   
  5. LPVOID lpvFile;   
  6.   
  7. hFile = ::CreateFile(lpszPathName, GENERIC_READ , 0, NULL   
  8. OPEN_EXISTING, FILE_ATTRIBUTTE_NORMAL, NULL);   
  9. if(hFile == INVALID_HANDLE_VALUE) {   
  10. //여기에서 에러 메세지 처리..   
  11. }   
  12. dwFileSize = ::GetFileSize(hFile, NULL);   
  13.   
  14. hFileMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0,   
  15. dwFileSize, NULL);   
  16.   
  17. if(hFileMap == NULL) {   
  18. CloseHandle(hFile);   
  19. //여기에서 에러 메세지 처리..   
  20. }   
  21.   
  22. lpFile = MapViewOfFile(hFileMap, FILE_MAP_COPY, 0,0,0);   
  23.   
  24. if(lpFile == NULL) {   
  25. CloseHandle(hFile);   
  26. CloseHandle(hFileMap);   
  27. //여기에서 에러 처리   
  28. }   
  29. }   


이렇게 하면.. 대용량의 파일을 빠르게 읽을 수 있습니다..


위의 예제는 메모리 맵파일을 이용한건데 좀 복잡해 보이나요 ??
이번에는 메모리 맵파일을 이용한 방법외에 간단한 방법이 있어서 올려봅니다.

그냥 도스용 시절에 사용했던 fread함수를 사용한 것입니다.
물론 fread대신 다른 파일 읽기 함수를 사용해도 됩니다.

 
  1. char *ReadFile( char *FileName )   
  2. {   
  3. FILE *fp;   
  4. int FileSize;   
  5. char *buffer;   
  6.   
  7. try {   
  8. fp = fopen( FileName, "rb" );   
  9. if( !fp ) throw "File Not Found!";   
  10.   
  11. FileSize = filelength( fileno(fp) );   
  12. buffer = new char [FileSize+1];   
  13. fread( buffer, FileSize, 1, fp );   
  14. *(buffer + FileSize) = 0;   
  15. fclose( fp );   
  16. return buffer;    
  17. }   
  18. catchchar *msg ) {   
  19. printf( msg );   
  20. return NULL;   
  21. }   
  22. }   

    출처 : http://webdizen.new21.net
728x90

▶ 사람 관련 실수
1. 동기 저하 :
 프로젝트 전 단계에 걸쳐 주로 프로젝트 관리자가 팀원들의 동기를 저하시키는 행동을 함.  예를 들어 팀원들과 프로젝트의 목적을 공유하지 않거나 야근을 하고 있는데 자신은 휴가를 가는 등의 행동.

2. 저급 인력 : 인력을 고용할 때 일을 완수할 수 있는 사람보다 가장 빨리 투입될 수 있는 사람을 고용.
3. 문제 인물 방치 : 팀이 프로젝트 관리자에게 가지는 가장 흔한 불만 중의 하나는 문제 팀원에 대해 조치를 취하지 않는 태도임.  일을 잘한다 하더라도 분위기를 흐리면 나의 경우는 팀에서 방출시킴.
4. 영웅적 행동 : '할 수 있다'식 태도를 너무 강조하여 모험적이고 극단적인 일정을 수립한다거나 독단적인 행동을 장려함.  사소한 실수를 진짜 재앙으로 이끌 수 있음.
5. 프로젝트 후반에 인력 추가 : 이것은 관리자들이 저지르는 가장 많은 실수.  임산부 2명이 있다고 아기가 5달안에 나올 수 없는 법.  불에 기름을 붓는 행위.
6. 시끄럽고 붐비는 사무실 : 개발자의 약 60%가 더 조용하고 사적인 사무실에서 일하고 싶다는 설문조사 통계가 있음.  본인의 경우도 지하 1층에서 1년간 프로젝트를 수행한 경험이 있는데 난방이 미흡하고 공기가 탁해 집중도 안되고 건강이 안좋아진 경험이 있음.
7. 개발자와 고객 사이의 마찰 : 마찰은 요구사항 변경, 일정 등의 여러 형태로 나타남.  어떤 형태이건 마찰은 의사소통 단절을 일으키고 이로 인해 요구사항 이해 부족, 제품의 질 저하가 발생하고 나아가 프로젝트가 취소를 고려하게 된다. 회복시간도 더디고 이로 인해 실제 업무 집중하기 어렵게 된다.  한번 마찰이 발생할 때마다 일주일은 후유증에 시달렸음.
8. 비현실적인 기대 : 3개월안에 개발할 수 있다고 근거 없는 말을 관리자가 고객에게 약속하는 경우 고객은 비현실적인 기대를 갖게 됨. 개발자는 거의 초죽음 상태.
9. 효과적인 프로젝트 후원 부족 : 프로젝트 팀에 효과적인 지원은 현실적인 계획을 인정해주거나 개발방법론, 품질보증 지원 등의 개발에 도움이 되는 내용이 필요.  간섭과 강요가 아닌 지원이 필요.
10. 관련자 참여 부족 : 프로젝트 관리자, 프로젝트 팀원, 영업, 고객, 최종 사용자, 경영진 후원자, 기타 이해관계자들이 적극적으로 참여해야 친밀한 협력과 조율이 가능.
11. 사용자 참여 부족 : 스탠디쉬 그룹 조사에 의하면 프로젝트가 성공하는 가장 큰 이유는 사용자 참여임.  특히 프로젝트 초기에 사용자 참여가 없으면 요구사항 파악이 제대로 되기 어렵고 이는 반드시 프로젝트 후반부의 변경을 가져와 일정 차질을 야기함.
12. 실속보다 정치 : 한 연구보고에 의하면 '정치가' 즉 상사와의 관계에 전념하는 사람은 초기에는 상사에게 신뢰를 받지만 시간이 지나면 제일 아래로 떨어진다고 함.  이는 정치를 결과보다 우선하는 태도 때문임.
13. 막연한 기대 : '주어진 일정에 맞게 열심히 일하면 문제 없이 끝날 수 있을겁니다.' 이런 식의 막연한 기대는 프로젝트에서 너무 자주 듣는 말임.  낙관주의를 반대하진 않지만 눈을 감고 대책없는 건 아님.

▶ 공정 관련 실수
14. 지나치게 낙관적인 일정 : 예를 들어 6개월 걸릴 프로젝트를 3개월안에 끝낼 수 있다고 비현실적으로 계획 수립 
15. 불충분한 위험 관리 : 무엇보다 적극적인 위험관리가 필요.  프로젝트란 위험을 줄여 나가는 과정으로 볼 수 있음.
16. 하청업체 실패 : 아웃소싱은 원가절감, 인력부족 때문에 하게 되지만 무엇보다 품질의 저하가 우려되고 또 한가지는 자사인력과의 융화 문제임.
17. 불충분한 계획 수립 : 계획 수립은 반드시 필수 사항.
18. 압력에 따른 계획 수립 포기 : 계획을 세웠다가 일정 문제에 부딪히면 팀은 흔히 그 계획을 포기하거나 변경계획을 세우지 않음.  그러면 그 이후의 일정은 주먹구구식으로 진행됨.
19. 애매한 시작으로 낭비한 시간 : 프로젝트를 시작하기 전 프로젝트 실행 품의, 계획서 승인 등에 보낸 낭비 시간이 너무 많음.
20. 건너 뛴 초기 활동 : '기간이 촉박해서 분석, 설계 시간이 없습니다.' 라고 바로 코딩에 들어가서 나중에 바로 잡는 시간과 비용이 도대체 얼마인가?  분석, 설계 상류의 활동의 오류 하나가 구현 단계의 오류와 비교할 때 100배 차이가 난다고 함. 
21. 불충분한 설계 : '건너 뛴 초기활동'의 특별한 경우가 불충분한 설계임.  설계는 품질보다 편의가 강조되는 현실임.
22. 부족한 품질보증 : 검증과 검토, Walkthrough, Inspection을 안하면 일정은 절약되나 나중에 더 큰 대가를 치루게 됨.
23. 불충분한 관리 감독 : 프로젝트를 계획한 후 제대로 일정, 비용, 품질목표를 달성하는 지를 감독, 감사하는 장치가 필요.
24. 너무 이르거나 지나치게 잦은 통합 : 제품을 최종 인도, 출시하기 전에 각 부문의 결과를 통합해야 하는데 소프트웨어의 버그가 해결되기 전에 출시 시기를 앞당기면 나중에 또 통합작업을 해야 하므로 시간 낭비가 발생.
25. 세부업무 누락 : 작은 업무라고 기록 관리되지 않으면 잊어버리고 나중에 추가 요청이 발생할 수 있음.  대략 말로 요구사항을 이야기하고 나중에 왜 구현이 안되었느냐고 하는 경우가 많음.  이런 업무는 대략 20~30%의 추가 비용을 요구.
26. 나중에 따라 잡을 계획 : 프로젝트를 진행하다 어떤 공정이 지연되면 계획을 조정할 때 추후 일정에서 따라 잡을 수 있도록 하는 경우가 있는데 경험상 따라 잡는 경우는 거의 없음.  계획을 재조정할 때 이런 인식이 필요.
27. 미친듯이 구현하는 개발 : 일단 짜보고 고치기(code and fix development) 전략과 무리한 일정이 조합된 재미있는 표현임.  중요한 건 분석과 설계의 상류 과정임을 간과하고 있음. 

▶ 제품 관련 실수
28. 요구사항 치장 : 사용자가 요구한 사항보다 더 복잡한 기능을 추가하는 경우.  사용자는 개발자만큼 복잡한 기능에 관심이 없음.
29. 기능 변형 : 평균적으로 프로젝트의 요구사항은 생명주기 안에 약 25% 정도 변한다고 함.  당연히 일정도 25% 정도 늘어나게 됨.  따라서 변경관리 활동이 필요하고 변경에 따른 일정이 감안되어야 함.
30. 개발자 치장 : 개발자들은 새로운 기술, 언어를 테스트, 구현하고 싶어함.  실제 프로젝트 상황에서 이런 행동이 발생하는 경우 일정은 지연됨.
31. 조삼모사식 협상 : 예를 들어 고객과 일정을 미루거나 오픈을 연기를 협상하는 경우에 대신 어떤 업무를 슬그머니 추가할 것을 요구하는 사례임.  배보다 배꼽이 더 큰 경우임.
32. 연구중심 개발 : 프로젝트 목표가 다분히 기술적인 목적에 치우쳐 있다면 그런 경우는 소프트웨어 개발이 아니라 소프트웨어 연구임.  기술 프로젝트는 일정을 예측하기 어려움.

▶ 기술 관련 실수
33. 특효약 증후군 : 개발 도구나 기술 한가지 만으로 개발 기간을 획기적으로 단축할 수 있다고 믿는 경우임.

34. 새로운 도구나 방법에 대한 과대평가 : 새로운 개발 도구, 언어가 개발 생산성을 획기적으로 향상시키고 일정을 단축시킬 수 있을 것이라는 과도한 믿음을 갖게 되는 경우.  개발 환경에 적용할 수 있는 지 충분한 검증이 필요함.
35. 프로젝트 도중에 도구 변경 : 프로젝트 도중에 버전을 업그레이드 하거다 새로운 도구를 도입하는 경우에 성공하는 경우는 거의 없음.  학습 기간, 안정화, 필연적인 실수 등을 감안하면 도입에 따른 이익이 크지 않음.
36. 자동화된 소스코드 관리 도구 부족 : 소스관리가 안되어 수작업으로 소스를 통합하거나 소스를 덮어쓰는 경우가 발생.  CVS, 소스카페 등의 자동화된 소스코드 관리가 필요함.


+ Recent posts