C# WPF 트레이 아이콘 띄울시 System.IO.FileNotFoundException 에러

조회수 1596회

C# 과 WPF로 백업프로그램을 만들고 있는데 계속 트레이 아이콘에서 아이콘 정하는 쪽에서 예외가 발생해서 트레이 아이콘이 뜨질 않습니다. 같은 폴더에 있는것도 확인했고 xaml파일에서는 아이콘이 잘 적용 되는데 뭐가 문제일까요..

C#코드

using Microsoft.WindowsAPICodePack.Dialogs;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Diagnostics;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;

namespace Disk_To_Disk_with_cs
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        DateTime backuptime;
        string target;
        string folder;
        public MainWindow()
        {
            InitializeComponent();
            Loaded += Window_Loaded;//WPF가 로드되면 실행
        }

        System.Windows.Forms.NotifyIcon ni = new System.Windows.Forms.NotifyIcon();
        private void Window_Loaded(object sender, RoutedEventArgs e)//wpf가 로드됐다면
        {
            try
            {
                //TODO:아이콘을 찾을 수 없어 트레이 아이콘을 못 띄우는 에러 수정
                /*트레이 아이콘 생성*/
                System.Windows.Forms.ContextMenu menu = new System.Windows.Forms.ContextMenu();
                System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem();

                menu.MenuItems.Add(exit);
                exit.Index = 0;
                exit.Text = "프로그램 종료";
                exit.Click += delegate (object click, EventArgs eClick)
                {
                    ni.Dispose();
                    System.Windows.Application.Current.Shutdown();
                };
                ni.Icon = new System.Drawing.Icon("icon.ico");
                ni.Visible = true;
                ni.ContextMenu = menu;
                ni.Text = "DTD Menu";
            }
            catch//실패시
            {
                MessageBox.Show("시스템 트레이 아이콘을 불러오지 못했습니다.", "Disk To Disk", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void backup_target_sel_Click(object sender, RoutedEventArgs e)
        {
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            dialog.InitialDirectory = @"C:\test";
            dialog.IsFolderPicker = true;
            if (dialog.ShowDialog() == CommonFileDialogResult.Ok)//폴더선택을 했으면
            {
                backup_target_path.Text = dialog.FileName;//textbox텍스트 변경
            }
        }

        private void backup_folder_sel_Click(object sender, RoutedEventArgs e)
        {
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            dialog.InitialDirectory = @"F:\dtd test";
            dialog.IsFolderPicker = true;
            if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
            {
                backup_folder_path.Text = dialog.FileName;
            }
        }

        private void backup_start_Click(object sender, RoutedEventArgs e)
        {
            backuptime = DateTime.ParseExact(H.Text + M.Text, "HHmm", null);//백업시간 형변환
            //백업 대상 폴더와 백업을 저장할 폴더 지정
            target = backup_target_path.Text;
            folder = backup_folder_path.Text;
            if (!Directory.Exists(target) || !Directory.Exists(folder))//만약 올바른 경로가 아니면
            {
                //오류후 리턴
                MessageBox.Show("올바른 경로를 입력해주세요.", "Disk To Disk", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            //백그라운드 동작 위한 함수 준비
            BackgroundWorker backup;
            backup = new BackgroundWorker()
            {
                WorkerSupportsCancellation = true,
            };
            backup.DoWork += check_time;
            backup.RunWorkerCompleted += done_backup;
            //TODO:백그라운드 동작전 json값 생성 및 저장
            JObject data = new JObject();
            data.Add(new JProperty("is_setting_save", is_setting_save.IsChecked.Value));
            data.Add(new JProperty("is_startup", is_startup.IsChecked.Value));
            data.Add(new JProperty("is_faststartup", is_faststartup.IsChecked.Value));
            data.Add(new JProperty("is_poweroff", is_poweroff.IsChecked.Value));
            File.WriteAllText(Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)+@"\DTD Data.json", data.ToString());
            //백그라운드 동작 시작
            backup.RunWorkerAsync();
            this.Hide();
            Console.WriteLine("thread start");
        }

        private void CopyTree(string source, string dest)
        {
            if (!Directory.Exists(dest))//만약 해당 디텍토리가 없다면
                Directory.CreateDirectory(dest);//생성
            File.Copy(source, dest, true);//파일 복사
        }

        private void backupEnd()//백업이 완료했을때 호출되는 함수
        {
            ProcessStartInfo cmd = new ProcessStartInfo();
            Process process = new Process();
            cmd.FileName = @"cmd";
            cmd.WindowStyle = ProcessWindowStyle.Hidden;
            cmd.CreateNoWindow = true;

            cmd.UseShellExecute = false;
            if (is_poweroff.IsChecked.Value)
            {
                process.EnableRaisingEvents = false;
                process.StartInfo = cmd;
                process.Start();
                process.StandardInput.Write(@"shutdown /s /t 00" + Environment.NewLine);//컴퓨터 끄기
                process.StandardInput.Close();
            }
        }

        private void check_time(object sender, DoWorkEventArgs e)
        {
            var befor_files = GetFileListFromFolderPath(target);//특정 시간 전의 파일 정보
            while (true)
            {
                TimeSpan test = backuptime - DateTime.Now;
                if (Math.Truncate(test.TotalSeconds) == 0)//특정 시간이 됐다면
                {
                    var after_files = GetFileListFromFolderPath(target);//특정 시간 후의 파일 정보
                    if(GetFileListFromFolderPath(folder).Count == 0)//만약 백업을 저장할 폴더가 비어있다면(처음 백업한다면)
                    {
                        for(int i = 0; i < after_files.Count; i++)
                        {
                            Console.WriteLine(after_files[i][0]);
                            CopyTree(after_files[i][0], folder + after_files[i][0].Replace(target, ""));//파일 복사
                        }
                    }
                    if (befor_files.Count != after_files.Count)//만약 파일개수가 다르다면
                    {
                        List<string> copyfile = new List<string>();//복사 대상 파일 리스트 생성
                        for (int i = 0; i < befor_files.Count; i++)
                        {
                            copyfile.Add(befor_files[i][0]);//befor_files경로 담음
                        }
                        for (int i = 0; i < after_files.Count; i++)
                        {
                            copyfile.Add(after_files[i][0]);//after_files경로 담음
                        }
                        copyfile = copyfile.Distinct().ToList();
                        for (int i = 0; i < befor_files.Count; i++)
                        {
                            copyfile.Remove(befor_files[i][0]);//중복항목 삭제
                        }
                        for (int i = 0; i < copyfile.Count; i++)
                        {
                            CopyTree(copyfile[i], folder + copyfile[i].Replace(target, ""));//복사할 파일 표시
                        }
                    }
                    for (int i = 0; i < befor_files.Count; i++)
                    {
                        if (befor_files[i][1] != after_files[i][1])//만약 마지막 수정 날자가 다르다면
                        {
                            CopyTree(after_files[i][0], folder + after_files[i][0].Replace(target, ""));//복사할 파일 표시
                        }
                    }
                    backuptime = backuptime.AddHours(24);

                }
                else if(Math.Truncate(test.TotalSeconds) > 0)
                {
                    backuptime = backuptime.AddHours(24);
                }
            }
        }

        private List<List<string>> GetFileListFromFolderPath(string FolderName)
        {
            List<List<string>> result = new List<List<string>>();
            DirectoryInfo di = new DirectoryInfo(FolderName); // 해당 폴더 정보를 가져옵니다.
            foreach (FileInfo File in di.GetFiles()) // 선택 폴더의 파일 목록을 스캔합니다.
            {
                result.Add(new List<string> { File.FullName, File.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") });
            }
            DirectoryInfo[] di_sub = di.GetDirectories(); // 하위 폴더 목록들의 정보 가져옵니다. 
            foreach (DirectoryInfo di1 in di_sub) // 하위 폴더목록을 스캔합니다. 
            {
                foreach (FileInfo File in di1.GetFiles()) // 선택 폴더의 파일 목록을 스캔합니다.
                {
                    result.Add(new List<string> { File.FullName, File.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") });
                }
            }
            return result;
        }

        private void done_backup(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("done");
        }

        private void is_faststartup_Checked(object sender, RoutedEventArgs e)
        {
            is_startup.IsChecked = false;
            is_startup.IsEnabled = false;
        }
        private void is_faststartup_UnChecked(object sender, RoutedEventArgs e)
        {
            is_startup.IsEnabled = true;
        }
    }
}

폴더 구조 이미지

xaml파일

<Window x:Class="Disk_To_Disk_with_cs.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Disk_To_Disk_with_cs"
        mc:Ignorable="d"
        Icon="icon.ico"
        Title="Disk To Disk" Height="222.727" Width="695.455">
    <Grid>
        <Button x:Name="backup_target_sel" Content="또는 경로 선택" Margin="572,40,15,0" VerticalAlignment="Top" Height="23" Click="backup_target_sel_Click"/>
        <Button x:Name="backup_folder_sel" Content="또는 경로 선택" Margin="572,76,15,0" VerticalAlignment="Top" Height="23" Click="backup_folder_sel_Click"/>
        <TextBox x:Name="backup_target_path" HorizontalAlignment="Left" Height="23" Margin="15,40,0,0" TextWrapping="Wrap" Text="이곳에 백업할 파일이 있는곳을 입력하세요." VerticalAlignment="Top" Width="552"/>
        <TextBox x:Name="backup_folder_path" HorizontalAlignment="Left" Height="23" Margin="15,76,0,0" TextWrapping="Wrap" Text="이곳에 백업할 파일을 옮길곳을 입력하세요." VerticalAlignment="Top" Width="552"/>
        <Label Content="Disk To Disk" HorizontalAlignment="Left" Margin="10,2,0,0" VerticalAlignment="Top" Width="128" Height="33" FontSize="20"/>
        <ComboBox x:Name="H" HorizontalAlignment="Left" Margin="15,104,0,0" VerticalAlignment="Top" Width="45" SelectedIndex="0">
            <Label Content="00"/>
            <Label Content="01"/>
            <Label Content="02"/>
            <Label Content="03"/>
            <Label Content="04"/>
            <Label Content="05"/>
            <Label Content="06"/>
            <Label Content="07"/>
            <Label Content="08"/>
            <Label Content="09"/>
            <Label Content="10"/>
            <Label Content="11"/>
            <Label Content="12"/>
            <Label Content="13"/>
            <Label Content="13"/>
            <Label Content="14"/>
            <Label Content="15"/>
            <Label Content="16"/>
            <Label Content="17"/>
            <Label Content="18"/>
            <Label Content="19"/>
            <Label Content="20"/>
            <Label Content="21"/>
            <Label Content="22"/>
            <Label Content="23"/>
        </ComboBox>
        <Label Content=":" HorizontalAlignment="Left" Margin="60,98,0,0" VerticalAlignment="Top" Height="33" FontSize="16"/>
        <ComboBox x:Name="M" HorizontalAlignment="Left" Margin="74,104,0,0" VerticalAlignment="Top" Width="45" SelectedIndex="0">
            <Label Content="00"/>
            <Label Content="01"/>
            <Label Content="02"/>
            <Label Content="03"/>
            <Label Content="04"/>
            <Label Content="05"/>
            <Label Content="06"/>
            <Label Content="07"/>
            <Label Content="08"/>
            <Label Content="09"/>
            <Label Content="10"/>
            <Label Content="11"/>
            <Label Content="12"/>
            <Label Content="13"/>
            <Label Content="14"/>
            <Label Content="15"/>
            <Label Content="16"/>
            <Label Content="17"/>
            <Label Content="18"/>
            <Label Content="19"/>
            <Label Content="20"/>
            <Label Content="21"/>
            <Label Content="22"/>
            <Label Content="23"/>
            <Label Content="24"/>
            <Label Content="25"/>
            <Label Content="26"/>
            <Label Content="27"/>
            <Label Content="28"/>
            <Label Content="29"/>
            <Label Content="30"/>
            <Label Content="31"/>
            <Label Content="32"/>
            <Label Content="33"/>
            <Label Content="34"/>
            <Label Content="35"/>
            <Label Content="36"/>
            <Label Content="37"/>
            <Label Content="38"/>
            <Label Content="39"/>
            <Label Content="40"/>
            <Label Content="41"/>
            <Label Content="42"/>
            <Label Content="43"/>
            <Label Content="44"/>
            <Label Content="45"/>
            <Label Content="46"/>
            <Label Content="47"/>
            <Label Content="48"/>
            <Label Content="49"/>
            <Label Content="50"/>
            <Label Content="51"/>
            <Label Content="52"/>
            <Label Content="53"/>
            <Label Content="54"/>
            <Label Content="55"/>
            <Label Content="56"/>
            <Label Content="57"/>
            <Label Content="58"/>
            <Label Content="59"/>
        </ComboBox>
        <CheckBox x:Name="is_setting_save" Content="설정값 저장" HorizontalAlignment="Left" Margin="124,108,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="is_startup" Content="윈도우 시작시 실행" HorizontalAlignment="Left" Margin="213,108,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="is_poweroff" Content="백업후 컴퓨터 종료" HorizontalAlignment="Left" Margin="342,108,0,0" VerticalAlignment="Top"/>
        <Button x:Name="backup_start" Content="백업 시작!" Margin="572,106,15,0" Click="backup_start_Click" Height="25" VerticalAlignment="Top"/>
        <CheckBox x:Name="is_faststartup" Content="컴퓨터 시작시 바로 백업 시작" HorizontalAlignment="Left" Margin="124,128,0,0" VerticalAlignment="Top" Checked="is_faststartup_Checked" Unchecked="is_faststartup_UnChecked"/>
    </Grid>
</Window>

  • 파일을 찾지 못하는 문제입니다. 디버거로 라인단위로 실행해가면서 파일경로를 올바르게 설정되었는지 확인하세요. 정영훈 2020.5.16 19:14
  • 감사합니다! 덕분에 해결됐습니다! bass9030 2020.5.17 10:14

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)