WiX Toolset 3.11 버전 기준으로 작성됨.
File element 는 File을 최종 사용자의 컴퓨터에 복사하려는 각 파일을 지정하는데 사용된다.
당연하게도 파일 경로를 식별하는 Source attribute은 꼭 작성해줘야 하고, Id, Name, KeyPath는 옵션입니다. Id 속성은 MSI 데이터베이스 행의 기본 키가 된다. 고유한 것이어야 하지만 File element를 참조한다는 점을 분명히 하기 위해 FILE로 시작하는 것을 고려할 수 있겠다. 설정 하지 않는다면 Source attribute의 이름으로 설정된다.
파일을 중요 파일로 표시하려면 (삭제 혹은 누락된 경우 복구) 해당 파일을 구성 요소의 KeyPath파일로 설정하면 된다. Component element 내에 하나의 파일만 배치해야 하므로 거의 모든 경우 해당 파일은 KeyPath 파일이어야 한다. 설정 하지 않는다면 구성 요소의 첫번째 파일이 자동으로 KeyPath 파일이 된다.
그 외, Hidden과 ReadOnly attribute 또한 유용하다.
- Hidden : 사용자가 숨겨진 파일을 표시하도록 폴더옵션을 설정하지 않으면 파일이 표시 되지 않는다. 숨김파일 처리
- ReadOnly : 읽을 수는 있지만 파일 속성을 변경하지 않는 한 수정할 수 없다.
아래는 작성 예이다.
<Component Id ="CMP_NonOverwriteATXT"
Guid ="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_NonOverwriteATXT"
Source="NonOverwiteA.txt"
Name="NonOverwiretA"
KeyPath="yes"/>
</Component>
위의 코드에서는 NonOverwiteA.txt 파일이 WiX 프로그램 내에 있으므로 상대경로를 써서 작성을 하였는데, 다른 폴더에 있는 경우 절대 경로("D:\ NonOverwiteA.txt ")나 상대 경로 ("..\..\NonOverwiteA.txt") 를 통해서 지정할 수 있다. 또 다른 한가지 방법은 preprocessor variable에 특정 경로를 지정하고, 소스에서 사용하는 방법이다.
아래처럼 지정해주고, 소스 내에서는 var.FilePath로 사용하면 된다.
<Component Id ="CMP_NonOverwiteATXT"
Guid ="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Source="$(var.FilePath)NonOverwiteA.txt" />
</Component>
내가 만든 프로그램을 C:\Program Files\ 이나 C:\Windows\System\ 등으로 복사하려면 어떻게 해야 할까?
Window Installer에서 제공하는 여러 디렉토리 속성을 사용하여 Directory element를 중첩으로 추가해주면 된다. 한가지 알아야 되는 점은 Id 속성이 TARGETDIR이고, 이름이 SourceDir인 Directory element로 시작을 해야 한다. 설치의 루트 디렉토리라고 생각하면 될 듯 하다. 따라서 항상 먼저 생성되고, 그 안에 다른 모든 Directory element들을 중첩하면 된다.
Directory element에는 Directory 테이블에서 기본 키 역할을 하는 Id속성이 있고, 위에 설명 처럼 미리 정의된 이름을 사용하거나 직접 정의할 수 있다. 폴더의 이름은 Name attribute에 지정한다. 이게 없으면 폴더가 생성되지 않고, 그 안에 들어갈 모든 파일이 대신 상위 폴더에 배치 된다. 기 정의된 Directory에는 Name attribute를 제공할 필요가 없다.
Directory 사용 예시 >
<Wix ....>
<Product ....>
<Package .... />
<Directory Id="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyProgramDir"
Name="MyProgramName" />
</Directory>
</Directory>
</Product>
</Wix>
속성 | 설명 |
ProgramFile64Folder | 64비트 Program Files 폴더의 전체 경로 |
ProgramFileFolder | 32비트 Program Fiels 폴더의 전체 경로 |
AppDataFolder | 현재 사용자에 대한 Roaming 폴더의 전체 경로 |
FontsFolder | Fonts 폴더의 전체 경로 |
LocalAppDataFolder | local 어플리케이션이 포함된 폴더의 전체 경로 |
StartMenuFolder | Start menu 폴더의 전체 경로 |
StartupFolder | Startup 폴더의 전체 경로 |
System64Floder | System64 폴더의 전체 경로 |
SystemFolder | 현재 사용자에 대한 System 폴더의 전체 경로 |
https://learn.microsoft.com/ko-kr/windows/win32/msi/property-reference?redirectedfrom=MSDN
Windows Installer에서는 모든 파일이 설치되기 전에 Component element에 래핑될 것으로 예상합니다. 항상 고유한 GUID를 갖는 구성 요소를 통해 Windows는 최종 사용자의 컴퓨터에 설치된 모든 파일을 추척할 수 있습니다. 설치하는 동안 이 정보는 Registry에 저장됩니다. 이를 통해 Windows는 제거 중에 제품의 모든 부분을 찾아 SW를 완전히 제거할 수 있습니다. 또한 이를 사용하여 복구 중에 누락된 파일을 교체할 수 있습니다. 이는 MSI 파일을 마우스 오른쪽 버튼으로 클릭하고 복구를 선택하여 실행할 수 있습니다.
각 Component element는 GUI attribute를 통해 고유한 GUID를 가져 옵니다. Visual Studio에서 GUID는 "도구 > GUID 만들기"를 통해서 생성하고 레지스트리 형식을 사용하여 새로운 GUID를 복사합니다. Component element ID 속성은 작성자가 만들어야 하며, 이는 MSI 데이터베이스 구성 요소의 기본 키 역할을 하므로 각 키도 고유해야 합니다.
Component를 생성하는 방법 1>
<Component Id ="CMP_NonOverwriteATXT"
Guid ="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_NonOverwriteATXT"
Source="NonOverwiteA.txt"
Name="NonOverwiretA"
KeyPath="yes"/>
</Component>
Direcotry에 Component를 추가하는 방법 1>
- 직접추가, 가장 간단하지만 파일과 폴더가 여러개라면 ??
<Directory Id ="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyProgramDir"
Name="first directory">
<Component Id="CMP_NonOverwriteATXT"
Guid="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_FIRST_DIR_NonOverwriteATXT"
Source="NonOverwiteA.txt"
KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
Direcotry에 Component를 추가하는 방법 2>
- DIrectoryRef element를 사용하여 Direcotry를 참조. Directory에 File을 추가하는 것과 Directory 생성부분을 분리
<Directory Id ="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyProgramDir"
Name="first directory">
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="MyProgramDir">
<Component Id="CMP_NonOverwriteATXT"
Guid="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_FIRST_DIR_NonOverwriteATXT"
Source="NonOverwiteA.txt"
KeyPath="yes"/>
</Component>
</DirectoryRef>
Direcotry에 Component를 추가하는 방법 3>
- ComponentGroup 내부에 구성 요소를 그룹화하고 해당 Directory element를 사용하여 대상 Directory를 설정.
<Directory Id ="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyProgramDir"
Name="first directory">
</Directory>
</Directory>
</Directory>
<ComponentGroup Id="ProductComponents"
Directory="MyProgramDir">
<Component Id="CMP_NonOverwriteATXT"
Guid="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_FIRST_DIR_NonOverwriteATXT"
Source="NonOverwiteA.txt"
KeyPath="yes"/>
</Component>
<Component Id="CMP_NonOverwriteBTXT"
Guid="D5F82112-A68C-4C3B-9478-54BE29151603">
<File Id="FILE_FIRST_DIR_NonOverwriteBTXT"
Source="NonOverwiteB.txt"
KeyPath="yes"/>
</Component>
</ComponentGroup>
Directory 구성을 먼저 다 하고, 그 이후에 DirectoryRef를 통해 Directory에 들어갈 파일들을 아래와 같이 작성할 수 있다. 여러개의 Component들을 각각의 DirectoryRef elment를 사용하여 작성할 수도 있고, 하나의 DirectoryRef elment에 여러개의 Component들을 배치할 수도 있다.
<Directory Id ="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyProgramDir"
Name="first directory">
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="MyProgramDir">
<Component Id="CMP_NonOverwriteATXT"
Guid="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_FIRST_DIR_NonOverwriteATXT"
Source="NonOverwiteA.txt"
KeyPath="yes"/>
</Component>
<Component Id="CMP_NonOverwriteBTXT"
Guid="D5F82112-A68C-4C3B-9478-54BE29151603">
<File Id="FILE_FIRST_DIR_NonOverwriteBTXT"
Source="NonOverwiteB.txt"
KeyPath="yes"/>
</Component>
</DirectoryRef>
ComponentGroup은 Component를 그룹화하는데 사용된다. 여러개의 Component를 참조하는 대신 그룹화 하여 하나의 GomponentGroup 참조하므로 유용하게 사용할 수 있다. ComponentGroup에 Directory attribute을 사용하여 포함될 Directory를 지정할 수 있다. ComponentGroup 대신 Component에서도 지정할 수 있다.
<ComponentGroup Id="ProductComponents"
Directory="MyProgramDir">
<Component Id="CMP_NonOverwriteATXT"
Guid="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_FIRST_DIR_NonOverwriteATXT"
Source="NonOverwiteA.txt"
KeyPath="yes"/>
</Component>
<Component Id="CMP_NonOverwriteBTXT"
Guid="D5F82112-A68C-4C3B-9478-54BE29151603">
<File Id="FILE_FIRST_DIR_NonOverwriteBTXT"
Source="NonOverwiteB.txt"
KeyPath="yes"/>
</Component>
</ComponentGroup>
DirectoryRef에 Component를 구성하고, 해당 ComponentRef를 통해 ComponentGroup을 지정하는 것도 가능하다.
<DirectoryRef Id="MyProgramDir">
<Component Id="CMP_NonOverwriteATXT"
Guid="A93701E5-2344-43D9-B7BE-6E07AC02333D">
<File Id="FILE_FIRST_DIR_NonOverwriteATXT"
Source="NonOverwiteA.txt"
KeyPath="yes"/>
</Component>
<Component Id="CMP_NonOverwriteBTXT"
Guid="D5F82112-A68C-4C3B-9478-54BE29151603">
<File Id="FILE_FIRST_DIR_NonOverwriteBTXT"
Source="NonOverwiteB.txt"
KeyPath="yes"/>
</Component>
</DirectoryRef>
<ComponentGroup Id="ProductComponentGroup">
<ComponentRef Id="CMP_NonOverwriteATXT" />
<ComponentRef Id="CMP_NonOverwriteBTXT" />
</ComponentGroup>
설치할 파일이 몇개 없다면 상관 없지만 많은 파일을 패키지화 하는 경우 모든 코드를 한곳에 모아두기 보다는 여러개로 분할할 수 있는데 이 때 쓰는 게 Fragment 이다. Fragment는 attribute가 필요하지 않다. 단지 컨테이너 일 뿐이다. 모든 Diretory나 모든 Component 등 그 안에는 무엇이든 배치할 수 있다.
댓글 영역