[dot Net] 윈도우 시스템 종료 프로그램 만들기 <上>

.net으로 일정 시간이 되면 윈도우 시스템을 종료하는 프로그램을 만드려고 합니다.

배치파일

배치파일에서 다뤄보았던 바로 이 내용인데요.


배치 파일로 할 수 없는 기능을 조금 더 추가하여

윈도우 프로그램 버전을 .net으로 만든다고 보시면 되겠습니다.


목표

1) 윈도우 시스템을 종료하는 프로그램을 만든다.

2) 간단한 UI를 가진다.

3) 프로그램은 종료되지 않고 트레이 아이콘으로 유지한다.

4) 매일 특정 시간에 종료가 가능하게 설정한다.

5) 종료 시각이 임박하면 사용자에게 즉시 종료와 취소를 가능하게 한다.


목표는 정해졌으니 아래부터 만들겠습니다.




윈도우 시스템 종료

프로그램 종료는 아래와 같은 코드로 수행될 수 있습니다.

System.Diagnostics.Process.Start("shutdown", "/s /f /t 0");
  • shutdown이라는 ProcessStart하는데 다음 인자(arguments)로 옵션을 제공한다고 보시면 되겠습니다.

    [/s] 시스템을 종료합니다.

    [/f] 응용프로그램 강제 종료

    [/t 0] 종료 전 대기 시간(초)

이 소스가 실행되면 프로그램은 즉시 종료됩니다.




프로그램 UI

Form.s[디자인]을 열어 속성(attributes)에 값을 입력합니다.

많은 속성이 있지만 기본적으로 항상 챙겨줘야 할 부분은

[Text] : [프로그램 명] : 윈도우 종료 프로그램 (현재시간 09:00:00)

[Icon] : [프로그램 아이콘] : 사용할 아이콘 등록

최대화, 최소화, 사이즈 변경은 사용 안 할 예정이니까

[MaximumBox] : 최대화 박스 : false

[MinimizeBox] : 최소화 박스 : false

[FormBorderStyle] : 폼 테두리 스타일 : FixedDialog

정도를 설정하고 시작합니다.


재시작프로그램

여기에 위와 같이 간단한 UI를 구현합니다.

왼쪽이 디자인이고 오른쪽이 실제 프로그램 실행 화면 UI입니다.


Datetimepicker, CheckBox, GroupBox, Label 2개를 사용했네요.


Datetimepicker는 CustomFormat으로 표시하였습니다.

dateTimePicker1.CustomFormat = "종료 시간 HH시 mm분";


CheckBox가 체크가 되었을 경우에만 ‘종료까지 남은 시간’과 ‘00:00:00’남은 시간 부분을 활성화 합니다.

private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
    if(checkBox1.CheckState == CheckState.Unchecked) //언체크
    {
        label3.Enabled = false;
        label3.Text = "00:00:00";
        label4.Enabled = false;
    }
    else //체크
    {
        label3.Enabled = true;
        label4.Enabled = true;
    }
}


timer를 등록해서 체크일 때 종료 시각까지 남은 시간을 표시합니다.

title text에 현재 시각도 함께 표시합니다.

