C# 프로젝트 실행은 되지만 디자이너 모드에서 강제로 종료되는 현상

처리되지 않은 ‘System.Windows.Markup.XamlParseException’ 형식의 예외가 PresentationFramework.dll에서 발생했습니다.

추가 정보: The satellite assembly named “Microsoft.VisualStudio.Shell.UI.Internal.resources.dll, Version=12.0.0.0, PublicKeyToken=b03f5f7f11d5a3a” for fallback culture “en” either could not be found or could not be loaded. This is generally a setup problem. Please consider reinstalling or repairing the application.

정리해서 이야기를 하자면, Telerik 이라는 컴포넌트를 설치하고
다른 PC에서는 잘 열리는 프로젝트를 클린 설치를 해놓은 나의 PC에서 열려고 하면
디자이너 모드로 진입할 때 강제로 종료되는 현상이 발생하였다.

윈도우 재설치 4번과 비주얼스튜디오 재설치 5번을 거친 후에 겨우 해결을 했는데,
해결한 방법을 이야기 하면 이렇다.

Telerik 이라는 컴포넌트는 기본적으로 영문판이다.
물론 한국어 개발환경에서 설치는 문제없이 되지만, 정상 작동을 보장하지는 않는다.

잘 열리던 PC는 한글 윈도우에, 영문판 VS2013, 한글 언어팩을 설치한 것이다.
위의 메시지에서 요구하는 것처럼 en 언어 설정이 존재하는 상태이다.

그러나 나는 그것도 모른채로 한글 VS2013만 주구장창 설치를 하던 것이었다.
그래서 나도 영문판 VS2013 + 한글 언어팩 설치로 문제를 해결하였다.

어떤 문제이건간에, 초기 개발머신과 동일한 상태를 만드는 것이 가장 큰 해결책인 것이다.

첫 줄 colspan시에 table 사이즈 설정하기

<table>
<tr>
<td style=”width:30%;”></td>
<td colspan=”3″></td>
</tr>
<tr>
<td style=”width:30%;”></td>
<td style=”width:30%;”></td>
<td style=”width:10%;”></td>
<td style=”width:30%;”></td>
</tr>
</table>

만약에 이렇게 디자인을 할 경우에

첫 번째 줄의 사이즈는 제대로 표시되지만,
두 번째 줄의 사이즈는 제대로 표시가 되지 않는 현상이 있습니다.
(width값이 무시되고 균등하게 분할이 되어버립니다.)

이런 경우에는 아래처럼 하면 해결됩니다.

<table>
<colgroup>
<col style=”width:30%;”>
<col style=”width:30%;”>
<col style=”width:10%;”>
<col style=”width:30%;”>
</colgroup>
<tr>
<td></td>
<td colspan=”3″></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>

또한 colgroup에서 사이즈를 지정해준 경우에는
하부에 있는 td에는 사이즈를 지정하지 않아도 적용됩니다.

Toad 설치하면서

오늘 문득 Toad설치하면서

Toad for Oracle Freeware랑
Toad Development Suite for Oracle의 차이가 뭔지 되게 궁금했다..

근데 인스톨러를 까보니 답이 딱 나오네.. 

디벨럽먼트시트 안에 토드포오라클이 들어있는 개념이었음.. ㅋㅋ
별거 아닌데.. 가려운부분이 긁어진 느낌 ㅋㅋ

시원한데? ㅋㅋ

403 – 사용 권한 없음: 액세스가 거부되었습니다.

