SettingUI : https://ghost1372.github.io/settingsui/

2022년 7월 25일 기준 SettingsUI의 Nuget 버전은 2.1.6이다. 이걸 이용해서 .Net6 용 WPF를 프로젝트를 만들고 nuget을 추가 후 바로 빌드하면 빌드 안될수 있다. 내가 발생한 부분에 대한 내용 및 해결방법을 정리한다.

1. nuget 자체가 설치 안될수 있다

이건 다른사람은 가능할 수 있다. 현재 작업환경이 윈도11(개발자 프리뷰)인데 그러다 보니 버전이 안맞아 생기는 문제로, 이는 프로젝트의 최소 OS 지원버전을 경고창에 나오는대로 맞춰주면 넘어간다.

대충 10.0.19041로 해주면 된다

2.  SettingUI의 icon을 찾을수가 없다?

nuget이 다운로드된 경로 이하에 icon이 없어서 실행이 안된다는 경고가 뜰수 있는데, 해당경로는 아래와 같다. (위에서 10.0.19041 버전을 설정했을 경우)

C:\Users\Admin\.nuget\packages\settingsui\2.1.6\lib\net6.0-windows10.0.19041

그럼 그 이하에 원하는 경로에 맞게 

SettingsUI\Assets\icon.png 파일을 넣어주면 된다. 폴더와 파일이 아예 없어서 발생하는 문제이니 일단 아무 128짜리 그림파일 하나 놔두면 된다.

일단 여기까지...

VS2019에서 .NET5 프로젝트들을 생성하면 빌드시
Bin\Debug\net5.0 이나 net5.0-windows 같은 폴더 이하에 빌드파일들이 생성되는것을 확인할 수 있는데,

이렇게 되면 여러 프로젝트들을 묶은 솔루션 같은 경우 전체 프로젝트들을 빌드시 빌드파일들의 경로가 중구난방이 된다.

기존의 4.8이하의 버전에서는 프로젝트 속성에서 설정한 출력경로 거기에 바로 파일들이 떨어졌었는데 이번에는 .Net5의 특성으로 인해 각종 설정이 붙다보니 뒤에 계속 접미사가 붙는것 같다.

 

솔루션의 해당 프로젝트마다 프로젝트 편집기를 통해 xml파일을 편집하는 화면으로 넘어가서 

맨 아래쪽 네 라인을 추가하면 된다

<PropertyGroup>
   <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
   <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>

위 코드를 추가하면 프로젝트 속성에서 설정한 출력경로로 바로 어셈블리들이 떨어지게 된다.

각 프로젝트마다 설정해 줘야 한다.

 

2021-07-18 기준 Prism WPF Sample을 기준으로 하나씩 분석해 보려 한다.

기본적인 사용법 이후에 Prism을 잘 사용하기 위한 방법을 확인해보려 한다.

문제는 Prism 라이브러리에 플러그인 중 

이런것이 있는데....(NOTE 참고), 플러그인 이라서 큰 문제는 안되나, 이렇게 가는게 맞는지는 모르겠다...

일단 메인을 기준으로 확인해보려 한다.

개념에 대한 설명은 사실 너무 옛날 버전들을 기준으로 Documents가 있어 그것을 보고 설명하기에는 너무 다른 내용들인것 같고, 일단은 WPF Sample 로 나온 코드를 기준으로 각 챕터별로 구분하여 확인하고자 한다. 

챕터가 무려 29번까지 있어 내용은 길어보일 수 있지만, 중복되는 내용 및 이전에 했던 챕터의 내용을 알고있다는 가정하에 다음챕터에서 활용하는 경우가 굉장히 많으므로 이를 숙지하고 넘어가야 한다.

sample URL은 https://github.com/PrismLibrary/Prism-Samples-Wpf 이며 WPF를 기준으로 설명하겠다.

끝.

'개발 > Prism' 카테고리의 다른 글

[Prism][WPFSample] Custom Regions  (0) 2021.07.19
[Prism][WPFSample] Regions  (0) 2021.07.19
[Prism][WPFSample] BootstrapperShell  (0) 2021.07.19

API 서비스 를 위해 구현중인데
초기에는 잘 연결되던 DB접속정보중 ConnectionString에 설정한 Password가 사라지는 현상이 발생했다.

그래서 DB내 SP 호출하는데 DB연결이 안되니 에러를 뱉는것이었다.

그래서 찾아보니 

https://stackoverflow.com/questions/12467335/connectionstring-loses-password-after-connection-open

 

ConnectionString loses password after connection.Open

i'm using ADO.NET to get some information from the database on a server, so this is what i do: string conStr = "Data Source=myServer\SQLEXPRESS;Initial Catalog=DBName;User ID=myUser;Password=myPas...

stackoverflow.com

당연히 오버플로에 있었고,

https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.connectionstring?redirectedfrom=MSDN&view=netframework-4.7.2#System_Data_SqlClient_SqlConnection_ConnectionString 

 

SqlConnection.ConnectionString Property (System.Data.SqlClient)

Gets or sets the string used to open a SQL Server database.

docs.microsoft.com

해당 내용에 대한 MSDN,

즉, ConnectionString에 포함되는 키들 중에
Persist Security Info=true;
이걸 넣어야 된다는 것이었다. 즉, 생략하면 기본적으로 false이고, 이는 나중에 Password를 지운다라는 것이었으므로 시간이 지나 API를 다시 호출해보면 Password만 사라지는 현상이 있었던 것이다.

보안관련 이슈는 있을 수 있으니 관련 포스트들을 확인해야한다.

ps. MSDN을 다시한번 확인해보기

위상까지는 그렇고.....

