2017. 7. 14. 16:02

- 지정된 폴더의 파일 변화 모니터링 (생성,삭제, 리네임, 변경)

- 파일이 현재 복사가 되는지 File Lock 여부


using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Runtime.InteropServices;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;


namespace FileWatcher

{

    /// <summary>

    /// MainWindow.xaml에 대한 상호 작용 논리

    /// </summary>

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();


            Start();

        }


        System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();

        string filePath = null;


        private void Start()

        {

            System.IO.FileSystemWatcher watcher = new System.IO.FileSystemWatcher();

            watcher.Path = @"d:\watch";

            watcher.NotifyFilter = System.IO.NotifyFilters.FileName | System.IO.NotifyFilters.DirectoryName | System.IO.NotifyFilters.Size;


            watcher.Changed += Watcher_Changed;

            watcher.Created += Watcher_Created;

            watcher.Deleted += Watcher_Deleted;

            watcher.Renamed += Watcher_Renamed;

            watcher.EnableRaisingEvents = true;


            timer.Interval = new TimeSpan(0, 0, 1);

            timer.Tick += (s, args) =>

            {

                if (!string.IsNullOrEmpty(filePath))

                {

                    if (IsFileLocked(filePath))

                        Log($"File Locked");

                    else

                    {

                        Log($"File unlocked");

                        timer.Stop();

                    }

                }

            };

        }


        private void Watcher_Renamed(object sender, System.IO.RenamedEventArgs e)

        {

            Log($"{e.ChangeType}, File: {e.FullPath}, Old File: {e.OldFullPath}");

        }


        private void Watcher_Deleted(object sender, System.IO.FileSystemEventArgs e)

        {

            Log($"{e.ChangeType}, File: {e.FullPath}");

        }


        private void Watcher_Created(object sender, System.IO.FileSystemEventArgs e)

        {

            Log($"{e.ChangeType}, File: {e.FullPath}");

            timer.Start();

        }


        private void Watcher_Changed(object sender, System.IO.FileSystemEventArgs e)

        {

            filePath = e.FullPath;

            Log($"{e.ChangeType}, File: {filePath}, Length: {new System.IO.FileInfo(filePath).Length}");

        }


        private void Timer_Tick(object sender, EventArgs e)

        {

            throw new NotImplementedException();

        }


        private void Log(string str)

        {

            this.Dispatcher.Invoke(() =>

            {

                txt.Text += str + "\r\n";

            });

        }


        const int ERROR_SHARING_VIOLATION = 32;

        const int ERROR_LOCK_VIOLATION = 33;

        private bool IsFileLocked(string file)

        {

            //check that problem is not in destination file

            if (File.Exists(file) == true)

            {

                FileStream stream = null;

                try

                {

                    stream = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None);

                }

                catch (Exception ex2)

                {

                    //_log.WriteLog(ex2, "Error in checking whether file is locked " + file);

                    int errorCode = Marshal.GetHRForException(ex2) & ((1 << 16) - 1);

                    if ((ex2 is IOException) && (errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION))

                    {

                        return true;

                    }

                }

                finally

                {

                    if (stream != null)

                        stream.Close();

                }

            }

            return false;

        }

    }

}



Posted by CoolDragon
2010. 7. 22. 10:25
WCF 서비스를 REST 방식으로 웹 서비스를 이용하고자 샘플을 만들어 보았으며
아래 샘플소스는 WCF + ASP.NET + jQuery 를 사용하였다.


간단히 HttpModule을 이용하여 URL Rewrite처리를 하여 .svc 의 URL을 주소에서 감추고자 하였다.
(IIS7은 URL Rewrite를 IIS에서 제공해주므로 구현 안하고 설정으로 사용 가능 할듯)
(IIS6은 HttpModule방식과 정규식과 web.config와 같은 설정파일에서 관리)

[실제URL]


참고 URL
1.
[Programming JSON with WCF in .NET Framework 3.5]

2.
[Rob Windsor on WCF with REST, JSON and RSS]

3.
[WCF and JQuery Using JSON]

4.
[Consuming JSON data in .NET with WCF]

5.
[클라이언트 페이지 json요청]
[서버 WCF 서비스  json요청 처리]

6.WCF REST 방식에서 .SVC를 제거하는 방법
Posted by CoolDragon
2010. 7. 21. 18:43
오늘에서야 알았다.

c#에서의 Replace 함수와 javascript의 replace함수는 같은듯 하지만 다르다란 걸 말이다.
그 차이점이 뭐냐하면.. 아래와 같다.