오늘 새롭게 작업한 프로젝트를 릴리즈를 한 후에 에러가 났다..
적절한 경로(가령.. http://127.0.0.1/login.aspx)를 입력하게 되면 문제없이 열리던 페이지가
그냥(가령 http://127.0.0.1)을 입력하면 접속이 안되는 것이다..

에러인 즉슨(? 맞춤법이 맞나?) 403에러 -> 이것도 좀 해맴..
Image

그래서 처음에는 “인증” 메뉴에서 뒤져봤는데.. 아닌거라.. ㅋㅋ
인터넷에 찾아보니.. “문서” 메뉴를 찾아보라고 해서.. “문서”를 찾으니 있어야지..
울 회사 차장님께서 그거 “기본 문서” 메뉴에서 추가하면 되잖아!! 라고 하셔서.. 해결함..
Image

이 메뉴 안에 들어가면 원래는 default.aspx 같은 파일들이 나열되었다..
그 파일들은 필요없어서 지워주고.. login.aspx를 추가해줬다..

이렇게 하니 에러없이 기본페이지가 화면에 보여졌다..

모두들 이렇게 해보세요..
어딜 찾아보니.. “문서”의 ‘ㅁ’자만 찾다가 낚여서.. “기본 문서” 입니다.
참.. 그리고 IIS6 기준입니다.

vb에서 Command(), Trim() 같은 내부함수 에러날 때

이것도 다른 방법을 찾다가 안되서..나만의 방법으로 해결한 내용이다..

우선 다른 분들의 답변들이다.. 데브피아는 참 좋은 곳이다.. 질문과 답이 유용하다..

1. http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=47&MAEULNo=19&no=219424&ref=219424
2. http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=47&MAEULNo=19&no=245682&ref=245682
3. http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=47&MaeulNo=19&no=310026&ref=310026

대부분의 답변들에 대해서 해결을 시도한 내용..

1. 참조에서 누락된 부분들 바꿔봐라 -> 누락이라고 표시되는게 어떤 건지 몰라서.. 시도조차 못함
2. 다시 설치해봐라.. -> VB6, MS-SQL 2008, VS 2008 외에 여러 컴포넌트들이 설치되어있는 회사 컴터에서 다시 설치한다는건.. VB6만 깔끔하게 지워지지 않을 수도 있다는 막연한 두려움과 함께 시도조차 하지 못함..

그래서 혹시나하는 마음에 참조를 뒤져보기로했다..Image

 

하지만.. 형님들 저는 “누락” 이라고 되어진 부분을 찾을 수가 없었어요..
그래서.. 주워들은게 있어서 Trim(), Command()가 VBA에 있는 함수라는 거다..

그 주워들은 지식을 바탕으로 밑으로 내려가봤다.. Visual Basic For Application 이라고 되어진게 
많이 있었다..

Image

 

이럴때는 무조건 체크하고 보는거다..

Image

 

그러고 확인을 누르니…

Image

같은 이름의 참조라 그런지 충돌이 난다면서 참조의 내용이 바뀌지는 않더라..

Image

그런데 웃긴게.. 실행이…. 실행이.. 잘되더라..

왜 그런걸까?

원인은 모르지만.. 자체적인 해결 솔루션을 발견했다..

하긴.. 원래 되던게 안되면.. 별 이유 없더라..

종료버튼 이벤트 처리하기

Image

그림에 재주가 없어서 엑셀로 그렸다. ㅎㅎ

이런 상황이다.
1. 기본적인 윈도우폼에서의 최소화, 최대화, 닫기 버튼이 있는 컨트롤 박스가 있다..
2. 폼 내에 닫기 버튼이 존재한다..

하고싶은 구현내용
-> 둘다 종료이벤트를 줘서 종료되도록 구현하고 싶다..

진행
1. 종료버튼에 이벤트 주기 (쉬워도 너~무 쉬운 인터넷에 널린 방법들.. e.Cancel = true 를 이용한다.
Image
2. 폼에 만든 [닫기] 버튼에 폼 종료 이벤트 주기
Image

그런데 문제가 발생했다.. 과정을 설명하자면 이렇다..
1. [닫기] 버튼을 클릭
2. 메시지 창이 출력됨 “Yes” 클릭 (버튼 클릭 이벤트에서 받아온 메시지 창)
3. 또 메시지 창이 출력됨 “Yes” 클릭 (폼 클로징 이벤트에서 받아온 메시지 창)

컨트롤 박스에서 “X”를 클릭했을 때는 문제가 없던 애가 버튼클릭으로 닫으니깐..
폼 클로징 이벤트까지 거치기 때문에 이런 문제가 발생하는 것..

방법을 강구하다가.. 이벤트 핸들러까지 갔는데.. 버튼끼리는 이벤트 핸들러로 연결이 가능한데..
파라미터가 다른 버튼과 폼 간에는 이벤트 연결이 불가하다는 결론이 났다..

방법이 없다기 보다는 내가 모른다는게 더 맞는 답일 것이다..
그래서 찾은 방법이 전역변수를 하나 둬서 버튼이 클릭 되었을 경우에는
폼 클로징 이벤트를 거치지 않도록 했다..

그리하여 탄생된 코딩..
1. 최 상단(클래스 선언 바로 밑단)에 불리언 변수 하나 둔다.. 이름은 상관없음..
Image
2. 버튼으로 종료가 된 경우에는 불리언을 참으로 만든다.
Image
3. 버튼으로 종료시킨 경우가 아닌 경우에만 폼 클로징에서 메시지 창을 띄운다..
Image

 

아래는 필요할 수도 있기에.. 코드 전문을 포함한다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace SSC
{
public partial class Form1 : Form
{
bool blnBtnClosing = false;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
txt_origin.Text = “”;
txt_day.Text = “”;
txt_week.Text = “”;
txtStatus.Text = “기동대기중”;
}

private void btn_origin_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.ShowDialog();
txt_origin.Text = dialog.SelectedPath;
}

private void btn_day_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.ShowDialog();
txt_day.Text = dialog.SelectedPath;
}

private void btn_week_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.ShowDialog();
txt_week.Text = dialog.SelectedPath;
}

// 닫기 버튼
private void btn_close_Click(object sender, EventArgs e)
{
if(MessageBox.Show(“종료하시겠습니까?”, “종료 확인”, MessageBoxButtons.YesNo) == DialogResult.Yes)
{
blnBtnClosing = true; // 버튼으로 종료 시킨 경우
this.DialogResult = DialogResult.Abort;
Application.Exit();
}
}

// 파일 복사
public void CopyFolder(string sourceFolder, string destFolder)
{
if (!Directory.Exists(destFolder)) Directory.CreateDirectory(destFolder);

string[] files = Directory.GetFiles(sourceFolder);
string[] folders = Directory.GetDirectories(sourceFolder);

foreach (string file in files)
{
string name = Path.GetFileName(file);
string dest = Path.Combine(destFolder, name);
File.Copy(file, dest, true);
}

// 안에 있는 폴더를 함수로 다시한번 돌리기
foreach (string folder in folders)
{
string name = Path.GetFileName(folder);
string dest = Path.Combine(destFolder, name);
CopyFolder(folder, dest);
}
}

private void btn_action_Click(object sender, EventArgs e)
{
//경로를 지정하지 않으면 메세지 박스로 알림.
if (txt_origin.Text == “” || txt_day.Text == “” || txt_week.Text == “”)
{
MessageBox.Show(“경로를 설정해야 합니다.”);
}
else if (cmb_date.SelectedItem == null || cmb_time.SelectedItem == null)
{
MessageBox.Show(“기본 옵션을 지정하세요.”);
}
else
{
if (txtStatus.Text == “기동대기중”)
{
txtStatus.Text = “실행중”;
timer1.Enabled = true;
}
else if (txtStatus.Text == “일시정지”)
{
txtStatus.Text = “실행중”;
timer1.Enabled = true;
}
else
{
txtStatus.Text = “일시정지”;
timer1.Enabled = false;
}
}
}

private void timer1_Tick(object sender, EventArgs e)
{
// 시간 계속 돌림
txtTimeNow.Text = System.DateTime.Now.ToString();

// 경로 받아옴
string sourceFolder = txt_origin.Text.ToString();
string destDayFolder = txt_day.Text.ToString();
string destWeekFolder = txt_week.Text.ToString();

if (sourceFolder != string.Empty && destDayFolder != string.Empty && destWeekFolder != string.Empty)
{
// 시간, 요일 할당
var Daily = System.DateTime.Now.Hour.ToString();
var Weekly = System.DateTime.Now.DayOfWeek;

// 시간이 같은 경우
if (cmb_time.SelectedItem.ToString().Equals(Daily) && System.DateTime.Now.Minute.ToString().Equals(“0”) && System.DateTime.Now.Second.ToString().Equals(“0”))
{
// 일일 백업
txtStatus.Text = “일간백업을 실행 중입니다.”;
CopyFolder(sourceFolder, destDayFolder);
txtStatus.Text = “실행중”;

// 요일을 한국어로 변환
var dayKor = “”;
switch (Weekly)
{
case DayOfWeek.Sunday:
dayKor = “일”;
break;
case DayOfWeek.Monday:
dayKor = “월”;
break;
case DayOfWeek.Tuesday:
dayKor = “화”;
break;
case DayOfWeek.Wednesday:
dayKor = “수”;
break;
case DayOfWeek.Thursday:
dayKor = “목”;
break;
case DayOfWeek.Friday:
dayKor = “금”;
break;
case DayOfWeek.Saturday:
dayKor = “토”;
break;
}

// 요일 비교
if (dayKor == cmb_date.SelectedItem.ToString())
{
// 주별 백업
txtStatus.Text = “주간백업을 실행 중입니다.”;
CopyFolder(sourceFolder, destWeekFolder);
txtStatus.Text = “실행중”;
}
}
}
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// 버튼으로 종료시킨 경우가 아닐 때
if (!blnBtnClosing)
{
if (System.Windows.Forms.MessageBox.Show(“종료하시겠습니까?”, “확인 취소”, MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
}

//public void formClose()
//{
// if (System.Windows.Forms.MessageBox.Show(“종료하시겠습니까:”, “확인 취소”, MessageBoxButtons.YesNo) == DialogResult.Yes)
// {
// Application.Exit();
// }
//}
}
}

[스크랩] C#에서 string.Empty

내가 C#을 하면서 문자열 초기화를 하면서 처음에 좀 신기했던 것이 문자열 초기화를 시킬 때 “”(큰 따옴표 묶음인 빈문자열)이 아니라, string.Empty로 초기화를 주는 것이었다.. 그래서 궁금해서 찾아봤는데.. 어떤 블로거 분이 너무 정리를 잘해주셔서 스크랩 해왔다..

출처: http://six605.tistory.com/320

C# Coding Standard (Coding Style) 을 보다 보면 다음과 같은 항목이 있다.
“”대신에 string.Empty를 사용하라!!

분명 이렇게 하라는 이유가 있을 것 같기에 자료좀 찾아 보았다.

1. string.Empty와 “”는 사용상의 약간의 차이점이 존재 하지만 동일한 의미 이다.

“”를 사용하는 곳에 string.Empty를 사용할 수 있다.
단, switch case 문에서 case 문에는 string.Emtpy가 올 수 없다.

2. string.Empty와 “”은 동일한 의미를 가지지만 내부적으로는 다르다.?!
다음의 블로그에 가보면 string.Empty와 “”는 내부적으로 다른 점을 갖고 있다고 말한다.
http://www.sleepyon.com/133
즉, “”는 컴파일 타임에 내부적으로 object 객체를 생성하고, string.Emtpy는 객체를 생성하지 않는다.
따라서 string.Emtpy를 사용하는 것이 더 효율적인 코드라고 말하고 있다.
그런데… 믿지 못하겠다. -_-;;

null 문자인지 비교하는 방법에 대한 차트도 보여주고 있다.
if (str == “”)
보다는
if (string.isNullOrEmpty(str))
이 빠른 비교 속도를 나타낸다고 한다.

Image

3. string.Emtpy 보단 “”를 사용할 때 이점이 더 많다?!
다음의 블로그에 보면 string.Empty 보다 “”를 사용할 때 이점이 더 많다고 말하고 있다.
http://dotnetperls.com/string-empty

즉, if (string.Empty == null) 보다
if (“” == null) 이 빠른 비교 속도를 나타낸다고 말하고 있다.

4. C# “” better than string.Empty ??
위 3번 글에 대한 어느 분의 대한 생각 글이다.
http://blog.dmbcllc.com/2009/04/20/c-better-than-stringempty/
3번에서 테스트한 시나리오가 현실에 맞지 않는다는 것과,
그 결과 역시 항상 “”가 너 좋지만은 않다는 것이다.
여전히 “”를 사용할 때 보다 string.Empty를 사용할 때 도 많은 이점을 누리게 된다고 말하고 있다.

난??
난 string.Emtpy를 더 즐겨 사용하려 한다.
일단 코드를 봤을 때 더 명시적으로 다가와서 좋으며
string보단 StringBuilder를 사용해야 되지 않겠는가!

테이블 줄바꿈과 줄바꿈막기

1. jQuery를 사용하는 웹페이지 (1024 X 768 사이즈)

2. POPUP창을 통해서 가로 800의 팝업창을 띄우도록 구성

3. 출력되는 테이블 구성이 좀 유별남..
1) 그림으로 표현하자면 이렇다..
Image
    2) 특징은 내용1,2,3 모두다 상당한 길이를 갖는 내용일 수 있다는 것이다.
