WIX在自定义操作中编辑二进制文件

时间:2013-01-25 09:22:47

标签: wix wix3.5 wix3.6 wix-extension wixlib

我正在尝试执行以下操作:

  1. 在安装过程中打开并通过自定义操作编辑sql文件
  2. 保存已编辑的更改并在安装期间执行。
  3. 在我的product.wxs中,我有以下内容:

    <Binary Id="SqlScriptSQLAuthentication"  SourceFile="$(sys.SOURCEFILEDIR)\MyDb.sql" />
    
            <Component Id='SqlComponent.SQLAuthentication' Guid='665D641C-3570-4b96-9CA5-2B4C12594A35' KeyPath='yes'>
                <Condition><![CDATA[USEINTEGRATEDSECURITY<>1]]></Condition>
                <sql:SqlDatabase Id='SqlDatabase.SQLAuthentication' Database='[DATABASE_NAME]' User='SQLUser' Server='[DATABASE_SERVER]' CreateOnInstall='yes' DropOnUninstall='yes' ContinueOnError='no' />
                <sql:SqlScript Id='SqlScriptSQLAuthentication' BinaryKey='SqlScriptSQLAuthentication' SqlDb='SqlDatabase.SQLAuthentication' ExecuteOnInstall='yes' />
            </Component>
    

    在设置过程中,我想编辑“MyDb.sql”,将更改写入并保存回来,以便wix可以在安装过程中运行它。

    什么是最好的方法? 感谢

    编辑:

    MyDb.sql文件:

    CREATE TABLE Test12345 (Value1 CHAR(50), Value2 INTEGER)
    

    在我的自定义操作中,我有以下内容:

            View v = session.Database.OpenView("SELECT `Data` FROM `Binary` WHERE `Name` = '{0}'", binaryKeyName);
    
            v.Execute();
    
            var IsReadOnly = session.Database.IsReadOnly;
    
            Record r = v.Fetch();
    
            StreamReader reader = new StreamReader(r.GetStream("Data"));
            string text = reader.ReadToEnd();
            text = text.Replace(@"Test12345", "TTTest");
    
            byte[] byteArray = Encoding.ASCII.GetBytes(text);
            MemoryStream stream = new MemoryStream(byteArray);
    
            r.SetStream("Data", stream);
    

    //到目前为止它可以工作,我从.sql文件中读取我的sql文本

        session.Database.ExecuteStringQuery("UPDATE `Binary` SET `Data` = '{0}' WHERE `Name` = '{1}')", text, binaryKeyName);
    
        v.Close();
        session.Database.Commit();
    

    当我尝试更新时(不确定我是否正确)它失败了。

1 个答案:

答案 0 :(得分:1)

您可以使用此自定义操作来提取二进制数据。然后,您必须进行更改并重新保存。不确定如何将它重新保存回二进制,因为我之前没有这样做 - 我已经用它将临时数据传输到许可协议中。这应该会给你一个良好的开端。

HRESULT ExtractBinary(__in LPCWSTR wzBinaryId,
                      __out BYTE** pbData,
                      __out DWORD* pcbData)
{
    HRESULT hr = S_OK;
    LPWSTR pwzSql = NULL;
    PMSIHANDLE hView;
    PMSIHANDLE hRec;

    // make sure we're not horked from the get-go
    hr = WcaTableExists(L"Binary");
    if (S_OK != hr)
    {
        if (SUCCEEDED(hr))
        {
            hr = E_UNEXPECTED;
        }
        ExitOnFailure(hr, "There is no Binary table.");
    }

    ExitOnNull(wzBinaryId, hr, E_INVALIDARG, "Binary ID cannot be null");
    ExitOnNull(*wzBinaryId, hr, E_INVALIDARG, "Binary ID cannot be empty string");

    hr = StrAllocFormatted(&pwzSql, L"SELECT `Data` FROM `Binary` WHERE `Name`=\'%s\'", wzBinaryId);
    ExitOnFailure(hr, "Failed to allocate Binary table query.");

    hr = WcaOpenExecuteView(pwzSql, &hView);
    ExitOnFailure(hr, "Failed to open view on Binary table");

    hr = WcaFetchSingleRecord(hView, &hRec);
    ExitOnFailure(hr, "Failed to retrieve request from Binary table");

    hr = WcaGetRecordStream(hRec, 1, pbData, pcbData);
    ExitOnFailure(hr, "Failed to read Binary.Data.");

    LExit:
    ReleaseStr(pwzSql);

    return hr;
}