728x90

IP Time 공유기를 사용하여 접속하면 보통 사설 IP 주소를 사용하게 된다.

내 PC의 공인 IP주소를 알아내는 코드는 Web 파싱을 이용하면 쉽다.


public static string getMyPublicIP()
{
    WebRequest request = WebRequest.Create("http://www.findip.kr");
    WebResponse response = request.GetResponse();
    StreamReader stream = new StreamReader(response.GetResponseStream());

    // 주소에 있는 텍스트 모두를 긁어 저장
    string firstStr = stream.ReadToEnd();
    // 파싱할 부분의 시작부분 검색
    int index1 = firstStr.IndexOf("<h1> 내 아이피 주소(My IP Address) :") + 31;
    // 끝부분 검색
    int index2 = firstStr.IndexOf("</h1>");
    //다시 담기
    string str = firstStr.Substring(index1, index2 - index1);
    return str;
}



블로그 이미지

Link2Me

,
728x90

C# Web 파일을 PC에 다운로드하기 위해 만든 함수다.

사용법은 Web 파일 다운로드 게시글을 참조하면 된다.


코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace NameSpace
{
    class Folder
    {
        public static void MyFolderCreate(string myfolder)
        {
            string MyPath = MyFolder(myfolder);
            if (!Directory.Exists(MyPath))
            {
                Directory.CreateDirectory(MyPath);
            }
        }

        public static string MyFolder(string myfolder)
        {
            string UserPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // User Documents 폴더
            return UserPath + "\\" + myfolder;
        }

        public static string MyfilePath(string myfolder, string appName)
        {
            return Folder.MyFolder(myfolder) + "\\" + appName;
        }

        public static void MyFolderDelete(string path)
        {
            DeleteDirectory(path, false);
        }

        public static void DeleteDirectory(string path, bool recursive)
        {
            if (recursive)
            {
                var subfolders = Directory.GetDirectories(path);
                foreach (var subfolder in subfolders)
                {
                    DeleteDirectory(subfolder, recursive);
                }
            }

            // Get all files of the folder
            var files = Directory.GetFiles(path);
            foreach (var file in files)
            {
                var attribute = File.GetAttributes(file);
                if ((attribute & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    File.SetAttributes(file, attribute ^ FileAttributes.ReadOnly);
                }
                File.Delete(file);
            }
            Directory.Delete(path);
        }

        public static string SSplit(string _body, string _parseString, int index)
        {
            // 엑셀 VBA 에서 사용하는 Split 함수처럼 만든 사용자 함수
            string varTemp = _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
            return varTemp;
        }
    }
}


블로그 이미지

Link2Me

,
728x90

NAudion DLL을 이용하여 만든 MP3 Player 허접한 버전이다.


작년에 기본적인 것만 만들어보다가 회사 일이 바빠서 손도 못대다가 최근에 C# 폴더 찾아보다가 발견하여 적어두고 소스코드를 포함해서 올린다.


자동 반복재생 처리하는 것까지 만들지를 못했다.

SQLite 를 이용하면 될 거 같은데 아직 이 기능을 제대로 익히지 못했다.

그냥 인터넷에 있는 아주 허접한 것보다는 약간 더 나은 수준정도인데 이것저것 참조해서 테스트해보면서 만들다가 만 거다.


LinkPlayer.zip






블로그 이미지

Link2Me

,
728x90

C# 독학하는 초보자인데 질문하신 분이 있어서 올립니다.

Encoding 자동 감지하는 소스를 올리지 않습니다.

그 부분은 Encoding enc = Encoding.Default;

와 같이 코드를 수동으로 처리해서 테스트하시기 바랍니다.


using System.IO;
private void btnHangul_Click(object sender, EventArgs e)
{
    // 한글이 포함되어 있는지 검사
    using (OpenFileDialog dlg = new OpenFileDialog())
    {
        dlg.Filter = "csv (*.csv) | *.csv";
        if (dlg.ShowDialog() == DialogResult.OK)
        {
            Read_CSV_firstColumn(dlg.FileName);
        }
    }
}

public void Read_CSV_firstColumn(string fileName)
{
    string delimiter = ";";  // 구분자
    Encoding enc = GetFileEncoding(fileName);
    if (enc == null)
    {
        MessageBox.Show("Encoding Detection failed.");
        return;
    }

    using (var sr = new StreamReader(fileName, enc, true))
    {
        string line = null;
        while ((line = sr.ReadLine()) != null)
        {
            string[] fields = line.Split(new string[] { delimiter }, StringSplitOptions.None);
            if (isContainHangul(fields[0]))  // 첫번째 칼럼에 한글이 포함되어 있으면
            {
                MessageBox.Show(fields[0] + " : 한글 포함되어 있네요");
            }
            else
            {
                MessageBox.Show(fields[0] + " : 한글 포함 안되어 있어요");
            }
        }
        sr.Close();
    }
}

/// <summary>
/// 문자열에 한글이 포함되어 있는지 검사하여 포함되어 있으면 true 반환
/// </summary>
public bool isContainHangul(string s)
{
    char[] charArr = s.ToCharArray();
    foreach (char c in charArr)
    {
        if (char.GetUnicodeCategory(c) == System.Globalization.UnicodeCategory.OtherLetter)
        {
            return true;
        }
    }
    return false;
}


블로그 이미지

Link2Me

,
728x90

C# 에서 관리자 권한으로 실행중인지 체크하는 코드다.

관리자 권한으로 실행중인지 알아야 할 때 이 코드를 활용하여 구현하면 도움이 될 거 같다.


using System;
using System.Security.Principal;


간단하게 작성하면

bool IsUserAdministrator(){
    WindowsIdentity user = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(user);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}


좀 더 자세히 작성하면

public bool IsUserAdministrator()
{
    bool isAdmin;
    WindowsIdentity user = null;
    try
    {
        user = WindowsIdentity.GetCurrent(); // 현재 로그인된 user의 정보
        if (user == null)
            throw new InvalidOperationException("Couldn't get the current user identity");
        WindowsPrincipal principal = new WindowsPrincipal(user);
        isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    catch (UnauthorizedAccessException ex)
    {
        isAdmin = false;
    }
    catch (Exception ex)
    {
        isAdmin = false;
    }
    finally
    {
        if (user != null)
            user.Dispose();
    }
    return isAdmin;
}

private void IsAdmin_Click(object sender, EventArgs e)
{
    if (IsUserAdministrator())
    {
        MessageBox.Show("관리자 권한으로 실행중입니다");
    }
    else
    {
        MessageBox.Show("관리자 권한으로 실행중이 아닙니다");
    }
}

블로그 이미지

Link2Me

,
728x90

트랙바를 이용하여 재생시간이 어느 정도 되고, 트랙바를 마음대로 움직여서 재생을 조절할 수 있게 하는 걸 하고 싶어서 폭풍검색을 해서 해결했다.

검색을 해보니 MP3 플레이어를 만드는 방법이 [DllImport("winmm.dll")] 를 이용하는 방법,  Interop.QuartzTypeLib.dll 을 이용하는 방법, NAudio.dll 를 이용하는 방법이 주로 나온다.

C# 5.0 프로그래밍 실전프로젝트(조호묵 저) 에 구현한 소스코드는 Interop.QuartzTypeLib.dll 을 이용하여 만들었다. (출판사 자료실 : http://www.kame.co.kr/)
winmm.dll 을 이용하여 tackBar 를 구현하려고 했으나 내 능력이 부족해서 구현할 수가 없었다.

검색하다보니 NAudio 를 활용하여 구현하면 된다는 내용이 블로그에 많았다.

그래서 이걸로 구현해보겠다고 마음먹고 구현을 해봤다.


처음에는 구글링한답시고 열라  삽질을 많이 했다.

구글링 검색해서 나오는 예제들은 모두 옛날 버전이더라.

유투브 동영상에 자료 찾아서 해봤는데 역시 예전버전이다. 하지만 모르는 코드를 알게되어 일부 건진 건 있다.



재생시간이 나오면서 트랙바가 움직이게 하는 걸 어떻게 할 수 있을까?

구글링해서 참조해서 만들어본 코드가

trackBar.Value = Convert.ToInt32((int)reader.CurrentTime.TotalSeconds * trackBar.Maximum / (int)reader.TotalTime.TotalSeconds);

이다.

그런데 NAudio 사이트에서 받은 코드에 나온 데모를 보니까 아주 간단하게 되어 있다.

trackBar.Value = Math.Min((int)((trackBar.Maximum * reader.Position) / reader.Length), trackBar.Maximum);


NAudio 트랙바 코드만 정리해보면

using NAudio.Wave;

using NAudio.FileFormats.Mp3;

private AudioFileReader reader;

private void timer1_Tick(object sender, EventArgs e)
{
    if (reader != null)
    {
        labelNowTime.Text = FormatTimeSpan(reader.CurrentTime); // 재생시간
        labelTotalTime.Text = FormatTimeSpan(reader.TotalTime);  // 총 시간
        trackBar.Value = Math.Min((int)((trackBar.Maximum * reader.Position) / reader.Length), trackBar.Maximum);
    }
}

private void trackBar_Scroll(object sender, EventArgs e)
{
    if (this.reader != null)
    {
        reader.Position = (trackBar.Value * reader.Length) / trackBar.Maximum;
    }
}


타이머가 동작되면 시간이 계산되어 움직이고, 타이머가 멈추면 같이 멈춘다.

트랙바에서 마우스로 찍으면 해당 지점에서 노래가 재생되도록 하고 싶어서 추가로 구현했다.

private void trackBar_MouseDown(object sender, MouseEventArgs e)
{
    if (this.reader != null)
    {
        double clickValue = ((double)e.X / (double)trackBar.Width) * (trackBar.Maximum - trackBar.Minimum);
        trackBar.Value = Convert.ToInt32(clickValue);
        reader.Position = (trackBar.Value * reader.Length) / trackBar.Maximum;
    }
}


NAudio 사이트 : http://naudio.codeplex.com/

에서 다운로드 하여 dll 파일을 참조로 포함시키고, 예제 소스코드를 참조할 수 있다.


// 재생시간 구현해보겠다고 삽질하면서 찾아낸 건데 나중에 도움이 될지도 몰라서 그냥 적어둔다.

public string Play_Duration(int iPostion)
{
    string strTimeLen = string.Empty;
    int iHour = iPostion / 3600;
    int iMinute = (int)((iPostion - (iHour * 3600)) / 60);
    int iSecond = (int)(iPostion - (iHour * 3600 + iMinute * 60));
    strTimeLen = String.Format("{0:D2}:{1:D2}:{2:D2}", iHour, iMinute, iSecond);

    return strTimeLen;
}

블로그 이미지

Link2Me

,
728x90

C# 자동 업데이터 구현 흐름도이다.

개념부족, 코드 활용 부족으로 몇일동안 만들어본 자동 업데이터의 코드 구현 흐름도이다.


Setup 파일은 Inno Setup 을 이용해서 만들고

자동업데이터는 설치된 폴더의 실행파일만 덮어쓰기 하는 형태다.

Program Files 폴더는 관리자권한이 있어야 파일 덮어쓰기가 가능하다.


서버에 있는 setup.txt 파일과 PC에 설치된 setup.txt 파일의 내용을 비교하여 버전이 서로 다르면 Updater 파일을 실행하고, 현재 실행된 파일은 종료시킨다.


Updater 파일에서도 버전 비교를 하는 이유는 업데이터 파일만 단독으로 실행했을 경우를 고려해서다.

보통은 업데이트할 내용을 팝업창으로 제공하지 않고 바로 서버에서 파일을 다운로드하여 덮어쓰기를 한다.

하지만 난 업데이트할 내용을 팝업창으로 제공되도록 보여줬다.




블로그 이미지

Link2Me

,
728x90

C# 에서 자동 업데이터를 만들어보고 있는데 Program Files(x86) 폴더 하단에 설치된 파일은 자동 업데이터를 구동시켜 보니까 Access 권한이 없다고 나온다.


Program.cs 파일 내용을 아래와 같이 수정해주면

파일 실행시 관리자 권한으로 실행할 것인지를 물어본다.

컴파일한 파일을 Program Files(x86) 폴더 해당폴더에 복사하고 나서 실행하니까 웹에서 파일을 다운로드 받아서 해당 폴더 파일을 업데이트한다.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using System.Security.Principal;

namespace AutoUpater
{
    static class Program
    {
        /// <summary>
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// </summary>
        [STAThread]
        static void Main()
        {
            if (IsAdministrator() == false)
            {
                try
                {
                    ProcessStartInfo procInfo = new ProcessStartInfo();
                    procInfo.UseShellExecute = true;
                    procInfo.FileName = Application.ExecutablePath;
                    procInfo.WorkingDirectory = Environment.CurrentDirectory;
                    procInfo.Verb = "runas";
                    Process.Start(procInfo);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
                return;
            }

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }

        public static bool IsAdministrator()
        {
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            if (null != identity)
            {
                WindowsPrincipal principal = new WindowsPrincipal(identity);
                return principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
            return false;
        }

    }
}




블로그 이미지

Link2Me

,
728x90

C# 을 배우면서 부족하지만 프로그램 하나를 만들었다.

설치 프로그램을 통해서 설치하고 uninstall 하는 걸 할 수 있도록 하는 걸 해보려고 찾아보니 Inno Setup 프로그램이 있다. Inno Setup 프로그램은 freeware 프로그램이다.


Inno Setup 프로그램 다운로드 : http://www.jrsoftware.org/isdl.php


Korean.isl


Inno Setup 파일을 설치하고 나서, 위 파일을 Languages 폴더에 복사한다.

그러면 프로그램 설치시에 한글로 메뉴가 나온다.


한두번 연습을 해보면서 기본적으로 터득한 것만 적어두려고 한다.

아직 부족한 부분은 나중에 알게되면 추가로 적어놓을 생각이다.


Inno Setup 실행파일을  실행하고 나면 아래 화면이 나온다.

New 아이콘을 눌러서 새로운 iss 파일을 만든다.






설치하는 파일에 ico 파일도 미리 만들거나 받아서 같이 설치해줘야 아이콘 모양이 같이 나온다.

아이콘 파일이 없으면 http://www.iconfinder.com 에서 받는다.




프로그램  설치전에 보여줄 텍스트파일 메시지와 설치되고 나서 버전업이 되면서 변화된 내용이 뭔지 알 수 있도록 보여주는 Chaneglog.txt 파일을 추가해준다.

파일은 반드시 UTF8 로 저장해야 글씨가 깨지지 않고 보인다.


미리 다운로드받아 Languages 폴더에 복사한 korean.isl 파일이 있으면 자동으로 선택할 수 있게 나온다.


아이콘 파일은 http://www.iconfinder.com 에서 찾아서 추가를 해줬다.

아이콘 편집기를 이용하여 본인만의 아이콘을 제작할 필요가 있다.



설치가 끝나고 나서 바로 compile 을 할 것인지 물어보는데

아니오를 선택했다.


EesyWig 으로 만들어진 파일을 저장한다.

가능하면 Setup 파일을 만들 폴더에 같이 저장하는게 편하다.

나중에 수동으로 편집하기가 편리하기 때문이다.


아래처럼 파일명을 생성할 때 버전정보가 같이 포함되게 작성하는 것도 팁의 하나라 볼 수 있다.


이제 make 를 하면 자동으로 Setup 파일이 만들어진다.


만들어진 setup 파일을 설치하면 Program Files(86) 폴더밑에 폴더가 생성되면서 프로그램이 생성된다.


참조하면 도움되는 블로그

http://blog.naver.com/empty_wagon/20141935914


부족하지만 이정도로 작성해둔다.

아직 바탕화면 아이콘 모양이 나오게 하는 것까지는 성공하지 못했다.

uninstall 도 실행해보니까 잘 된다.

Inno Setup 정말 멋진 프로그램 인거 같다.


바탕화면 아이콘이 나오게 하는 걸 알아냈다.

Files 라인에 ico 파일도 같이 복사하게 한 다음에

Source: "C:\LInkSutitle\LinkSubtitles.ico"; DestDir: "{app}"; Flags: ignoreversion


[Icons]

Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; WorkingDir: {app}; IconFilename: {app}\LinkSubtitles.ico; IconIndex: 0; Tasks: desktopicon


부분을 추가해주면 바탕화면 아이콘이 제대로 반영된다.


아직 의미파악은 안되었지만 다른 샘플들을 보고 추가한 부분을 적어둔다.

DisableProgramGroupPage=false
DisableReadyPage=true
PrivilegesRequired=admin
ShowLanguageDialog=yes
DisableDirPage=false
CloseApplications=true
AlwaysUsePersonalGroup=true


블로그 이미지

Link2Me

,
728x90

MP3 파일 헤더에 포함된 태그 정보를 가져오는 함수이다.

구글링을 통해서 얻은 자료를 가지고 쉽게 원하는 정보를 얻기 위해서 함수화를 했다.


사용법

using (OpenFileDialog dlgOpen = new OpenFileDialog())
{
    dlgOpen.Filter = "MP3 File|*.mp3";
    dlgOpen.Title = "Select Audio File";
    //dlgOpen.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);

    if (dlgOpen.ShowDialog() == DialogResult.OK)
    {
        // listView 등에 원하는 형태로 출력하여 사용
        MessageBox.Show("제목 : " + MP3TAG_Split(dlgOpen.FileName, 0));
    }
}



함수
/// <summary>
/// MP3 파일 헤더에 포함된 태그를 추출하여 타이틀, 가수, 앨범, 연도, 코멘ㅌ, 장르 정보를 가져옵니다
/// </summary>
/// <param name="filePath">파일경로를 포함한 MP3파일명</param>
/// <param name="index">추출할 인덱스</param>
/// <returns>추출된 문자열</returns>
public string MP3TAG_Split(string filePath, int index)
{
    string _parseString = ";";  // MP3_TAG 의 구분자
    string _body = MP3TAG_Read(filePath);
    if (_body != string.Empty)
    {
        return _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
    }
    else
    {
        return string.Empty;
    }
}

public string MP3TAG_Read(string filePath)
{
    using (FileStream fs = File.OpenRead(filePath))
    {
        if (fs.Length >= 128)
        {
            MP3ID3Tag tag = new MP3ID3Tag(); // 클래스형인 tag 객체 초기화
            fs.Seek(-128, SeekOrigin.End);
            fs.Read(tag.TAGID, 0, tag.TAGID.Length);
            fs.Read(tag.Title, 0, tag.Title.Length);
            fs.Read(tag.Artist, 0, tag.Artist.Length);
            fs.Read(tag.Album, 0, tag.Album.Length);
            fs.Read(tag.Year, 0, tag.Year.Length);
            fs.Read(tag.Comment, 0, tag.Comment.Length);
            fs.Read(tag.Genre, 0, tag.Genre.Length);
            string theTAGID = Encoding.Default.GetString(tag.TAGID);

            if (theTAGID.Equals("TAG"))
            {
                string Title = Encoding.Default.GetString(tag.Title);
                string Artist = Encoding.Default.GetString(tag.Artist);
                string Album = Encoding.Default.GetString(tag.Album);
                string Year = Encoding.Default.GetString(tag.Year);
                string Comment = Encoding.Default.GetString(tag.Comment);
                string Genre = Encoding.Default.GetString(tag.Genre);

                return string.Format("{0};{1};{2};{3};{4};{5}",Title,Artist,Album,Year,Comment,Genre);
            }
            else
            {
                return string.Empty;
            }
        }
        else
        {
            return string.Empty;
        }
    }
}



// MP3ID3Tag 의 클래스

class MP3ID3Tag
{
    public byte[] TAGID = new byte[3];      //  3
    public byte[] Title = new byte[30];     //  30
    public byte[] Artist = new byte[30];    //  30
    public byte[] Album = new byte[30];     //  30
    public byte[] Year = new byte[4];       //  4
    public byte[] Comment = new byte[30];   //  30
    public byte[] Genre = new byte[1];      //  1
}



블로그 이미지

Link2Me

,
728x90

메인폼(MainForm)에서 자식폼을 실행하고 난 후 자식폼의 종료버튼을 눌러도 종료되지 않도록 처리하는게 필요하여 적어둔다.




메인폼에서 자식폼을 띄우는 이벤트

private void pictureBoxOpen_Click(object sender, EventArgs e)
{
    foreach (Form openForm in Application.OpenForms)
    {
        if (openForm.Name == "MP3List") //폼 중복 열기 방지
        {
            if (openForm.WindowState == FormWindowState.Minimized)
            {
                openForm.WindowState = FormWindowState.Normal;
            }
            openForm.Activate();
            return;
        }
    }

    MP3List frm2 = new MP3List();
    frm2.TextSendEvent += new MP3List.MP3List_EventHandler(frm2_getTextEvent);
    frm2.Show();
}



자식폼에서 종료버튼을 클릭하면 종료되지 않고 윈도우 상태가 Minimized 되도록 처리하는 방법

private void MP3List_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        e.Cancel = true;
        this.WindowState = FormWindowState.Minimized;
    }
}


'C# > 기능 활용' 카테고리의 다른 글

Inno Setup 을 이용한 설치 프로그램 만들기  (2) 2015.12.27
C# MP3 파일 헤더정보 추출하는 함수  (0) 2015.12.02
C# DLL 만들기  (0) 2015.11.14
C# 프로그램 사용기한 체크  (0) 2015.10.23
C# Get Mac Address  (0) 2015.10.12
블로그 이미지

Link2Me

,

C# DLL 만들기

C#/기능 활용 2015. 11. 14. 00:00
728x90

DLL 이 외부로 공개할 수 있는 것은 클래스, 구조체, 열거형, 인터페이스 같은 타입인데 주로 클래스를 공개한다.


DLL 을 만들기 위한 절차

1. 비주얼 스튜디오 실행시킨 후 파일 - 새로 만들기 - 프로젝트를 실행한다.

클래스 라이브러리를 선택하고 파일 이름을 Link2Me 로 생성했다.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Link2Me
{
    public class Class1
    {
    }
}

로 기본 파일이 생성된다.


2. 만들고자 하는 코드를 작성한다.

using System;
using System.IO;
using System.Net;

namespace Link2Me
{
    public class Logic
    {
        /// <summary>
        /// 문자열 원본에서 오른쪽에서 부터 추출한 갯수만큼 문자열을 가져옵니다.
        /// </summary>
        /// <param name="Text">문자열 원본</param>
        /// <param name="nLength">추출할 갯수</param>
        /// <returns>추출된 문자열</returns>
        public string RIGHT(string Text, int nLength)
        {
            string ConvertText = string.Empty;
            if (Text.Length < nLength)
            {
                nLength = Text.Length;
            }
            ConvertText = Text.Substring(Text.Length - nLength, nLength);
            return ConvertText;
        }

        /// 문자열 원본에서 왼쪽에서 부터 추출한 갯수만큼 문자열을 가져옵니다.
        /// </summary>
        /// <param name="Text">문자열 원본</param>
        /// <param name="nLength">추출할 갯수</param>
        /// <returns>추출된 문자열</returns>
        public string LEFT(string Text, int nLength)
        {
            string ConvertText = string.Empty;
            if (Text.Length < nLength)
            {
                nLength = Text.Length;
            }
            ConvertText = Text.Substring(0, nLength);
            return ConvertText;
        }

        /// <summary>
        /// 문자열 원본의 지정한 위치에서 부터 추출할 갯수 만큼 문자열을 가져옵니다.
        /// </summary>
        /// <param name="Text">문자열 원본</param>
        /// <param name="nStart">추출을 시작할 위치, 0부터 시작</param>
        /// <param name="nLength">추출된 문자열</param>
        /// <returns>추출된 문자열</returns>
        public string Mid(string Text, int nStart, int nLength)
        {
            string ConvertText;
            if (nStart < Text.Length)
            {
                if ((nStart + nLength) <= Text.Length)
                {
                    ConvertText = Text.Substring(nStart, nLength);
                }
                else
                {
                    ConvertText = Text.Substring(nStart);
                }
                return ConvertText;
            }
            else
            {
                Text = string.Empty;  // 시작점이 길이보다 길면 반환할 것이 없음
                return Text;
            }
        }

        /// <summary>
        /// 문자열이 숫자인지 검사하여 숫자이면 true 를 반환
        /// </summary>
        public bool isNumeric(string str)
        {
            double Num;
            bool isNum = double.TryParse(str, out Num);
            if (isNum)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 원하는 문자열을 잘라내는 함수입니다
        /// </summary>
        /// <param name="_body">원본 문자열</param>
        /// <param name="_parseString">Split할 구분자</param>
        /// <param name="index">Split으로 잘라진 배열의 숫자</param>
        public static string SSplit(string _body, string _parseString, int index)
        {
            // 엑셀 VBA 에서 사용하는 Split 함수
            string varTemp = _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
            return varTemp;
        }

        /// <summary>
        /// 문자열에 한글이 포함되어 있는지 검사하여 포함되어 있으면 true 반환
        /// </summary>
        public bool isContainHangul(string s)
        {
            char[] charArr = s.ToCharArray();
            foreach (char c in charArr)
            {
                if (char.GetUnicodeCategory(c) == System.Globalization.UnicodeCategory.OtherLetter)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Public IP 주소를 문자열로 반환
        /// </summary>
        public static string GetRealIP()
        {
            string url = "http://www.findip.kr/";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";

            string resResult = string.Empty;
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                StreamReader readerPost = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8, true);
                resResult = readerPost.ReadToEnd();
            }

            if (resResult.IndexOf("내 아이피 주소(My IP Address) :") > 0)
            {
                int ingNO = resResult.IndexOf("내 아이피 주소(My IP Address) :");
                string varTemp = resResult.Substring(ingNO, 50);              
                string realip = SSplit(SSplit(varTemp, "내 아이피 주소(My IP Address) :", 1), "</h1>", 0).Trim();
                return realip;
            }
            return null;
        }
    }
}


3. 순수한 응용 프로그램 코드만 만드는 것이므로 Release 모드로 실행한다.

   



4. DLL 을 프로젝트 파일에 참조시키기








5. DLL 실행시키기

MessageBox.Show(Link2Me.Logic.GetRealIP());

로 테스트를 해봤다.

정상적으로 IP 정보를 잘 보여준다.

using Link2Me;

를 선언해서 사용해도 된다.


블로그 이미지

Link2Me

,
728x90

private void GetDueday()
{   // 프로그램 사용기한 체크
    try
    {
        // DB에 저장된 사용기한 날짜 정보를 가져와서 오늘날짜와 비교
        string enddate = "201510/09"; // DB에서 가져온 날짜라고 가정
        DateTime today, endday;
        today = System.DateTime.Today;
        endday = System.DateTime.Parse(enddate);
        TimeSpan dayDiff;  // 시간의 차이를 구할 때 TimeSpan 사용
        dayDiff = endday - today;
        if (dayDiff.TotalDays > 0)
        {
            MessageBox.Show("사용기한이 " + dayDiff.TotalDays + " 일 남았습니다");
        }
        else if (dayDiff.TotalDays.Equals(0))
        {
            MessageBox.Show("오늘까지 사용할 수 있습니다");
        }
        else
        {
            MessageBox.Show("사용기한이 만료되어 더이상 사용할 수 없습니다");
            Application.Exit();
        }
    }
    catch (Exception)
    {
        MessageBox.Show("날짜형식에 맞지 않습니다." + Environment.NewLine + "다음과 같은 형식으로 입력하세요." + Environment.NewLine + " 2015-10-01, 2015.10.01, 2015/10/01, 2015 10 01");
    }
}


DateTime과 TimeSpan 둘 다 시간을 표현한다.
DateTime은 TimeSpan 자료형이 된다.
TotalSeconds : 시간(초)의 정수 부분과 소수 부분으로 표시된 현재 TimeSpan 구조체의 값을 가져온다.
https://msdn.microsoft.com/ko-kr/library/system.timespan%28v=vs.110%29.aspx


TimeSpan 예제가 있는 사이트

http://www.dotnetperls.com/timespan

'C# > 기능 활용' 카테고리의 다른 글

C# 자식폼 종료아이콘 클릭시 다른 이벤트 실행되게 하기  (0) 2015.11.30
C# DLL 만들기  (0) 2015.11.14
C# Get Mac Address  (0) 2015.10.12
C# Get IP Address (사설 IP, 공인 IP)  (0) 2015.10.11
C# 인코딩  (0) 2015.09.24
블로그 이미지

Link2Me

,

C# Get Mac Address

C#/기능 활용 2015. 10. 12. 00:00
728x90

내 컴퓨터의 LAN 카드 MAC(하드웨어)주소를 알아내는 코드다.

MAC주소 포멧부분은 코드를 손을 봤다.

StringBuilder 기능을 활용하면 코드가 심플해진다.


private void GetMac_Click(object sender, EventArgs e)
{
    // MAC주소 가져오기
    MessageBox.Show(MACformat(GetMacAddress()));
}

public static string GetMacAddress()
{
    // MAC주소 가져오기
    return NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().ToString();
}

public static string MACformat(string str)
{   //Mac주소 포맷
    StringBuilder sb = new StringBuilder();
    char[] chrArr = str.ToCharArray();
    for (int i = 0; i < chrArr.Length; i++)
    {
        int n = i + 1;
        if (sb.Length > 0 && n % 2 !=0) sb.Append("-");
        sb.Append(chrArr[i].ToString());
    }
    string mac = sb.ToString();
    return mac;
}


'C# > 기능 활용' 카테고리의 다른 글

C# DLL 만들기  (0) 2015.11.14
C# 프로그램 사용기한 체크  (0) 2015.10.23
C# Get IP Address (사설 IP, 공인 IP)  (0) 2015.10.11
C# 인코딩  (0) 2015.09.24
문자열 암호화 - RSA, MD5, DES  (0) 2015.08.07
블로그 이미지

Link2Me

,
728x90

내가 사용하는 IP주소를 알아내기 위한 코드이다.

단순하게 IP주소를 알아내는 코드를 사용하면 사설IP주소(공유기 또는 방화벽내에서 사설 IP)를 사용하는 곳에서는 실제 인터넷에 접속된 IP주소와 다를 수가 있다.

공인 IP주소를 확인하기 위해서 파싱 방식으로 처리하였다.


using System.Net;
using System.IO;
using System.Text.RegularExpressions;


private void button1_Click(object sender, EventArgs e)
{
    if (GetRealIP().Equals(GetFirstIPv4()))
    {
        MessageBox.Show("Your IP Address : " + GetRealIP());
    }
    else   //
    {
        MessageBox.Show("Your Public IP Address : " + GetRealIP() + Environment.NewLine + "Your Private IP Address : " + GetFirstIPv4());
    }
}

public static string GetRealIP()
{
    string url = "http://checkip.dyndns.org";  //
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";

    string resResult = string.Empty;
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        StreamReader readerPost = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8, true);
        resResult = readerPost.ReadToEnd();
    }
    //MessageBox.Show(resResult);  //
    string realip = Parsing(Parsing(resResult, "Current IP Address:")[1], "</body>")[0].Trim();
    //MessageBox.Show(temp);  // 파싱한 이후의 메시지 확인
    return realip;
}

public static string[] Parsing(string _body, string _parseString)
{
    // 엑셀 VBA 에서 사용하는 Split 함수처럼 파싱을 쉽게 사용 가능하게 해줌
    // 만든이 : http://blog.naver.com/bobojisu
    return System.Text.RegularExpressions.Regex.Split(_body, _parseString);
}

public string GetFirstIPv4()
{
    Regex regex = new Regex(@"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$");
    foreach (System.Net.IPAddress ip in System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList)
    {
        if (regex.IsMatch(ip.ToString()))
        {
            return ip.ToString();
        }
    }
    return null;
}


공인(Public) IP 주소 가져오는 속도가 느려서 다른 사이트를 참조해서 작업을 했더니 Parinsing 함수쪽에서 에러가 발생한다. 그래서 다른 방법으로 해결을 했다.


public static string GetRealIP()
{
    string url = "http://www.findip.kr/";
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";

    string resResult = string.Empty;
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        StreamReader readerPost = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8, true);
        resResult = readerPost.ReadToEnd();
    }

    if (resResult.IndexOf("내 아이피 주소(My IP Address) :") > 0)
    {
        int ingNO = resResult.IndexOf("내 아이피 주소(My IP Address) :");
        string varTemp = resResult.Substring(ingNO, 50);
        string realip = Parsing(Parsing(varTemp, "내 아이피 주소(My IP Address) :", 1), "</h1>", 0).Trim();
        return realip;
    }
    return null;
}