그래서 전체적으로 레이블로 구성했다.. 걍 <td></td>로 묶으니
적절치 않은 것 같아서..
3) 결론적으로 이야기하면 가로길이가 총 800PX인데.. 그 이상 초과될 수 있다는 뜻..
4) 그래서 이게 늘어나면 이렇게 깨지더라.. (이것 때문에 정말 힘들었다.. ㅠㅠ)
Image
5) 게다가 내용3은 짤려서 더이상 보여지지도 않는 것임..
그래서 수도 없이 PX을 바꿔주면서 찾아다녔는데.. 안되더라..
6) 내용1은 줄바꿈이 되도록 내용2는 오른쪽으로 늘어나도록
내용3도 오른족으로 늘어나도록
이게 처음에는 가능하지 않은 줄 알았다.. 그래서.. 좀 구글링을 해봤다..

4. 해결책을 찾음..
1) 내용1의 <td>에는 CSS속성 중에 word-break:break-all;
white-space:pre-wrap;를 추가함
사이즈에 맞게 줄바꿈을 하는 속성이라고 하는데.. 아직 실력이 부족하여..
디테일한 부분은 감이 안 옴..
2) 내용2,3의 <td>에는 CSS속성 중에 white-space: nowrap; 을 추가함..
사이즈를 무시하고 줄바꿈 하지 않는 속성이라고 한다..

