WIX에서 사용자 정의 작업을 정의하는 가장 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/128279

  •  02-07-2019
  •  | 
  •  

문제

나는있다 wix 설치 프로그램의 속성을 사용하는 설치 관리자 및 단일 사용자 정의 작업 (플러스 실행 취소 및 롤백). 모든 파일이 하드 디스크에있는 후에 사용자 정의 작업이 발생해야합니다. 이를 위해 WXS 파일에 16 개의 항목이 필요한 것 같습니다. 루트 내에서 8 개 : 그렇게 :

<CustomAction Id="SetForRollbackDo" Execute="immediate" Property="RollbackDo" Value="[MYPROP]"/>
<CustomAction Id="RollbackDo" Execute="rollback" BinaryKey="MyDLL" DllEntry="UndoThing" Return="ignore"/>
<CustomAction Id="SetForDo" Execute="immediate" Property="Do" Value="[MYPROP]"/>
<CustomAction Id="Do" Execute="deferred" BinaryKey="MyDLL" DllEntry="DoThing" Return="check"/>
<CustomAction Id="SetForRollbackUndo" Execute="immediate" Property="RollbackUndo" Value="[MYPROP]"/>
<CustomAction Id="RollbackUndo" Execute="rollback" BinaryKey="MyDLL" DllEntry="DoThing" Return="ignore"/>
<CustomAction Id="SetForUndo" Execute="immediate" Property="Undo" Value="[MYPROP]"/>
<CustomAction Id="Undo" Execute="deferred" BinaryKey="MyDLL" DllEntry="UndoThing" Return="check"/>

그리고 8 개 InstallExecuteSequence, 그렇게 :

<Custom Action="SetForRollbackDo" After="InstallFiles">REMOVE&lt;>"ALL"</Custom>
<Custom Action="RollbackDo" After="SetForRollbackDo">REMOVE&lt;>"ALL"</Custom>
<Custom Action="SetForDo" After="RollbackDo">REMOVE&lt;>"ALL"</Custom>
<Custom Action="Do" After="SetForDo">REMOVE&lt;>"ALL"</Custom>
<Custom Action="SetForRollbackUndo" After="InstallInitialize">REMOVE="ALL"</Custom>
<Custom Action="RollbackUndo" After="SetForRollbackUndo">REMOVE="ALL"</Custom>
<Custom Action="SetForUndo" After="RollbackUndo">REMOVE="ALL"</Custom>
<Custom Action="Undo" After="SetForUndo">REMOVE="ALL"</Custom>

더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

Wix 설치 프로그램을 작성할 때도 같은 문제를 발견했습니다. 문제에 대한 나의 접근 방식은 대부분 Mike가 제안한 것과 비슷하며 블로그 게시물이 있습니다. WIX 사용자 정의 작업 구현 파트 2 : 사용자 정의 테이블 사용.

요컨대, 데이터의 사용자 정의 테이블을 정의 할 수 있습니다.

<CustomTable Id="LocalGroupPermissionTable">
    <Column Id="GroupName" Category="Text" PrimaryKey="yes" Type="string"/>
    <Column Id="ACL" Category="Text" PrimaryKey="no" Type="string"/>
    <Row>
        <Data Column="GroupName">GroupToCreate</Data>
        <Data Column="ACL">SeIncreaseQuotaPrivilege</Data>
    </Row>
</CustomTable>

그런 다음 단일 즉각적인 사용자 정의 조치를 작성하여 연기, 롤백 및 커스텀 액션을 예약하십시오.

extern "C" UINT __stdcall ScheduleLocalGroupCreation(MSIHANDLE hInstall)
{
    try {
        ScheduleAction(hInstall,L"SELECT * FROM CreateLocalGroupTable", L"CA.LocalGroupCustomAction.deferred", L"create");
        ScheduleAction(hInstall,L"SELECT * FROM CreateLocalGroupTable", L"CA.LocalGroupCustomAction.rollback", L"create");
    }
    catch( CMsiException & ) {
        return ERROR_INSTALL_FAILURE;
    }
    return ERROR_SUCCESS;
}