public static string Parsing(string _body, string _parseString, int no)
{
    // 엑셀 VBA 에서 사용하는 Split 함수
    string varTemp = _body.Split(new string[] { _parseString }, StringSplitOptions.None)[no];
    return varTemp;
}





'C# > 기능 활용' 카테고리의 다른 글

C# 프로그램 사용기한 체크  (0) 2015.10.23
C# Get Mac Address  (0) 2015.10.12
C# 인코딩  (0) 2015.09.24
문자열 암호화 - RSA, MD5, DES  (0) 2015.08.07
C# OS 버전 및 플랫폼 확인 방법  (0) 2015.08.06
블로그 이미지

Link2Me

,

C# 인코딩

C#/기능 활용 2015. 9. 24. 00:30
728x90

Network Stream을 제외하고 모든 Stream 은 System.IO 네임스페이스에 정의되어 있다.

string 문자열을 C#의 Char[] 배열로 변경하는 것은 String 클래스의 ToCharArray() 메서드를 사용한다.


byte[]를 직접 string으로 변경하려면 우선 byte[] 가 어떤 Charset을 가지고 인코딩(ASCII, Unicode, UTF8 등) 되었는지 알아야 한다.


StreamReader 는 특정 인코딩으로 입력된 문자를 읽도록 설계된 반면 Stream 클래스는 입력 및 출력된 바이트를 읽도록 설계되었다.


