我正在尝试在摘要信息Stram中设置Template属性,但无论我做什么,它都会失败。我可以从句柄中读取属性但无法将其写回。
我想生成MSI的多语言副本,这些副本是用英语构建的(烛光和轻音)。我能够替换所有表格中所有相应的翻译数据;我唯一无法改变的是上面的模板属性。
我已尝试过所有可用于传递新String值的方法,但它总是说无效参数。 这是我用来做同样的功能(C#):
public Boolean ChangeTemplateSummaryProperty(String strLangID) {
IntPtr hSIHandle;
if (MsiError.Success == MsiInterop.MsiGetSummaryInformation(IntPtr.Zero, m_strMSIPath, 1, out hSIHandle))
{
VariantType vtType = VariantType.LPStr;
int iVal = 0;
FILETIME oFileTime;
oFileTime.HighDateTime = 0;
oFileTime.LowDateTime = 0;
int iValSz = 0;
MsiError err = MsiInterop.MsiSummaryInfoGetProperty(hSIHandle, (uint)(SummaryInformationStreamProperty.Template),
out vtType, out iVal, out oFileTime, String.Empty, ref iValSz);
String strValue = new String('l', ++iValSz);
if (err == MsiError.MoreData)
{
err = MsiInterop.MsiSummaryInfoGetProperty(hSIHandle, (uint)(SummaryInformationStreamProperty.Template),
out vtType, out iVal, out oFileTime, strValue, ref iValSz);
}
else
{
Logger.LogError("Failed to get SummaryInformationStreamProperty.Template... err = " + err);
}
//I get the correct value here. as ";1033\0"
Logger.LogInfo("SummaryInformationStreamProperty.Template: " + strValue);
char[] arrNV = new char[strLangID.Length+2];
arrNV[0] = ';';
for (int i = 1; i < strLangID.Length + 1; i++) {
arrNV[i] = strLangID[i-1];
}
arrNV[strLangID.Length+1] = '\0';
String strNewVal = new String(arrNV);
//tried this, but fails.
//string strNV = ";";
//string strNV2 = strNV.Insert(1, strLangID);
//strNV2 = strNV2.Insert(strLangID.Length + 1, "\0");
err = MsiInterop.MsiSummaryInfoSetProperty(hSIHandle, (uint)(SummaryInformationStreamProperty.Template),
vtType, iVal, oFileTime, strNewVal);
if (err != MsiError.NoError)
{
Logger.LogError("Failed to set SummaryInformationStreamProperty.Template... err = " + err);
MsiInterop.MsiSummaryInfoPersist(hSIHandle);
MsiInterop.MsiCloseHandle(hSIHandle);
return false;
}
MsiInterop.MsiSummaryInfoPersist(hSIHandle);
MsiInterop.MsiCloseHandle(hSIHandle);
}
else
{
Logger.LogError("Failed to MsiGetSummaryInformation...");
return false;
}
return true;
}
答案 0 :(得分:1)
摆脱您正在使用的MsiInterop,并使用WiX DTF中的互操作。 Microsoft.Deploymnet.WindowsInstaller命名空间有一个SummaryInformation类,它公开读/写字符串模板属性。更好的对象模型和互操作方式,而不必担心当前互操作使您处理的所有P / Invoke细节。
我现在在家,所以这里是一个代码片段:
using Microsoft.Deployment.WindowsInstaller;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using( var database = new Database(@"C:\orca.msi", DatabaseOpenMode.Direct ))
{
database.SummaryInfo.Template = "Intel;666";
}
}
}
}
注意使用using()子句。 Database类实现了IDisposable接口,并自动处理(双关语)清理所有那些讨厌的非托管句柄。
答案 1 :(得分:0)
Database msidb = objInstaller.OpenDatabase(MSIFileNameWithPath,MsiOpenDatabaseMode.msiOpenDatabaseModeTransact);
SummaryInfo info = msidb.get_SummaryInformation(1);
info.set_Property(2, (object)("sample title"));
info.Persist();
msidb.Commit();
回答这个问题的最佳参考是
http://blogs.msdn.com/b/mwade/archive/2007/08/07/sail-away-with-me-to-another-world.aspx