리소스가 굉장히 많은 프로젝트를 구축할 때 포함된 파일을 모두 "빌드 작업" 속성을 "포함 리소스"로 바꾸려니 방법이 없더라.
여기서 말하는 방법은 정규식을 통한 csproj 파일 수정 방법으로,
빌드 전 이벤트에 넣는 식으로 사용할 수 있다.
우선 정규식으로 csproj 파일을 변경할 수 있는 프로그램을 만들어보자.
콘솔 프로그램이며, 아래와 같이 만들었다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace csprojReplace
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 1)
return;
string filePath = args[0].Trim();
if (!File.Exists(filePath))
return;
string fContent = ReadText(filePath);
string pattern = @"(<)(Content)(.+?Include=.+?\/>)";
string substitute = "$1EmbeddedResource$3";
string rtn = Regex.Replace(fContent, pattern, substitute);
WriteText(filePath, rtn);
}
public static string ReadText(string filePath)
{
StringBuilder sb = new StringBuilder();
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default))
{
string line;
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
}
}
return sb.ToString();
}
public static void WriteText(string filePath, string strData)
{
DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(filePath));
if (di.Exists == false) //If New Folder not exits
{
di.Create(); //create Folder
}
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
{
sw.WriteLine(strData.TrimEnd());
}
}
}
}
}
그리고 해당 프로젝트의 빌 드 후 이벤트 명령줄에는 아래와 같이 해당 프로젝트 루트로 빌드한 파일을 복사하도록 한다.
xcopy "$(TargetDir)*.*" "$(SolutionDir)..\Database\Nc5.DatabaseV2" /Y /S
echo "$(SolutionDir)..\Database\Nc5.DatabaseV2"
위의 소스를 빌드한 후 변경해야 할 프로젝트의 csproj 가 있는 폴더로 가서 빌드한 exe 파일을 붙여 넣는다.
그리고 변경 해야 하는 프로젝트의 프로젝트 속성 -> 빌드 전 이벤트에 아래와 같이 적어준다.
$(ProjectDir)csprojReplace.exe $(ProjectPath)
매번 진행하고 싶지 않다면, 아래와 같이 REM 명령어로 위의 명령어를 주석으로 처리할 수 있다.
REM $(ProjectDir)csprojReplace.exe $(ProjectPath)
빌드 전 편집 버튼을 누르고 매크로 버튼을 누르면 해당 매크로가 가리키는 것을 볼 수 있다.
이렇게 파일 리소스를 프로젝트 파일에 바이너리로 포함시킨 후에 해당 프로젝트에서 읽어오는 방법은 아래와 같다.
해당 내용은 아래와 같은 방법으로 읽어올 수 있다.
참고로 리소스에서 읽어올 때 폴더구조는
네임스페이스 + . + 서브폴더 + . + 파일명.확장자
방식으로 읽어올 수 있다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Assembly Asm = Assembly.GetExecutingAssembly();
var list = Asm.GetManifestResourceNames(); // string[] 타입으로 리소스의 리스트를 가져온다
string AsmName = Asm.GetName().Name;
string resourceName = AsmName + "." + "_02.funs" + "." + "F_CV_DT.sql"; // 숫자 폴더에는 앞에 언더바(_)를 붙인다
using (Stream stream = Asm.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
Console.WriteLine(result);
}
Console.Read();
}
}
}