3일간 발생하는 에러를 해결하지 못하다가 무료 Hex Viewer 를 설치해서 파일 인코딩 형식이 어떻게 되는지 파악하고서야 문제를 해결할 수 있었다.

http://mh-nexus.de/en/downloads.php?product=HxD

에서 다운로드 받을 수 있다.


HEXViewer.zip



Subtitle Edit 자막툴에서 제공하는 인코딩 모드를 변경해본 다음에 어떻게 변경되는지 일일이 확인을 해봤다.

그리고 EditPlus 로도 일일이 인코딩모드를 변경해서 확인을 해봤다.

CSV 파일로 내보내기를 한 파일도 조사를 해봤다. 다른 점이 발견되었다.










'C# > 기능 활용' 카테고리의 다른 글

C# 프로그램 사용기한 체크  (0) 2015.10.23
C# Get Mac Address  (0) 2015.10.12
C# Get IP Address (사설 IP, 공인 IP)  (0) 2015.10.11
문자열 암호화 - RSA, MD5, DES  (0) 2015.08.07
C# OS 버전 및 플랫폼 확인 방법  (0) 2015.08.06
블로그 이미지

Link2Me

,
728x90

처 : http://choiwonwoo.egloos.com/669096


crypt-9352-bugsoda.cs최상단의 const string desKey는 DES암호화에 필요한 키데이터이고 이 키 값은 임의로 정의해서 쓰시면 됩니다. 이 키값은 암호화와 복호화에 쓰이게 되므로 유출될 시에 문제가 발생할 수 있겠죠. 