[c#]
string str = "?,?,?,?,?";
str = str.Replace("?", "TEST"); MessageBox.Show(str);
이렇게 하면 결과는 아래와 같이 출력된다.
TEST,TEST,TEST,TEST,TEST
[javascript]
var str = "?,?,?,?,?"; str = str.replace("?", "TEST"); alert(str);
이렇게 하면 결과는 아래와 같이 출력된다.
TEST,?,?,?,?

나 혼자만 몰랐나? 응응?? -_-;;
Posted by CoolDragon
2009. 10. 28. 14:39

포스트를 열심히 올리고자 마음 먹었지만
전혀 올리지 못 하고있었다. (마음만 앞섰을 뿐이고.. 그리고 귀찮았을 뿐이고..)
뭐 암튼 간만에 포스팅을 한다.

c#에서 DataTable 클래스에서 DataTable끼리의 Merge와 Sort가 있다. (그 밖에도 많겠지...)

대략 소스와 주석으로 설명을 대신하고자 한다.

 private void button1_Click(object sender, EventArgs e)
        {
            DataTable dt = GetData(1, 3);
            DataTable dt2 = GetData(2, 5);

// Merge
            DataTable dt3 = dt.Copy();
            dt3.PrimaryKey = new DataColumn[] { dt3.Columns["A"] };
            dt3.Merge(dt2);

// Sort
            DataView view = dt3.DefaultView;
            view.Sort = "B DESC, A ASC, C DESC";

            this.dataGridView1.DataSource = dt;
            this.dataGridView2.DataSource = dt2;
            this.dataGridView3.DataSource = view.ToTable();
        }

        DataTable GetData(int from, int to)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("A");
            dt.Columns.Add("B");
            dt.Columns.Add("C");
            Random rnd = new Random((int)DateTime.Now.Ticks);
            for (int i = from; i <= to; i++)
            {
                DataRow dr = dt.NewRow();
                dr["A"] = i;
                dr["B"] = rnd.Next(1, 5);
                dr["C"] = rnd.Next(1, 5);
                dt.Rows.Add(dr);
            }
            return dt;
        }


추가적인 설명으로
a.Merge(b); 처럼 Merge할 경우 b테이블의 데이터를 a테이블에 포함시키는 거라 할 수 있다.
만약 DataTable의 PrimaryKey 설정을 한다면 b테이블 데이터중 a테이블의 Key 컬럼과 중복되는 데이터를 제외한 데이터가 a테이블로 포함된다. (이해를 돕고자 이미지를 첨부)

PrimaryKey 설정 전

PrimaryKey 설정 후






Posted by CoolDragon
2009. 3. 19. 15:30


System.Net 네임스페이스를 통해서 단순히 소켓프로그래밍(TCP통신, UDP통신)만 하는것이 아니다.
여러가지 많은 것을 할 수 있는데.. System.Net.NetworkInformation.Ping에 대해 알아보겠다.

보통 cmd창에서 아래와 같이 해본사람이 많을 것이다.
    c:\> ping 127.0.0.1 (엔터)

이런 작업을 C#.NET 코드로 구현이 매우 쉽게 가능했다. 아래 샘플 코드만으로도 쉽게 이해할 수 있으리라 생각한다.

Ping.Send 함수는 overloading이 많은데 자세한 내용은 아래 링크를 참고하면 되겠다.
 -> http://msdn.microsoft.com/ko-kr/library/7hzczzed.aspx

참고로 무조건 timeout이 발생하는 hostname이 있을 수 있다. (예:www.daum.net, www.naver.com 등)
이것은 아마도 네트워크 관리자(?)가 해당 서버로 ping요청이 허용되지 않도록 막았을 가능성이 매우 크다.

-------------------------------------- 샘플코드 --------------------------------------

System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply reply = p.Send("127.0.0.1"); // www.contoso.com
MessageBox.Show(reply.Status.ToString() + "//" + reply.RoundtripTime.ToString());

--------------------------------------------------------------------------------------

Posted by CoolDragon
2009. 3. 9. 19:23

하나의 팁쯤이라고 생각해도 될 듯 하다.
.NET 에서 자바스크립트에서 사용되는 escape와 같은 함수를 사용하고 싶을때가 혹시라도 있을 것이다.
그럴 경우 난 System.Web.HttpUtility.UrlEncode를 사용하면 되는줄 알았다.
하지만 변환되는 형식이 당연히 틀렸다. (사실 틀릴줄은 알았지만 뭐 그냥 써도 되는줄로 알고 었었을 뿐이다.)
그런데 구글링을 통해서 알아낸 사실은 따로 escape와 같은 역할을 하는 클래스가 존재한다는 것이었다.
그 방법은 아래와 같다.

1. Microsoft.JScript 어셈블리를 참조한다.
2.
  escape    => Microsoft.JScript.GlobalObject.escape("바꿀 문자열");
  unescape => Microsoft.JScript.GlobalObject.unescape("바꿀 문자열");


이외에도 Microsoft.JScript.GlobalObject 클래스의 멤버가 여러가지 있으니 나중에 자바스크립트 관련된 일이 있으면
이 클래스를 우선 참고할 필요가 있겠다.

ps. 참 쉽죠 잉~?

Posted by CoolDragon