한국에서는 C#이 자리잡을 곳이 없다.

게임업계에서는 Unity때문에 C#이 스크립트처럼 쓰이는 부분이라 쓰이는거지, 정통(?) C#을 사용한다고 볼수는 없다.

그나마 WFP나 UWP등의 윈도 클라이언트, 그리고 공장 자동화, 반도체 쪽에서 WPF나 Winform을 사용중이다.

서버쪽에서는 여전히 자바 엔터프라이즈 계열이 대부분이라 극단적인 자바 공화국임을 느낄수 있는게, 서버단에서 닷넷을 구하는 대기업은 거의 볼수 조차 없다.

넥슨에서 약간 서버쪽 구인을 하는것 같은데, 쿠팡은 C# 포함에서 약간 다양하게 뽑는것 같고(아마 도커 컨테이너 때문이지 않을까), 네이버, 카카오, 배민은 전부 자바나 모바일 관련만 뽑는다. 엔씨도 서버쪽은 전부 자바다.

그래서 그런지 C#은 책 찾기도 힘들다. 흔히 말하는 악순환이다.

개발자 없음 -> 책 없음 -> 기술 스택 부족 -> 기업에서 안찾음 -> 개발자 없음 -> ...

이 섹션에서 말하고 싶은건 한가지, C#은 책이 부족하다. 즉, 한글화 되는 책이 잘 없다.

그렇기 때문에 책이 나와도 금방 절판된다. 그러므로 책이 나오면 일단 괜찮다 싶으면 사고 봐라. 회사에서 책 사주는 복지가 있다면, 일단 안보더라도 책을 사라. 나중에 필요한데 나중에는 절판되서 책 안나온다. 아니면 원서를 아마존에서 배송비까지 주고 비싸게 주고 보면서 영어의 늪에서 허우적 거리면서 보게 될것이다.

아쉽지만 어쩔 수 없다. 험지에서 살아갈려면 이정도 노력은 해야지. 대신 인력풀이 그만큼 작다보니 고인물 되어서 나름 살아가기는 쉬울 수 있다.

요즘 좀 프로젝트 말미라 빡시게 돌아간다.


하면서 개인 스터디를 하고 있는데, 하면서 알게된 기초적인 프로그래밍 문법





다들 if문과 switch문이 비슷한 용도로 쓰이는것을 알것이다.

물른 다르지만 비슷하다.


즉 조건식으로 분기를 하기위해 사용되는데 개발자에 따라, 회사간의 정책에 따라 사용하는 방법은 다 다르겠지

Whatever!


나는 vs2005를 사용(.Net 2.0)


if문과 switch문에서 int a = 10을 주고

if( a == 0) ~

else if (a == 1) ~

else if (a == 2) ~

else if (a == 3) ~

~~~


이렇게 흘러가는데 만약 조건에 맞는 식이 저 밑에 있다고 치면 if문을 위에서부터 하나씩 전부 검사하고 내려온다.

이것을 어셈블리어로 확인할 수 있다.


if문에 진입하기 직전에 BreakPoint를 걸고 실행하면 if문앞에서 걸리면서 소스가 나올것이고,

소스화면에서 마우스 오른쪽 -> Go to Disassembly를 통해 확인할 수 있다.


대충 보면(나도 어셈블리어는 모른다 갸초보라 ㅠㅠ) jmp가 그 주소로 이동한다는  소리인데,

if문은 각 else if 문이 끝나는 지점에서 다음 else if 문의 주소로 jmp를 한다.(왜 jmp명령어를 사용하는지는 어셈블리어를 몰라서 모름. return 도 아닌데..)

if문은 이런식이고.....


switch문도 BreakPoint를 직전에 걸고 실행한 후 Disassembly를 통해 보면 switch인 조건식 검사 구문에서 다음 첫 case를 넘어가기 전까지 여기서 조건을 검사한 후 바로 해당 case로 넘어간다. case가 없으면 default가 지정되어 있으면 거기로 넘어가고  아니면 switch문 밖으로 jmp해버린다.


이것이 바로 if문과 switch문의 차이이기 때문에 실제 실행 속도면에서도 조건식이 많을경우 switch문이 빠른것을 알 수 있다.


출처 : http://nicejinux.net/bbs/zboard.php?id=lecture&no=66
-- 감사합니다

using System;        
using System.Diagnostics;        
using System.Windows.Forms;        
using System.Runtime.InteropServices;        

class InterceptKeys        
{        
        private const int WH_KEYBOARD_LL = 13; 
        private const int WM_KEYDOWN = 0x0100; 
        private static LowLevelKeyboardProc _proc = HookCallback;        
        private static IntPtr _hookID = IntPtr.Zero; 

        public static void Main()        
        {        
                _hookID = SetHook(_proc);        
                Application.Run(); 
                UnhookWindowsHookEx(_hookID);        
        }        

        private static IntPtr SetHook(LowLevelKeyboardProc proc) 
        {        
                using (Process curProcess = Process.GetCurrentProcess()) 
                using (ProcessModule curModule = curProcess.MainModule)        
                {
                        return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); 
                }        
        }        
        
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);        
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
        {        
                if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
                {        
                        int vkCode = Marshal.ReadInt32(lParam);        
                        Console.WriteLine((Keys)vkCode); 
                }        
        
                return CallNextHookEx(_hookID, nCode, wParam, lParam); 
        }
        
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);   
        
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
        [return: MarshalAs(UnmanagedType.Bool)] 
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);   
        
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); 
        
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
        private static extern IntPtr GetModuleHandle(string lpModuleName);  
}


콘솔어플리케이션으로 만들고 system.window.form하나 추가해주고 

+ Recent posts