5. 그런데.. 이상한게.. 그런데도 계속 깨지더라.. 그래서 포기하려고 하는 와중에..
우리 과장님께서 찾아주셨다.. 테이블 자체에 속성을 넣어야 하더라..
그 속성은 바로.. <table>의 CSS속성 중에 table-layout:fixed; 이다..
<td>에만 넣는 다고 되는게 아니라
<table>에서 일그러지지 않도록 잡아주는 속성이다.

6. 결론적으로는 해결되었다..
1) <table> 의 table-layout:fixed;
2) 줄바꿈 줄 : <td>의 word-break:break-all; white-space:pre-line;
(지금 보니깐.. word-break는 필요없을 듯 하긴하다.. 직접 테스트 해보시길..)
3) 줄안바꿈 줄 : <td>의 white-space: nowrap;

나날이 늘어가는 야근과 함께 향상되는 나의 실력.. ㅠㅠ

C#에서 엑셀 참조시에 주의할 내용

참조추가를 누르면 탭이 여러개가 있다.. (기준은 VS2008)

.NET, COM, 프로젝트, 찾아보기, 최근에 사용한 파일

방법은 두가지가 있다.. .NET을 사용하는 방법, COM을 사용하는 방법

둘중에 아무거나 하면 된다고 한다..

나도 마찬가지로 두가지 중에 아무거나 하면 되리라 생각해서

