Etc/2021

[NSIS] nsis 스크립트에서 and, or 논리 연산 사용하기 (조건문 여러 개 사용하기)

메바동 2021. 7. 16. 13:25
728x90

 

${If}와 ${OrIf} 혹은 ${AndIf}를 같이 사용하여 여러 개의 조건문을 엮을 수 있다.



설치 파일을 만드는 부분에서 레지스트리 등록을 해야 했다

크롬 및 엣지에서 외부 프로그램 사용 여부를 묻지 않고 바로 실행되도록 AutoLaunchProtocolsFromOrigins 및 UrlAllowlist, UrlWhitelist에 값을 추가해야 하는 부분이었다.

 

기존에는 url 리스트의 경우 1번으로 그냥 추가하도록 되어있었고 auto launch 부분도 해당 값으로 덮어 씌우게 되어있었다. 물론 해당 레지스트리를 사용하는 다른 프로그램이 없을 경우 문제가 되지 않을 테지만, 만약 해당 레지스트리를 사용하는 다른 프로그램이 있을 경우 해당 값이 사라지게 되어 문제가 생길 수 있다고 판단했다.

 

우선 AutoLaunchProtocolsFromOrigins 레지스트리의 경우

 

 

SOFTWARE\Policies\Microsoft\Edge\AutoLaunchProtocolsFromOrigins = [
  {
    "allowed_origins": [
      "example.com",
      "http://www.example.com:8080"
    ],
    "protocol": "spotify"
  },
  {
    "allowed_origins": [
      "https://example.com",
      "https://.mail.example.com"
    ], 
    "protocol": "msteams"
  }, 
  {
    "allowed_origins": [
      "*"
    ], 
    "protocol": "msoutlook"
  }
]
 

 

위와 같은 형식으로 작성이 된다.

따라서, AutoLaunchProtocolsFromOrigins의 값이 없을 경우나 이미 내가 추가해 주고 싶은 값이 들어있을 경우에는 해당 값으로 저장하고, 이미 값이 있을 경우 마지막 '}' 뒤에 내가 사용할 값을 붙여주는 형식으로 만들어 주어야 했다.

 

이때, if문으로 비어 있을 경우와 내가 사용할 값이 이미 있는 경우를 or 연산으로 묶어야 했는데 nsis에서는 논리 연산자가 존재하지 않았다. 그래서 다음과 같이 해결해 주었다.

 

!include "LogicLib.nsh"
!include "WordFunc.nsh"

Section -main
  ReadRegStr $0 HKLM "SOFTWARE\Policies\Microsoft\Edge" "AutoLaunchProtocolsFromOrigins"

  ${if} $0 == ''
  ${OrIf} $0 == '[{"allowed_origins": ["*"], "protocol": "mebadong"}]'
    StrCpy $0 '[{"allowed_origins": ["*"], "protocol": "mebadong"}]'
  ${else}
   ${WordReplace} $0 "}" '}, {"allowed_origins": ["*"], "protocol": "mebadong"}' "-1" $0
  ${endif}
SectionEnd
 

 

우선 분기문, 반복문, 논리 연산을 사용하기 위해서는 "LogicLib.nsh"를 꼭 불러와야 한다.

 

${if}를 사용해서 조건을 하나 작성한 뒤, 그 뒤에 ${OrIf}를 사용하면 OR로 묶이게 되고, ${AndIf}를 사용하면 AND로 묶이게 된다.

위에 작성한 스크립트를 실행해 보면

 

 

다음과 같이 msoutlook이 이미 작성되어 있을 경우 마지막 '}' 뒤에 내가 사용할 값을 이어 붙인 문자열이 출력되고,

 

 

AutoLaunchProtocolsFromOrigins의 값이 비어 있거나 없을 경우 내가 사용할 값만 출력이 되게 된다.

 

 

 

 

 

다음으로 UrlAllowlist에 값을 추가하는 경우에는 반복문과 논리 연산을 사용해야 했다.

 

 

SOFTWARE\Policies\Microsoft\Edge\URLAllowlist\1 = "contoso.com"
SOFTWARE\Policies\Microsoft\Edge\URLAllowlist\2 = "https://ssl.server.com"
SOFTWARE\Policies\Microsoft\Edge\URLAllowlist\3 = "hosting.com/good_path"
SOFTWARE\Policies\Microsoft\Edge\URLAllowlist\4 = "https://server:8080/path"
SOFTWARE\Policies\Microsoft\Edge\URLAllowlist\5 = ".exact.hostname.com"

 

UrlAllowlist의 구조가 다음과 같이 되어 있는데 값 이름이 1부터 순차적으로 증가하는 형식으로 되어있기 때문에 마지막 숫자나, 혹은 내가 사용할 값이 있는 부분을 찾아 해당 순서에 추가해 주어야 한다.

반복문을 돌면서 값 이름을 1씩 증가시키고 해당 부분이 비어있거나 원하는 값이 있는지 확인하면 된다.

 

!include "LogicLib.nsh"

Section -main
  IntFmt $0 "%d" "0"

  ${Do}
    IntOp $0 $0 + 1
    ReadRegStr $1 HKLM "SOFTWARE\Policies\Microsoft\Edge\URLAllowlist" $0
    ${If} $1 == ''
    ${OrIf} $1 == 'https://mebadong.tistory.com'
      ${Break}
    ${EndIf}
  ${Loop}
SectionEnd

 

위와 같이 Do... Loop를 이용하고 마지막 부분에 ${If}와 ${OrIf} 혹은 ${AndIf}를 사용해서 빠져나오고 싶은 조건을 적어주고 ${break}를 사용해주면 반복문에 논리 연산자를 사용한 것처럼 동작한다.

 

!include "LogicLib.nsh"

Section -main
  IntFmt $0 "%d" "0"

  loop:
    IntOp $0 $0 + 1
    ReadRegStr $1 HKLM "SOFTWARE\Policies\Microsoft\Edge\URLAllowlist" $0
    ${If} $1 != ''
    ${AndIf} $1 != 'https://mebadong.tistory.com'
      Goto loop
    ${EndIf}
SectionEnd

 

혹은 loop:로 감싸준 다음 조건문을 주고 Goto문을 이용해서 같은 결과를 얻을 수 있다.

위의 스크립트는 ${AndIf}를 사용하였다.

 

 

다음과 같이 값 이름이 5까지 존재할 경우 6번째 값에 반복문이 멈추게 되고, 해당 위치에 원하는 레지스트리를 등록해주면 된다.

 

 

값 이름 2에 원하는 데이터가 들어가 있을 경우 2번째 값에 반복문이 멈추는 것을 확인할 수 있다.

 

 

NSIS 스크립트를 만지는 게 귀찮아서 수정해야지~ 수정해야지~~ 생각만 하다가 이번에 간단히 찾아보며 수정할 수 있었다.

지금까지 다뤄왔던 스크립트 언어들과는 다르게 다루기 너무 불편한 스크립트 같다.

제발 다시는 수정할 일이 없었으면 좋겠네

728x90