다음 코드는 단일 사용자 정의 작업을 예약하는 방법을 보여줍니다. 기본적으로 사용자 정의 테이블을 열고 원하는 속성을 읽습니다 (전화하여 사용자 정의 테이블의 스키마를 얻을 수 있습니다. msiviewgetColumnInfo ()), 그런 다음 필요한 속성을 CustomActionData 속성 (나는 양식을 사용합니다 /propname:value, 원하는 것을 사용할 수 있지만).

void ScheduleAction(MSIHANDLE hInstall,
            const wchar_t *szQueryString,
            const wchar_t *szCustomActionName,
            const wchar_t *szAction)
{
    CTableView view(hInstall,szQueryString);
    PMSIHANDLE record;

    //For each record in the custom action table
    while( view.Fetch(record) ) {
        //get the "GroupName" property
        wchar_t recordBuf[2048] = {0};
        DWORD    dwBufSize(_countof(recordBuf));
        MsiRecordGetString(record, view.GetPropIdx(L"GroupName"), recordBuf, &dwBufSize);

        //Format two properties "GroupName" and "Operation" into
        //the custom action data string.
        CCustomActionDataUtil formatter;
        formatter.addProp(L"GroupName", recordBuf);
        formatter.addProp(L"Operation", szAction );

        //Set the "CustomActionData" property".
        MsiSetProperty(hInstall,szCustomActionName,formatter.GetCustomActionData());

        //Add the custom action into installation script. Each
        //MsiDoAction adds a distinct custom action into the
        //script, so if we have multiple entries in the custom
        //action table, the deferred custom action will be called
        //multiple times.
        nRet = MsiDoAction(hInstall,szCustomActionName);
    }
}

연기, 롤백 및 커밋 커스텀 액션을 구현할 때, 나는 하나의 기능 만 사용하고 사용하는 것을 선호합니다. msigetmode () 해야 할 일을 구별하기 위해 :

extern "C" UINT __stdcall LocalGroupCustomAction(MSIHANDLE hInstall)
{
    try {
        //Parse the properties from the "CustomActionData" property
        std::map<std::wstring,std::wstring> mapProps;
        {
            wchar_t szBuf[2048]={0};
            DWORD dwBufSize = _countof(szBuf); MsiGetProperty(hInstall,L"CustomActionData",szBuf,&dwBufSize);
            CCustomActionDataUtil::ParseCustomActionData(szBuf,mapProps);
        }

        //Find the "GroupName" and "Operation" property
        std::wstring sGroupName;
        bool bCreate = false;
        std::map<std::wstring,std::wstring>::const_iterator it;
        it = mapProps.find(L"GroupName");
        if( mapProps.end() != it ) sGroupName = it->second;
        it = mapProps.find(L"Operation");
        if( mapProps.end() != it )
            bCreate = wcscmp(it->second.c_str(),L"create") == 0 ? true : false ;

        //Since we know what opeartion to perform, and we know whether it is
        //running rollback, commit or deferred script by MsiGetMode, the
        //implementation is straight forward
        if( MsiGetMode(hInstall,MSIRUNMODE_SCHEDULED) ) {
            if( bCreate )
                CreateLocalGroup(sGroupName.c_str());
            else
                DeleteLocalGroup(sGroupName.c_str());
        }
        else if( MsiGetMode(hInstall,MSIRUNMODE_ROLLBACK) ) {
            if( bCreate )
                DeleteLocalGroup(sGroupName.c_str());
            else
                CreateLocalGroup(sGroupName.c_str());
        }
    }
    catch( CMsiException & ) {
        return ERROR_INSTALL_FAILURE;
    }
    return ERROR_SUCCESS;
}

위의 기술을 사용하면 일반적인 사용자 정의 액션 세트의 경우 사용자 정의 액션 테이블을 5 개의 항목으로 줄일 수 있습니다.

<CustomAction Id="CA.ScheduleLocalGroupCreation"
              Return="check"
              Execute="immediate"
              BinaryKey="CustomActionDLL"
              DllEntry="ScheduleLocalGroupCreation"
              HideTarget="yes"/>