아무거나 하니깐 되긴한다..

근데.. 문제는 COM으로 할 경우에는 개발하는 곳에 설치된 오피스와

배포지에 설치된 오피스의 버젼이 동일해야 한다..

만약 2003, 2007, 2010이 설치되어있다한다면.. 2010이

혹은 2003, 2010이 설치되어있다고 해도, 2010이

배포지에 설치되어있어야 한다.

최종 버전을 따라가는 것 같다..

나도 2003, 2010이 설치되어있는 상태에서 

2003 어샘블리를 추가했는데도

2003이 설치된 배포지에서 실행이 되지 않았다..

또 예외처리를 보니깐 2010을 찾고 있었다..

결론적으로 2010, 그러니깐 최종버전을 따라가는 것 같다..

그래서 나는 배포할 때 .NET으로 배포하도록 했다..

그리고 엑셀의 대단한 기능들을 사용하지 않기 때문에 

Microsoft.Office.Interop.Excel 11.0.0.0 과

Office 11.0.0.0을 참조했다..

그 후에 배포하니.. 별문제 없이 배포되었다..

문제는 서버인데.. 아마도 윈도서버 자체에 .NET프레임워크가 있기때문에

그리고 WIN 2008 R2 정도만 되어도 .NET 3.5는 설치되기 때문에

Microsoft.Office.Interop.Excel 11.0.0.0 과

Office 11.0.0.0정도는 무방하다 생각되었다..

결론적으로는 .NET으로 배포되었다..

그리고 아까 말했던 내용이 무엇이냐면..

COM 부분에서 

Microsoft Excel 11.0 Object Library를 추가하면 자동으로 Office도 딸려오더라..

그래서 추가가 된 것이.. Microsoft Office 11.0 Object Library인데..

참조 속성의 경로에 보면

C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Interop.Excel\14.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll

라고 되어있는 것 처럼 14.0을 가리키게된다..

그래서 배포지에서 실행을 하면 14.0이 없다면서 에러를 뿜는다..

결론은 2003으로 배포하고 싶으면 2003만 깔아서 2003으로 배포를 하던지..

2010이 설치되어있는 상황에서 배포해서 2003에서 사용하도록 하던지다..

해결되니.. 뭐.. 쉬웠네 소리 나오네..

Excel 메서드 SaveAs()의 참고사항

기본적으로 빈값에는 False나 Null을 넣는게 일반적이라고 하던데.. 

SaveAs()에는 Type.Missing을 넣는게 더 좋다고 했다..

인터넷 어딘가에 있는 내용인데.. 기억이 안나서 예제만 올리겠다..

// to save the excel sheet….
oWorkBook.SaveAs(
strPath // File Name
, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal // Format
, Type.Missing // Password
, Type.Missing // Write Res Password
, false // Read Only Recommended
, false // Create Backup
, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared // Access Mode
, false // Conflict Resolution
, false // Add To Mru
, Type.Missing // Text Code Page
, Type.Missing // Text Visual Layout
, Type.Missing // Local
);