출처는.. 데브피아 같은데 까먹었습니다 -_- (죄송합니다.)
원본소스를 조금 수정한 버전이라 다를수도 있겠네요.

C#으로 작성된 소스이며, VS.NET에서는 기본적으로 암호화 함수를 지원하고 있습니다. 아래 코드는 이 암호화함수들을 사용하는 셈플이지요.

using System;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.IO;

namespace Utility
{
/// <summary>
/// Crypt에 대한 요약 설명입니다.
/// </summary>
public class Crypt
{
// 암호화 키
private const string desKey="......";

public Crypt()
{
  //
  // TODO: 여기에 생성자 논리를 추가합니다.
  //
}

//------------------------------------------------------------------------
#region MD5 Hash

public static string MD5HashCrypt(string val)
{
  byte[] data = Convert.FromBase64String(val);
  // This is one implementation of the abstract class MD5.
  MD5 md5 = new MD5CryptoServiceProvider();
  byte[] result = md5.ComputeHash(data);

  return Convert.ToBase64String(result);
}

#endregion //MD5 Hash

//------------------------------------------------------------------------
#region DES암복호화

// Public Function
public static string DESEncrypt(string inStr)
{   
  return DesEncrypt(inStr,desKey);
}

//문자열 암호화
private static string DesEncrypt(string str,string key) 
{
  //키 유효성 검사
  byte[] btKey = ConvertStringToByteArrayA(key);

  //키가 8Byte가 아니면 예외발생
  if(btKey.Length!=8)
  {
   throw (new Exception("Invalid key. Key length must be 8 byte."));
  }

  //소스 문자열
  byte[] btSrc = ConvertStringToByteArray(str);
  DESCryptoServiceProvider des = new DESCryptoServiceProvider();
           
  des.Key = btKey;
  des.IV = btKey;

  ICryptoTransform desencrypt = des.CreateEncryptor();

  MemoryStream ms = new MemoryStream();

  CryptoStream cs = new CryptoStream(ms, desencrypt, 
   CryptoStreamMode.Write);

  cs.Write(btSrc, 0, btSrc.Length);
  cs.FlushFinalBlock();


  byte[] btEncData = ms.ToArray();

  return (ConvertByteArrayToStringB(btEncData));        
}//end of func DesEncrypt

// Public Function
public static string DESDecrypt(string inStr) // 복호화
{
  return DesDecrypt(inStr,desKey);
}

//문자열 복호화
private static string DesDecrypt(string str,string key) 
{
  //키 유효성 검사
  byte[] btKey = ConvertStringToByteArrayA(key);

  //키가 8Byte가 아니면 예외발생
  if(btKey.Length!=8)
  {
   throw (new Exception("Invalid key. Key length must be 8 byte."));
  }


  byte[] btEncData = ConvertStringToByteArrayB(str);
  DESCryptoServiceProvider des = new DESCryptoServiceProvider();
           
  des.Key = btKey;
  des.IV = btKey;

  ICryptoTransform desdecrypt = des.CreateDecryptor();

  MemoryStream ms = new MemoryStream();

  CryptoStream cs = new CryptoStream(ms, desdecrypt, 
   CryptoStreamMode.Write);

  cs.Write(btEncData, 0, btEncData.Length);

  cs.FlushFinalBlock();

  byte[] btSrc = ms.ToArray();


  return (ConvertByteArrayToString(btSrc));
  
}//end of func DesDecrypt

//문자열->유니코드 바이트 배열
private static Byte[] ConvertStringToByteArray(String s)
{
  return (new UnicodeEncoding()).GetBytes(s);
}

//유니코드 바이트 배열->문자열
private static string ConvertByteArrayToString(byte[] b)
{
  return (new UnicodeEncoding()).GetString(b, 0, b.Length);
}

//문자열->안시 바이트 배열
private static Byte[] ConvertStringToByteArrayA(String s)
{
  return (new ASCIIEncoding()).GetBytes(s);
}

//안시 바이트 배열->문자열
private static string ConvertByteArrayToStringA(byte[] b)
{
  return (new ASCIIEncoding()).GetString(b, 0, b.Length);
}

//문자열->Base64 바이트 배열
private static Byte[] ConvertStringToByteArrayB(String s)
{
  return Convert.FromBase64String(s);
}

//Base64 바이트 배열->문자열
private static string ConvertByteArrayToStringB(byte[] b)
{
  return Convert.ToBase64String(b);
}

#endregion //DES암복호화

//------------------------------------------------------------------------
#region RSA암복호화
//RSA 암호화
public static string RSAEncrypt(string sValue,string sPubKey)
{
  //공개키 생성
  byte [] keybuf = Convert.FromBase64String(sPubKey);
  sPubKey =  (new UTF8Encoding()).GetString(keybuf);
  System.Security.Cryptography.RSACryptoServiceProvider oEnc = new RSACryptoServiceProvider(); //암호화


  oEnc.FromXmlString(sPubKey);

  //암호화할 문자열을 UFT8인코딩
  byte [] inbuf = (new UTF8Encoding()).GetBytes(sValue);
  //암호화
  byte [] encbuf = oEnc.Encrypt(inbuf, false);
  
  //암호화된 문자열 Base64인코딩
  return Convert.ToBase64String(encbuf);
}
//RSA 복호화
public static string RSADecrypt(string sValue,string sPrvKey)
{
  //개인키 생성
  byte [] inbuf = Convert.FromBase64String(sPrvKey);
  sPrvKey =  (new UTF8Encoding()).GetString(inbuf);

  //RSA객체생성
  System.Security.Cryptography.RSACryptoServiceProvider oDec = new RSACryptoServiceProvider(); //복호화
  //개인키로 활성화
  oDec.FromXmlString(sPrvKey);

  //sValue문자열을 바이트배열로 변환
  byte [] srcbuf = Convert.FromBase64String(sValue);

  //바이트배열 복호화
  byte [] decbuf = oDec.Decrypt(srcbuf, false);

  //복호화 바이트배열을 문자열로 변환
  string sDec = (new UTF8Encoding()).GetString(decbuf,0,decbuf.Length);
  return sDec;
}

#endregion

}
}


