글 작성자: 써니루루

MSI 파일은 msiexec 로 실행하는 command line 을 위해 ProductCode를 알아야지 uninstall을 할 수 있습니다.

이를 위해서 MSI 파일의 ProductCode를 알아야 하는데, 파일의 속성을 아무리 봐도 ProductCode는 할 수 없죠.

참 짜증나게 만들었습니다 -_ -;


그러면 ProductCode를 어떻게 찾아낼지 생각하다가 vbs (Visual basic script)로 되어 있는 코드를 찾았습니다.


사용법은

C:\>cscript GetMSIProductCode.vbs ccmsetup.msi

Microsoft (R) Windows Script Host Version 5.7

Copyright (C) Microsoft Corporation. All rights reserved.

 

Database (MSI) = ccmsetup.msi

ProductName    = SMS Client Setup Bootstrap

ProductCode    = {292C90B8-E8FA-47A3-92BB-F2F62AC109FC}




처럼 입력하시면 알아낼 수 있고요.



알아낸 코드로

C:\>msiexec /x {292C90B8-E8FA-47A3-92BB-F2F62AC109FC}


위 코드처럼 입력하면 삭제됩니다.


GetMSIProductCode.vbs 파일의 코드는 다음과 같습니다.

 

' GetMSIProductCode.vbs

Option Explicit

' Variables
Const msiOpenDatabaseModeReadOnly     = 0

' Get command-line arguements
Dim argCount:argCount = Wscript.Arguments.Count

' Connect to the Windows Installer object.
On Error Resume Next
Dim installer : Set installer = Nothing
Set installer = Wscript.CreateObject("WindowsInstaller.Installer") : CheckError

' Open the database (read-only).
Dim databasePath:databasePath = Wscript.Arguments(0)
Dim openMode : openMode = msiOpenDatabaseModeReadOnly
Dim database : Set database = installer.OpenDatabase(databasePath, openMode) : CheckError

' Extract language info and compose report message
Wscript.Echo "Database (MSI) = "         & databasePath
Wscript.Echo "ProductName    = "         & ProductName(database)
Wscript.Echo "ProductCode    = "         & ProductCode(database)

' Clean up
Set database = nothing
Wscript.Quit 0

' Get the Property.ProductName value.
Function ProductName(database)
 On Error Resume Next
 Dim view : Set view = database.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductName'")
 view.Execute : CheckError
 Dim record : Set record = view.Fetch : CheckError
 If record Is Nothing Then ProductName = "Not specified!" Else ProductName = record.StringData(1)
End Function

' Get the Property.ProductCode value.
Function ProductCode(database)
 On Error Resume Next
 Dim view : Set view = database.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")
 view.Execute : CheckError
 Dim record : Set record = view.Fetch : CheckError
 If record Is Nothing Then ProductCode = "Not specified!" Else ProductCode = record.StringData(1)
End Function

Sub CheckError
 Dim message, errRec
 If Err = 0 Then Exit Sub
 message = Err.Source & " " & Hex(Err) & ": " & Err.Description
 If Not installer Is Nothing Then
  Set errRec = installer.LastErrorRecord
  If Not errRec Is Nothing Then message = message & vbNewLine & errRec.FormatText
 End If
 Fail message
End Sub

Sub Fail(message)
 Wscript.Echo message
 Wscript.Quit 2
End Sub




추가로.. .msp 파일은 패치 파일이므로 ProductCode는 패치를 적용하는 .msi 파일의 Product와 같습니다.

.msp를 설치했다고 해서 .msp를 먼저 지우는 것은 아닌가 보네요.


참고한 페이지들은 다음과 같습니다.

http://social.technet.microsoft.com/Forums/en-US/configmgrsdk/thread/b5d994b7-9ff6-4e0d-baa5-3159212604f5/

Uninstall MSI with VBScript

http://juice.altiris.com/download/3859/uninstall-msi-with-vbscript

 

How Can I Retrieve the Subject Property for a .MSI File?

http://www.microsoft.com/technet/scriptcenter/resources/qanda/jan07/hey0110.mspx

 

Microsoft ® Windows Server® 2003 R2 Platform SDK Web Install*

http://www.microsoft.com/downloads/details.aspx?FamilyID=0baf2b35-c656-4969-ace8-e4c0c0716adb&DisplayLang=en

 

22 MSI Script Examples (after Windows SDK installation)

C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\SysMgmt\MSI\scripts