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

이 네이밍 규칙은 닷넷 스파이더 팀에서 만든 [C# Coding Standards and Best Programming Practices]를 바탕으로 만들었습니다.

혼자 작업할때는 상관없지만 팀작업을 해야 할 때는 필요한 자료입니다. ^^;

1. 네이밍 관례와 표준


  이 문서 전반에 걸쳐 파스칼표기법과 카멜 표기법이 사용된다.  

  파스칼 표기법 - 모든 단어에서 첫번째 문자가 대문자이며 나머지는 소문자이다.

    예: BackColor

  카멜 표기법 - 최초에 사용된 단어를 제외한 첫번째 문자가 대문자이며
                     나머지는 소문자이다.

    예: backColor


 

1. 클래스 명에는 파스칼 표기법을 사용한다.

public class HelloWorld
{

...

}


2. 함수(Method) 명에는 파스칼 표기법을 사용한다.


void SayHello(string name)
{

...

}



3. 변수와 함수 파라미터에는 카멜표기법을 사용한다.

int totalCount = 0;

void SayHello(string name)
{

string fullMessage = "Hello " + name;

...

}


4. 인터페이스에는 접두사 "I"가 포함된 파스칼표기법에 따른다. ( Example: IEntity )


5. 변수명에 헝가리안 표기법을 사용하지 않는다.

이전에는 많은 프로그래머들이 변수명에 데이타 타입에 해당하는 접두사를 첨가하겨 맴버변수에는 m_을 접두사로 사용하는 헝가리안 표기법을 사용했다. 예를 들어

string m_sName;

int nAge;


그러나 닷넷 코딩 표준에서 헝가리안 표기법은 추천하지 않는다. 데이타 타입을 사용하는 것과 멤버 변수를 표현하기 위한 m_ 은 사용해서는 안된다. 모든 변수는 카멜 표기법을 사용해야 한다.


몇몇 프로그래머들은 아직 m_를 붙이거나 데이타 타입을 표시하는 것을 더 좋아하겠지만, 이제 이것들은 멤버 변수를 확인하기위한 쉬운 방법이 아니다.


6. 변수에 모든 의미를 충분히 담아라. 약어를 사용하지 말것.


좋은 예:

string address

int salary


나쁜 예:

string nam

string addr

int sal


7. i, n, s 같이 한글자로 된 이름을 사용하지 말것. index, temp 같은 이름을 사용할 것.


한가지 예외가 있다면 루프에서 반복을 의미하는 변수를 하용하는 경우이다.


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

{

...

}


만일 변수가 단지 반복을 위한 카운터로만 사용된다면 그리고 그것이 루프안에 있는 다른 어떤 곳에서도 사용되지 않는다면, 많은 사람들은 아직까지 다른 적합한 단어는 만들어서 사용하는 것보다 i를 사용하는 것을 선호한다.


8. 지역변수에는 밑줄(_)을 사용하지 않느다.


9. 모든 멤버 변수들은 앞에 밑줄(_)을 사용해야 한다. 그래야 다른 지역변수들과 구분할 수 있다.


10. 키워드와 비슷한 이름을 하용하지 말것.


11. boolean 이 들어가는 변수, 속성, 함수(method)등은 "is" 또는 유사한 접두사를 사용한다.


예: private bool _isFinished


12. 네임스페이스 명은 표준 패턴을 따라야 한다.


<회사명>.<제품명>.<최상위모듈>.<하위모듈>


13. UI 구성요소를 위하여 적당한 접두사를 사용해야 한다. 그래서 다른 변수들과 구분할 수 있어야 한다.


여기 추천하는 서로 다른 두가지 방식이 있다.


a. 모든 UI 구성요소를 위하여 공통적인 접두사(ui_)를 사용하는 것이다. 이것은 모든 UI 구성요소를 묶는데 도움을 줄 것이고 쉽게 이해하고 접근하게 할 것이다.


b. 각각의 UI 구성요소마다 접두사를 적용하는 방법. 간단한 목록이 아래에 있다. 닷넷은 다양한 컨트롤들이 제공되므로 더 많은 컨트롤(써드파티 컨트롤을 포함한)에 대한 표준을 정의해야 한다.


 Control  prifix  Control  prifix
 Label  lbl  Checkbox  chk
 TextBox  txt  CheckBoxList  cbl
 DataGrid  dtg  RadioButton  rdo
 Button  btn  RadioButtonList  rbl
 ImageButton  imb  Image  img
 Hyperlink  hlk  Panel  pnl
 DropDownList  ddl  PlaceHolder  phd
 ListBox  lst  Table  tbl
 DataList  dtl  Validators  val
 Repeater  rep    
   

14. 파일명은 클래스 명과 같아야 한다.


예를 들어, 클래스 명이 "HelloWorld" 라면 파일명은 "HelloWorld.cs" 이어야 한다.


15.  파일명은 파스칼 표기법을 사용한다.




2. 들여쓰기


1. 들여쓰기에는 TAB 을 사용한다. SPACE를 사용하지 않는다. Tab 사이즈는 4로 정의한다.


2. 주선은 코드와 같은 레벨에 있어야 한다(들여쓰기의 레벨을 같이 사용한다.).


좋은 예:


// Format a message and display


string fullMessage = "Hello " + name;

DateTime currentTime = DateTime.Now;

string message = fullMessage + ", the time is : " + currentTime.ToShortTimeString();

MessageBox.Show ( message );


좋지 않은 예:


// Format a message and display

    string fullMessage = "Hello " + name;

    DateTime currentTime = DateTime.Now;

    string message = fullMessage + ", the time is : " + currentTime.ToShortTimeString();

    MessageBox.Show ( message );


3. 중괄호는 중괄호 밖에 있는 코드와 같은 레벨에 있어야 한다.

            
4. 논리적인 코드 그룹은 다른 코드와 한칸 띄어서 구분한다.


좋은 예:

        bool SayHello ( string name )

        {

               string fullMessage = "Hello " + name;

               DateTime currentTime = DateTime.Now;


               string message = fullMessage + ", the time is : " + currentTime.ToShortTimeString();


               MessageBox.Show ( message );


               if ( ... )

               {

                       // Do something

                       // ...


                       return false;

               }


               return true;

        }


안 좋은 예:


        bool SayHello (string name)

        {

               string fullMessage = "Hello " + name;

               DateTime currentTime = DateTime.Now;

               string message = fullMessage + ", the time is : " + currentTime.ToShortTimeString();

               MessageBox.Show ( message );

               if ( ... )

               {

                       // Do something

                       // ...

                       return false;

               }

               return true;

        }


5.     There should be one and only one single blank line between each method inside the class.


6. 중괄호는 다른 라인과 분리되어 있어야하며 라인을 같이 쓰면 안된다.


좋은 예:

               if ( ... )    

               {

                       // Do something

               }


안 좋은 예:


               if ( ... )     {

                       // Do something

               }


7. 지시자(operator)와 괄호 앞뒤로는 한 칸의 공간을 남긴다.


좋은 예:

               if ( showResult == true )

               {

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

                       {

                              //

                       }

               }


나쁜 예:


               if(showResult==true)

               {

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

                       {

                              //

                       }

               }



8. 연관된 코드를 묶을때는 #region을 사용해라. #region을 사용해서 묶는다면 그 페이지는 훨씬 간략해질 것이다.


9. private 멤버 변수, 속성, 그리고 메쏘드는 파일의 하단에 그리고 public 멤버들을 파일의 하단에 위치하도록 하라. 


 

+ Recent posts