<CustomAction Id="CA.ScheduleLocalGroupDeletion"
              Return="check"
              Execute="immediate"
              BinaryKey="CustomActionDLL"
              DllEntry="ScheduleLocalGroupDeletion"
              HideTarget="yes"/>
<CustomAction Id="CA.LocalGroupCustomAction.deferred"
              Return="check"
              Execute="deferred"
              BinaryKey="CustomActionDLL"
              DllEntry="LocalGroupCustomAction"
              HideTarget="yes"/>
<CustomAction Id="CA.LocalGroupCustomAction.commit"
              Return="check"
              Execute="commit"
              BinaryKey="CustomActionDLL"
              DllEntry="LocalGroupCustomAction"
              HideTarget="yes"/>
<CustomAction Id="CA.LocalGroupCustomAction.rollback"
              Return="check"
              Execute="rollback"
              BinaryKey="CustomActionDLL"
              DllEntry="LocalGroupCustomAction"
              HideTarget="yes"/>

설치 테이블은 두 개의 항목으로 만 있습니다.

<InstallExecuteSequence>
    <Custom Action="CA.ScheduleLocalGroupCreation" 
            After="InstallFiles">
        Not Installed
    </Custom>
    <Custom Action="CA.ScheduleLocalGroupDeletion" 
            After="InstallFiles">
        Installed
    </Custom>
</InstallExecuteSequence>

또한 약간의 노력으로 대부분의 코드는 재사용되도록 작성 될 수 있습니다 (예 : 사용자 정의 테이블 읽기, 속성 가져 오기, 필요한 속성을 형식화하고 CustomActionData 속성으로 설정) 및 현재 사용자 정의 액션 테이블의 항목은 다음과 같습니다. 애플리케이션이 아닌 (응용 프로그램 별 데이터는 사용자 정의 테이블에 작성됨) 사용자 정의 액션 테이블을 자체 파일에 넣고 각 WIX 프로젝트에 포함시킬 수 있습니다.

사용자 정의 조치 DLL 파일의 경우 응용 프로그램 데이터가 사용자 정의 테이블에서 읽히기 때문에 응용 프로그램 특정 세부 정보를 DLL 구현에서 보관할 수 있으므로 사용자 정의 작업 테이블이 라이브러리가되어 재사용이 쉬울 수 있습니다.

이것은 현재 Wix 사용자 정의 작업을 작성하는 방법입니다. 누군가가 더 개선하는 방법을 알고 있다면 매우 감사하겠습니다. :)

(내 블로그 게시물에서 전체 소스 코드를 찾을 수도 있습니다. WIX 사용자 정의 작업 구현 파트 2 : 사용자 정의 테이블 사용.).

다른 팁

WIX 사용자 정의 작업은 따라야 할 훌륭한 모델입니다. 이 경우에만 선언합니다 CustomAction, 즉각적인 행동, 연기 된 행동 및 롤백 액션. 당신은 함께 일정을 잡습니다 Custom, 즉각적인 조치, 즉각적인 조치가 기본 DLL에서 코드로 구현되는 즉각적인 조치.

그런 다음 즉시 행동에서 암호, 당신은 전화합니다 MsiDoAction 롤백과 연기 된 행동을 예약하려면 : 연기 될 때, 그들은 당신이 전화 할 때 대본에 기록됩니다. MsiDoAction 즉시 실행되기보다는. 전화해야합니다 MsiSetProperty 또한 사용자 정의 작업 데이터를 설정합니다.

Wix 소스 코드를 다운로드하고 방법을 연구하십시오 IISExtension 예를 들어 작동합니다. WIX 작업은 일반적으로 사용자 정의 테이블을 구문 분석하고 해당 테이블을 기반으로 지연된 조치의 속성에 대한 데이터를 생성합니다.

롤백을 지원 해야하는 복잡한 사용자 정의 작업이있는 경우 WIX 확장자 작성을 고려할 수 있습니다. 확장자는 일반적으로 저작 지원 (예 : MSI 테이블 항목에 매핑되는 새로운 XML 태그)과 사용자 정의 작업의 자동 일정을 제공합니다.

CAS가 특정 수준의 복잡성에 도달하면 확장이 제공하는 저자의 용이성이 그만한 가치가있을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top