private void timer1_Tick(object sender, EventArgs e)
{
    //현재 시간 title text 적용
    DateTime CurrentDateTime = DateTime.Now;
    this.Text = "윈도우 종료 프로그램 (현재시간 " + CurrentDateTime.Hour.ToString("D2") + ":" + CurrentDateTime.Minute.ToString("D2") + ":"+ CurrentDateTime.Second.ToString("D2") + ")";

    //체크가 되었을 경우 종료되기까지 남은 시간 계산
    if (checkBox1.CheckState == CheckState.Checked)
    {
        int RestartHour = dateTimePicker1.Value.Hour;
        int RestartMinute = dateTimePicker1.Value.Minute;
        DateTime RestartDateTime = new DateTime(CurrentDateTime.Year, CurrentDateTime.Month, CurrentDateTime.Day, RestartHour, RestartMinute, 0);
        
        // CurrentDateTime가 더 느린 경우
        //재시작시간을 다음날로 계산
        if(DateTime.Compare(CurrentDateTime, RestartDateTime)>0) 
        {
            RestartDateTime = RestartDateTime.AddDays(1);
        }

        //시간 차이 계산
        TimeSpan timeSpan = RestartDateTime - CurrentDateTime;
        TimeSpan timeSpanOneSecond = new TimeSpan(0, 0, 1);
        timeSpan = timeSpan.Add(timeSpanOneSecond);
        label3.Text = timeSpan.Hours.ToString("D2") + ":" + timeSpan.Minutes.ToString("D2") + ":" + timeSpan.Seconds.ToString("D2");
    }
}

정말 간단한 UI인데

이렇게 글로 적으니 실제 만들 때보다

시간이 5배는 더 걸리네요.

디버프 걸린 것 같습니다.




트레이 아이콘(notifyicon)

트레이아이콘

트레이 아이콘은 윈도우 작업표시줄에서 일반적으로 우측에 보이는 작은 아이콘들을 말합니다.

보통은 상시 유지되는 백그라운드 형태의 프로그램에 많이 사용합니다.

특정 시간에 실행이 되기 위해서는 프로그램이 상시 유지돼야 하기에 적용하겠습니다.

프로그램을 완성한 후에 시작프로그램 폴더에 바로가기를 만들어 두면

상시 실행되는 프로그램이 됩니다.


.net에서 트레이 아이콘을 구현하는 방법은 정말 쉽습니다.

도구상자에서 notifyicon과 contextmenustrip을 등록하고요.

아래와 같이 contextmenustrip에 메뉴를 등록했습니다.

contextmenu

아이콘 상태에서 우클릭 메뉴를 적용할 예정입니다.


아래는 트레이 아이콘에 사용되는 기본적인 구현 내용입니다.

아이콘을 우클릭했을 때 설정과 종료가 가능하게 만듭니다.

프로그램은 종료키로 종료되지 않고 우클릭 메뉴 종료로만 종료할 수 있습니다.

설정으로 다이얼로그가 보이게 됩니다.

마찬가지로 아이콘을 더블 클릭 시에도 다이얼로그가 보이게 됩니다.


  • 우클릭 시에 메뉴가 뜰 수 있게 다이얼로그 폼이 로드될 때 연결합니다.
private void Form1_Load(object sender, EventArgs e)
{
    notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
}


  • 폼에 종료 신호가 들어올 때 종료는 하지 않고 폼은 숨기고 notifyicon을 보여줍니다.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        notifyIcon1.Visible = true;
        this.Hide();
        e.Cancel = true;
    }
}


  • notifyicon에서 우클릭 메뉴 설정 클릭 시 폼은 보여주고 notifyicon은 안 보이게 합니다.
private void ToolStripMenuItemShow_Click(object sender, EventArgs e)
{
   this.Show();
   notifyIcon1.Visible = false;
}


  • notifyicon에서 더블 클릭 시 마찬가지로 폼은 보여주고 notifyicon은 안 보이게 합니다.
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
    this.Show();
    notifyIcon1.Visible = false;
}


  • notifyicon에서 우클릭 메뉴 종료 시 프로그램을 종료합니다.
private void ToolStripMenuItemExit_Click(object sender, EventArgs e)
{
   Application.Exit();
}


contextmenu

아이콘을 우클릭해서 잘 동작하는지 확인합니다.




이렇게 上편은 종료합니다.

다음 편에는 만들어진 UI를 기반으로

매일 특정 시간에 종료가 가능하게 설정하고 적용하는 내용(Registry)과

종료시간이 임박하면 사용자에게

즉시 종료와 취소를 지원하는 기능(Child Dialog)을 적용할 예정입니다.


감사합니다.