'C# > 기능 활용' 카테고리의 다른 글

C# 프로그램 사용기한 체크  (0) 2015.10.23
C# Get Mac Address  (0) 2015.10.12
C# Get IP Address (사설 IP, 공인 IP)  (0) 2015.10.11
C# 인코딩  (0) 2015.09.24
C# OS 버전 및 플랫폼 확인 방법  (0) 2015.08.06
블로그 이미지

Link2Me

,
728x90

C# 소스 예제에 대한 설명을 보고 싶다면

http://www.codeproject.com/ 사이트를 참조


OS 버전 및 플랫폼 확인 방법


static void Main(string[] args)

        {

            OperatingSystem os = System.Environment.OSVersion;

            Console.WriteLine("플랫폼 : " + os.Platform);

            Console.WriteLine("서비스팩 : " + os.ServicePack);

            Console.WriteLine("버전 : " + os.Version);

            Console.WriteLine("버전 문자열 : " + os.VersionString);

            Console.WriteLine("CLR버전 : " + System.Environment.Version);

            Console.ReadLine();

        }


'C# > 기능 활용' 카테고리의 다른 글

C# 프로그램 사용기한 체크  (0) 2015.10.23
C# Get Mac Address  (0) 2015.10.12
C# Get IP Address (사설 IP, 공인 IP)  (0) 2015.10.11
C# 인코딩  (0) 2015.09.24
문자열 암호화 - RSA, MD5, DES  (0) 2015.08.07
블로그 이미지

Link2Me

,