本文整理汇总了C#中Microsoft.Tools.WindowsInstallerXml.Table.CreateRow方法的典型用法代码示例。如果您正苦于以下问题:C# Table.CreateRow方法的具体用法?C# Table.CreateRow怎么用?C# Table.CreateRow使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.Tools.WindowsInstallerXml.Table
的用法示例。
在下文中一共展示了Table.CreateRow方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: UpdateTransformSummaryInformationTable
private void UpdateTransformSummaryInformationTable(Table summaryInfoTable, TransformFlags validationFlags)
{
// calculate the minimum version of MSI required to process the transform
int targetMin;
int updatedMin;
int minimumVersion = 100;
if (Int32.TryParse(this.transformSummaryInfo.TargetMinimumVersion, out targetMin) && Int32.TryParse(this.transformSummaryInfo.UpdatedMinimumVersion, out updatedMin))
{
minimumVersion = Math.Max(targetMin, updatedMin);
}
Hashtable summaryRows = new Hashtable(summaryInfoTable.Rows.Count);
foreach (Row row in summaryInfoTable.Rows)
{
summaryRows[row[0]] = row;
if ((int)SummaryInformation.Transform.CodePage == (int)row[0])
{
row.Fields[1].Data = this.transformSummaryInfo.UpdatedSummaryInfoCodepage;
row.Fields[1].PreviousData = this.transformSummaryInfo.TargetSummaryInfoCodepage;
}
else if ((int)SummaryInformation.Transform.TargetPlatformAndLanguage == (int)row[0])
{
row[1] = this.transformSummaryInfo.TargetPlatformAndLanguage;
}
else if ((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage == (int)row[0])
{
row[1] = this.transformSummaryInfo.UpdatedPlatformAndLanguage;
}
else if ((int)SummaryInformation.Transform.ProductCodes == (int)row[0])
{
row[1] = String.Concat(this.transformSummaryInfo.TargetProductCode, this.transformSummaryInfo.TargetProductVersion, ';', this.transformSummaryInfo.UpdatedProductCode, this.transformSummaryInfo.UpdatedProductVersion, ';', this.transformSummaryInfo.TargetUpgradeCode);
}
else if ((int)SummaryInformation.Transform.InstallerRequirement == (int)row[0])
{
row[1] = minimumVersion.ToString(CultureInfo.InvariantCulture);
}
else if ((int)SummaryInformation.Transform.Security == (int)row[0])
{
row[1] = "4";
}
}
if (!summaryRows.Contains((int)SummaryInformation.Transform.TargetPlatformAndLanguage))
{
Row summaryRow = summaryInfoTable.CreateRow(null);
summaryRow[0] = (int)SummaryInformation.Transform.TargetPlatformAndLanguage;
summaryRow[1] = this.transformSummaryInfo.TargetPlatformAndLanguage;
}
if (!summaryRows.Contains((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage))
{
Row summaryRow = summaryInfoTable.CreateRow(null);
summaryRow[0] = (int)SummaryInformation.Transform.UpdatedPlatformAndLanguage;
summaryRow[1] = this.transformSummaryInfo.UpdatedPlatformAndLanguage;
}
if (!summaryRows.Contains((int)SummaryInformation.Transform.ValidationFlags))
{
Row summaryRow = summaryInfoTable.CreateRow(null);
summaryRow[0] = (int)SummaryInformation.Transform.ValidationFlags;
summaryRow[1] = ((int)validationFlags).ToString(CultureInfo.InvariantCulture);
}
if (!summaryRows.Contains((int)SummaryInformation.Transform.InstallerRequirement))
{
Row summaryRow = summaryInfoTable.CreateRow(null);
summaryRow[0] = (int)SummaryInformation.Transform.InstallerRequirement;
summaryRow[1] = minimumVersion.ToString(CultureInfo.InvariantCulture);
}
if (!summaryRows.Contains((int)SummaryInformation.Transform.Security))
{
Row summaryRow = summaryInfoTable.CreateRow(null);
summaryRow[0] = (int)SummaryInformation.Transform.Security;
summaryRow[1] = "4";
}
}
示例2: FinalizeSequenceTables
/// <summary>
/// Finalize the sequence tables.
/// </summary>
/// <param name="tables">The collection of all tables.</param>
/// <remarks>
/// Creates the sequence elements. Occurs during finalization because its
/// not known if sequences refer to custom actions or dialogs during decompilation.
/// </remarks>
private void FinalizeSequenceTables(TableCollection tables)
{
// finalize the normal sequence tables
if (OutputType.Product == this.outputType && !this.treatProductAsModule)
{
foreach (SequenceTable sequenceTable in Enum.GetValues(typeof(SequenceTable)))
{
// if suppressing UI elements, skip UI-related sequence tables
if (this.suppressUI && ("AdminUISequence" == sequenceTable.ToString() || "InstallUISequence" == sequenceTable.ToString()))
{
continue;
}
Table actionsTable = new Table(null, this.tableDefinitions["WixAction"]);
Table table = tables[sequenceTable.ToString()];
if (null != table)
{
ArrayList actionRows = new ArrayList();
bool needAbsoluteScheduling = this.suppressRelativeActionSequencing;
WixActionRowCollection nonSequencedActionRows = new WixActionRowCollection();
WixActionRowCollection suppressedRelativeActionRows = new WixActionRowCollection();
// create a sorted array of actions in this table
foreach (Row row in table.Rows)
{
WixActionRow actionRow = (WixActionRow)actionsTable.CreateRow(null);
actionRow.Action = Convert.ToString(row[0]);
if (null != row[1])
{
actionRow.Condition = Convert.ToString(row[1]);
}
actionRow.Sequence = Convert.ToInt32(row[2]);
actionRow.SequenceTable = sequenceTable;
actionRows.Add(actionRow);
}
actionRows.Sort();
for (int i = 0; i < actionRows.Count && !needAbsoluteScheduling; i++)
{
WixActionRow actionRow = (WixActionRow)actionRows[i];
WixActionRow standardActionRow = this.standardActions[actionRow.SequenceTable, actionRow.Action];
// create actions for custom actions, dialogs, AppSearch when its moved, and standard actions with non-standard conditions
if ("AppSearch" == actionRow.Action || null == standardActionRow || actionRow.Condition != standardActionRow.Condition)
{
WixActionRow previousActionRow = null;
WixActionRow nextActionRow = null;
// find the previous action row if there is one
if (0 <= i - 1)
{
previousActionRow = (WixActionRow)actionRows[i - 1];
}
// find the next action row if there is one
if (actionRows.Count > i + 1)
{
nextActionRow = (WixActionRow)actionRows[i + 1];
}
// the logic for setting the before or after attribute for an action:
// 1. If more than one action shares the same sequence number, everything must be absolutely sequenced.
// 2. If the next action is a standard action and is 1 sequence number higher, this action occurs before it.
// 3. If the previous action is a standard action and is 1 sequence number lower, this action occurs after it.
// 4. If this action is not standard and the previous action is 1 sequence number lower and does not occur before this action, this action occurs after it.
// 5. If this action is not standard and the previous action does not have the same sequence number and the next action is 1 sequence number higher, this action occurs before it.
// 6. If this action is AppSearch and has all standard information, ignore it.
// 7. If this action is standard and has a non-standard condition, create the action without any scheduling information.
// 8. Everything must be absolutely sequenced.
if ((null != previousActionRow && actionRow.Sequence == previousActionRow.Sequence) || (null != nextActionRow && actionRow.Sequence == nextActionRow.Sequence))
{
needAbsoluteScheduling = true;
}
else if (null != nextActionRow && null != this.standardActions[sequenceTable, nextActionRow.Action] && actionRow.Sequence + 1 == nextActionRow.Sequence)
{
actionRow.Before = nextActionRow.Action;
}
else if (null != previousActionRow && null != this.standardActions[sequenceTable, previousActionRow.Action] && actionRow.Sequence - 1 == previousActionRow.Sequence)
{
actionRow.After = previousActionRow.Action;
}
else if (null == standardActionRow && null != previousActionRow && actionRow.Sequence - 1 == previousActionRow.Sequence && previousActionRow.Before != actionRow.Action)
{
actionRow.After = previousActionRow.Action;
}
else if (null == standardActionRow && null != previousActionRow && actionRow.Sequence != previousActionRow.Sequence && null != nextActionRow && actionRow.Sequence + 1 == nextActionRow.Sequence)
//.........这里部分代码省略.........
示例3: SetMsiAssemblyName
private void SetMsiAssemblyName(Output output, Table assemblyNameTable, FileRow fileRow, string name, string value, IDictionary<string, string> infoCache, string modularizationGuid)
{
// check for null value (this can occur when grabbing the file version from an assembly without one)
if (null == value || 0 == value.Length)
{
this.core.OnMessage(WixWarnings.NullMsiAssemblyNameValue(fileRow.SourceLineNumbers, fileRow.Component, name));
}
else
{
Row assemblyNameRow = null;
// override directly authored value
foreach (Row row in assemblyNameTable.Rows)
{
if ((string)row[0] == fileRow.Component && (string)row[1] == name)
{
assemblyNameRow = row;
break;
}
}
// if the assembly will be GAC'd and the name in the file table doesn't match the name in the MsiAssemblyName table, error because the install will fail.
if ("name" == name && FileAssemblyType.DotNetAssembly == fileRow.AssemblyType && String.IsNullOrEmpty(fileRow.AssemblyApplication) && !String.Equals(Path.GetFileNameWithoutExtension(fileRow.LongFileName), value, StringComparison.OrdinalIgnoreCase))
{
this.core.OnMessage(WixErrors.GACAssemblyIdentityWarning(fileRow.SourceLineNumbers, Path.GetFileNameWithoutExtension(fileRow.LongFileName), value));
}
if (null == assemblyNameRow)
{
assemblyNameRow = assemblyNameTable.CreateRow(fileRow.SourceLineNumbers);
assemblyNameRow[0] = fileRow.Component;
assemblyNameRow[1] = name;
assemblyNameRow[2] = value;
// put the MsiAssemblyName row in the same section as the related File row
assemblyNameRow.SectionId = fileRow.SectionId;
if (null == fileRow.AssemblyNameRows)
{
fileRow.AssemblyNameRows = new RowCollection();
}
fileRow.AssemblyNameRows.Add(assemblyNameRow);
}
else
{
assemblyNameRow[2] = value;
}
if (infoCache != null)
{
string key = String.Format(CultureInfo.InvariantCulture, "assembly{0}.{1}", name, Demodularize(output, modularizationGuid, fileRow.File)).ToLower(CultureInfo.InvariantCulture);
infoCache[key] = (string)assemblyNameRow[2];
}
}
}
示例4: Parse
/// <summary>
/// Creates a Row from the XmlReader.
/// </summary>
/// <param name="reader">Reader to get data from.</param>
/// <param name="table">Table for this row.</param>
/// <returns>New row object.</returns>
internal static Row Parse(XmlReader reader, Table table)
{
Debug.Assert("row" == reader.LocalName);
bool empty = reader.IsEmptyElement;
RowOperation operation = RowOperation.None;
string sectionId = null;
SourceLineNumberCollection sourceLineNumbers = null;
while (reader.MoveToNextAttribute())
{
switch (reader.LocalName)
{
case "op":
switch (reader.Value)
{
case "add":
operation = RowOperation.Add;
break;
case "delete":
operation = RowOperation.Delete;
break;
case "modify":
operation = RowOperation.Modify;
break;
default:
throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name, reader.Value, "Add", "Delete", "Modify"));
}
break;
case "sectionId":
sectionId = reader.Value;
break;
case "sourceLineNumber":
sourceLineNumbers = new SourceLineNumberCollection(reader.Value);
break;
default:
if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
{
throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name));
}
break;
}
}
Row row = table.CreateRow(sourceLineNumbers);
row.Operation = operation;
row.SectionId = sectionId;
// loop through all the fields in a row
if (!empty)
{
bool done = false;
int field = 0;
// loop through all the fields in a row
while (!done && reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
switch (reader.LocalName)
{
case "field":
if (row.Fields.Length <= field)
{
if (!reader.IsEmptyElement)
{
throw new WixException(WixErrors.UnexpectedColumnCount(SourceLineNumberCollection.FromUri(reader.BaseURI), table.Name));
}
}
else
{
row.fields[field].Parse(reader);
}
++field;
break;
default:
throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name));
}
break;
case XmlNodeType.EndElement:
done = true;
break;
}
}
if (!done)
{
throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "row"));
}
}
return row;
}
示例5: AddMediaRow
/// <summary>
/// Adds a row to the media table with cab name template filled in.
/// </summary>
/// <param name="mediaTable"></param>
/// <param name="cabIndex"></param>
/// <returns></returns>
private MediaRow AddMediaRow(Table mediaTable, int cabIndex)
{
MediaRow currentMediaRow = (MediaRow)mediaTable.CreateRow(null);
currentMediaRow.DiskId = cabIndex;
mediaRows.Add(currentMediaRow);
currentMediaRow.Cabinet = String.Format(this.cabinetNameTemplate, cabIndex);
cabinets.Add(currentMediaRow, new FileRowCollection());
return currentMediaRow;
}
示例6: AssignFiles
/// <summary>
/// Assigns the file rows to media rows based on Media or MediaTemplate authoring. Updates uncompressed files collection.
/// </summary>
/// <param name="fileRows">FileRowCollection</param>
public void AssignFiles(FileRowCollection fileRows)
{
bool autoAssign = false;
MediaRow mergeModuleMediaRow = null;
Table mediaTable = this.output.Tables["Media"];
Table mediaTemplateTable = this.output.Tables["WixMediaTemplate"];
// If both tables are authored, it is an error.
if ((mediaTemplateTable != null && mediaTemplateTable.Rows.Count > 0) &&( mediaTable != null && mediaTable.Rows.Count > 1))
{
throw new WixException(WixErrors.MediaTableCollision(null));
}
autoAssign = mediaTemplateTable != null && OutputType.Module != this.output.Type ? true : false;
// When building merge module, all the files go to "#MergeModule.CABinet"
if (OutputType.Module == this.output.Type)
{
Table mergeModuleMediaTable = new Table(null, this.core.TableDefinitions["Media"]);
mergeModuleMediaRow = (MediaRow)mergeModuleMediaTable.CreateRow(null);
mergeModuleMediaRow.Cabinet = "#MergeModule.CABinet";
this.cabinets.Add(mergeModuleMediaRow, new FileRowCollection());
}
if (autoAssign)
{
this.AutoAssignFiles(mediaTable, fileRows);
}
else
{
this.ManuallyAssignFiles(mediaTable, mergeModuleMediaRow, fileRows);
}
}
示例7: AutoAssignFiles
//.........这里部分代码省略.........
// When building a product, if the current file is not to be compressed or if
// the package set not to be compressed, don't cab it.
if (OutputType.Product == output.Type &&
(YesNoType.No == fileRow.Compressed ||
(YesNoType.NotSet == fileRow.Compressed && !this.filesCompressed)))
{
uncompressedFileRows.Add(fileRow);
continue;
}
FileInfo fileInfo = null;
// Get the file size
try
{
fileInfo = new FileInfo(fileRow.Source);
}
catch (ArgumentException)
{
this.core.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, fileRow.Source));
}
catch (PathTooLongException)
{
this.core.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, fileRow.Source));
}
catch (NotSupportedException)
{
this.core.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, fileRow.Source));
}
if (fileInfo.Exists)
{
if (fileInfo.Length > Int32.MaxValue)
{
throw new WixException(WixErrors.FileTooLarge(fileRow.SourceLineNumbers, fileRow.Source));
}
fileRow.FileSize = Convert.ToInt32(fileInfo.Length, CultureInfo.InvariantCulture);
}
if (currentCabIndex == MaxCabIndex)
{
// Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore.
FileRowCollection cabinetFileRow = (FileRowCollection)this.cabinets[currentMediaRow];
fileRow.DiskId = currentCabIndex;
cabinetFileRow.Add(fileRow);
continue;
}
// Update current cab size.
currentPreCabSize += (ulong)fileRow.FileSize;
if (currentPreCabSize > maxPreCabSizeInBytes)
{
// Overflow due to current file
if (currentPreCabSize == (ulong)fileRow.FileSize)
{
// Only one file in this cab.
currentMediaRow = AddMediaRow(mediaTable, ++currentCabIndex);
FileRowCollection cabinetFileRow = (FileRowCollection)cabinets[currentMediaRow];
fileRow.DiskId = currentCabIndex;
cabinetFileRow.Add(fileRow);
currentPreCabSize = 0;
}
else
{
currentMediaRow = this.AddMediaRow(mediaTable, ++currentCabIndex);
// Finish current media row and create new one.
FileRowCollection cabinetFileRow = (FileRowCollection)this.cabinets[currentMediaRow];
fileRow.DiskId = currentCabIndex;
cabinetFileRow.Add(fileRow);
currentPreCabSize = (ulong)fileRow.FileSize;
}
}
else
{
// File fits in the current cab.
if (currentMediaRow == null)
{
// Create new cab and MediaRow
currentMediaRow = AddMediaRow(mediaTable, ++currentCabIndex);
}
// Associate current file with current cab.
FileRowCollection cabinetFileRow = (FileRowCollection)this.cabinets[currentMediaRow];
fileRow.DiskId = currentCabIndex;
cabinetFileRow.Add(fileRow);
}
}
// If there are uncompressed files and no MediaRow, create a default one.
if (uncompressedFileRows.Count > 0 && mediaTable.Rows.Count == 0 )
{
MediaRow defaultMediaRow = (MediaRow)mediaTable.CreateRow(null);
defaultMediaRow.DiskId = 1;
mediaRows.Add(defaultMediaRow);
}
}
示例8: AddMediaRow
/// <summary>
/// Adds a row to the media table with cab name template filled in.
/// </summary>
/// <param name="mediaTable"></param>
/// <param name="cabIndex"></param>
/// <returns></returns>
private MediaRow AddMediaRow(Table mediaTable, int cabIndex, string compressionLevel)
{
MediaRow currentMediaRow = (MediaRow)mediaTable.CreateRow(null);
currentMediaRow.DiskId = cabIndex;
currentMediaRow.Cabinet = String.Format(this.cabinetNameTemplate, cabIndex);
this.mediaRows.Add(currentMediaRow);
this.cabinets.Add(currentMediaRow, new FileRowCollection());
Table wixMediaTable = this.output.EnsureTable(this.core.TableDefinitions["WixMedia"]);
Row row = wixMediaTable.CreateRow(null);
row[0] = cabIndex;
row[1] = compressionLevel;
return currentMediaRow;
}
示例9: UnbindDatabase
/// <summary>
/// Unbind an MSI database file.
/// </summary>
/// <param name="databaseFile">The database file.</param>
/// <param name="database">The opened database.</param>
/// <param name="outputType">The type of output to create.</param>
/// <param name="exportBasePath">The path where files should be exported.</param>
/// <param name="skipSummaryInfo">Option to skip unbinding the _SummaryInformation table.</param>
/// <returns>The output representing the database.</returns>
private Output UnbindDatabase(string databaseFile, Database database, OutputType outputType, string exportBasePath, bool skipSummaryInfo)
{
string modularizationGuid = null;
Output output = new Output(SourceLineNumberCollection.FromFileName(databaseFile));
View validationView = null;
// set the output type
output.Type = outputType;
// get the codepage
database.Export("_ForceCodepage", this.TempFilesLocation, "_ForceCodepage.idt");
using (StreamReader sr = File.OpenText(Path.Combine(this.TempFilesLocation, "_ForceCodepage.idt")))
{
string line;
while (null != (line = sr.ReadLine()))
{
string[] data = line.Split('\t');
if (2 == data.Length)
{
output.Codepage = Convert.ToInt32(data[0], CultureInfo.InvariantCulture);
}
}
}
// get the summary information table if it exists; it won't if unbinding a transform
if (!skipSummaryInfo)
{
using (SummaryInformation summaryInformation = new SummaryInformation(database))
{
Table table = new Table(null, this.tableDefinitions["_SummaryInformation"]);
for (int i = 1; 19 >= i; i++)
{
string value = summaryInformation.GetProperty(i);
if (0 < value.Length)
{
Row row = table.CreateRow(output.SourceLineNumbers);
row[0] = i;
row[1] = value;
}
}
output.Tables.Add(table);
}
}
try
{
// open a view on the validation table if it exists
if (database.TableExists("_Validation"))
{
validationView = database.OpenView("SELECT * FROM `_Validation` WHERE `Table` = ? AND `Column` = ?");
}
// get the normal tables
using (View tablesView = database.OpenExecuteView("SELECT * FROM _Tables"))
{
while (true)
{
using (Record tableRecord = tablesView.Fetch())
{
if (null == tableRecord)
{
break;
}
string tableName = tableRecord.GetString(1);
using (View tableView = database.OpenExecuteView(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM `{0}`", tableName)))
{
TableDefinition tableDefinition = new TableDefinition(tableName, false, false);
Hashtable tablePrimaryKeys = new Hashtable();
using (Record columnNameRecord = tableView.GetColumnInfo(MsiInterop.MSICOLINFONAMES),
columnTypeRecord = tableView.GetColumnInfo(MsiInterop.MSICOLINFOTYPES))
{
int columnCount = columnNameRecord.GetFieldCount();
// index the primary keys
using (Record primaryKeysRecord = database.PrimaryKeys(tableName))
{
int primaryKeysFieldCount = primaryKeysRecord.GetFieldCount();
for (int i = 1; i <= primaryKeysFieldCount; i++)
{
tablePrimaryKeys[primaryKeysRecord.GetString(i)] = null;
}
}
//.........这里部分代码省略.........
示例10: CreateRow
/// <summary>
/// Create a deleted or modified row.
/// </summary>
/// <param name="table">The table containing the row.</param>
/// <param name="primaryKeys">The primary keys of the row.</param>
/// <param name="setRequiredFields">Option to set all required fields with placeholder values.</param>
/// <returns>The new row.</returns>
private Row CreateRow(Table table, string primaryKeys, bool setRequiredFields)
{
Row row = table.CreateRow(null);
string[] primaryKeyParts = primaryKeys.Split('\t');
int primaryKeyPartIndex = 0;
for (int i = 0; i < table.Definition.Columns.Count; i++)
{
ColumnDefinition columnDefinition = table.Definition.Columns[i];
if (columnDefinition.IsPrimaryKey)
{
if (ColumnType.Number == columnDefinition.Type && !columnDefinition.IsLocalizable)
{
row[i] = Convert.ToInt32(primaryKeyParts[primaryKeyPartIndex++], CultureInfo.InvariantCulture);
}
else
{
row[i] = primaryKeyParts[primaryKeyPartIndex++];
}
}
else if (setRequiredFields)
{
if (ColumnType.Number == columnDefinition.Type && !columnDefinition.IsLocalizable)
{
row[i] = 1;
}
else if (ColumnType.Object == columnDefinition.Type)
{
if (null == this.emptyFile)
{
this.emptyFile = this.tempFiles.AddExtension("empty");
using (FileStream fileStream = File.Create(this.emptyFile))
{
}
}
row[i] = this.emptyFile;
}
else
{
row[i] = "1";
}
}
}
return row;
}
示例11: InscribeDatabase
/// <summary>
/// Updates database with signatures from external cabinets.
/// </summary>
/// <param name="databaseFile">Path to MSI database.</param>
/// <param name="outputFile">Ouput for updated MSI database.</param>
/// <param name="tidy">Clean up files.</param>
/// <returns>True if database is updated.</returns>
public bool InscribeDatabase(string databaseFile, string outputFile, bool tidy)
{
// Keeps track of whether we've encountered at least one signed cab or not - we'll throw a warning if no signed cabs were encountered
bool foundUnsignedExternals = false;
bool shouldCommit = false;
FileAttributes attributes = File.GetAttributes(databaseFile);
if (FileAttributes.ReadOnly == (attributes & FileAttributes.ReadOnly))
{
this.OnMessage(WixErrors.ReadOnlyOutputFile(databaseFile));
return shouldCommit;
}
using (Database database = new Database(databaseFile, OpenDatabase.Transact))
{
// Just use the English codepage, because the tables we're importing only have binary streams / MSI identifiers / other non-localizable content
int codepage = 1252;
// list of certificates for this database (hash/identifier)
Dictionary<string, string> certificates = new Dictionary<string, string>();
// Reset the in-memory tables for this new database
Table digitalSignatureTable = new Table(null, this.tableDefinitions["MsiDigitalSignature"]);
Table digitalCertificateTable = new Table(null, this.tableDefinitions["MsiDigitalCertificate"]);
// If any digital signature records exist that are not of the media type, preserve them
if (database.TableExists("MsiDigitalSignature"))
{
using (View digitalSignatureView = database.OpenExecuteView("SELECT `Table`, `SignObject`, `DigitalCertificate_`, `Hash` FROM `MsiDigitalSignature` WHERE `Table` <> 'Media'"))
{
while (true)
{
using (Record digitalSignatureRecord = digitalSignatureView.Fetch())
{
if (null == digitalSignatureRecord)
{
break;
}
Row digitalSignatureRow = null;
digitalSignatureRow = digitalSignatureTable.CreateRow(null);
string table = digitalSignatureRecord.GetString(0);
string signObject = digitalSignatureRecord.GetString(1);
digitalSignatureRow[0] = table;
digitalSignatureRow[1] = signObject;
digitalSignatureRow[2] = digitalSignatureRecord.GetString(2);
if (false == digitalSignatureRecord.IsNull(3))
{
// Export to a file, because the MSI API's require us to provide a file path on disk
string hashPath = Path.Combine(this.TempFilesLocation, "MsiDigitalSignature");
string hashFileName = string.Concat(table,".", signObject, ".bin");
Directory.CreateDirectory(hashPath);
hashPath = Path.Combine(hashPath, hashFileName);
using (FileStream fs = File.Create(hashPath))
{
int bytesRead;
byte[] buffer = new byte[1024 * 4];
while (0 != (bytesRead = digitalSignatureRecord.GetStream(3, buffer, buffer.Length)))
{
fs.Write(buffer, 0, bytesRead);
}
}
digitalSignatureRow[3] = hashFileName;
}
}
}
}
}
// If any digital certificates exist, extract and preserve them
if (database.TableExists("MsiDigitalCertificate"))
{
using (View digitalCertificateView = database.OpenExecuteView("SELECT * FROM `MsiDigitalCertificate`"))
{
while (true)
{
using (Record digitalCertificateRecord = digitalCertificateView.Fetch())
{
if (null == digitalCertificateRecord)
{
break;
}
string certificateId = digitalCertificateRecord.GetString(1); // get the identifier of the certificate
// Export to a file, because the MSI API's require us to provide a file path on disk
//.........这里部分代码省略.........