WIX редактирует двоичный файл в пользовательском действии

Я пытаюсь сделать следующее:

  1. во время установки откройте и отредактируйте файл sql с помощью настраиваемого действия
  2. сохранить отредактированные изменения и выполнить их во время установки.

В моем 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();

когда я пытаюсь обновить (не уверен, что делаю это правильно), это не удается.


person ShaneKm    schedule 25.01.2013    source источник
comment
Вы нашли какое-либо решение для обновления содержимого двоичного файла sql? КАК я также столкнулся с той же проблемой. Может читать содержимое, но не может его обновить.   -  person supriya khamesra    schedule 16.05.2014
comment
Мне пришлось удалить одинарные кавычки из имен столбцов и таблиц (и оставить строковое значение в кавычках), чтобы это работало для чтения записи двоичной таблицы. Возможно, VS использует другой символ одинарной кавычки.   -  person StingyJack    schedule 14.09.2015
comment
Я искал способ получить фактические данные, содержащиеся в двоичном элементе... Ваш вопрос вообще не относился ко мне, но серьезно, вы непреднамеренно сэкономили мне массу времени.   -  person Brandon    schedule 30.10.2015


Ответы (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;
}
person Natalie Carr    schedule 25.01.2013
comment
У меня эта часть работает. Единственная проблема заключается в том, что он терпит неудачу при обратной записи. - person ShaneKm; 25.01.2013
comment
Может быть, есть вариант записать во временный файл на целевой машине и использовать его оттуда, а затем удалить? У меня есть код для этого, если вам это нужно .. :) - person Natalie Carr; 25.01.2013
comment
не вариант для меня. Я не могу сделать файл sql доступным для просмотра другими (даже за такой короткий промежуток времени) во время установки. Он должен быть частью файла msi. - person ShaneKm; 25.01.2013
comment
WcaAddTempRecord может работать для вас из центра сертификации Wix — вы пробовали это? - person Natalie Carr; 25.01.2013