问题描述
我正面临以下问题场景:
I am facing the following problem scenario:
- 以常规方式构建MSI,例如:MyTest.msi
- 重命名它,保留msi扩展名.例如:MyTest_V1.0.0.msi
- 测试一下,它可以工作.安装成功.
- 再次重复过程.这次重命名为ex:MyTest_V2.0.0.msi
- 进行测试,并且文件位于本地磁盘上时,失败并显示网络错误".
"尝试从MyTest_V1.0.0.msi文件读取时发生网络错误"
是什么,难道我们不能简单地重命名MSI文件吗?有什么问题可以防止这种情况发生吗?现在我陷入了困境.请指导.
What gives, can't we simply rename an MSI file? Is there some issue that prevents this?Now i stuck in this. please guide.
最高的问候,穆罕默德·穆巴希尔(Muhammad Mubashir).
Highest Regards,Muhammad Mubashir.
推荐答案
我找到了解决方案.这就像WebSite安装程序安装指南. **
I found solution my self. This is just like tutorial for WebSite Installer Setup. **
步骤:对于WebSites设置,您必须先安装webDeployemnt安装程序,然后从VS中添加WebDeployemnt项目,并将此webProject ADD作为etup项目中的引用.示例:来自WebDeploy Project的预编译Web Putput.
Steps:For WebSites setup you have to install webDeployemnt setup and then from VS Add WebDeployemnt Project and this webProject ADD as referrence in etup project.example: Precomiled Web Putputs from WebDeploy Project.
黑白网站和Web应用程序.网站具有多个程序集,并且没有.sln文件.WebApp具有.sln文件,因此所有程序集都合并为一个.
Difference b/w WebSite and Web App.Websites have morethan one assemblies and not have .sln file.WebApp have .sln file so all assemblies merge in one.
1-设置设置属性:
- RemovePreviousVersion True.
- DetectNewerVersionInstalled为False.
2-在Setup Project的postbuild事件中使用vbScript或c#代码;
- 更改MSI的产品版本.
- 更改MSI的产品代码.新Guid 32个字符.
- 将MaxVersion设置为您的新版本.在MSI的升级"表中可用.
- 在所有情况下,确保UpgradeCode必须相同.意味着要当心不要更改它.
下面,我同时发布了VbScript PBE.vbs和C#代码.
below i post both VbScript PBE.vbs and C# code.
从这里帮助网络链接,我有一个想法可以解决我的问题: https://www.simple-talk.com/dotnet/visual-studio/updates-to-setup-projects/
Help webLinks from here i got an idea to overcome my problem:https://www.simple-talk.com/dotnet/visual-studio/updates-to-setup-projects/
PBE.vbs. cscript//nologo"$(ProjectDir)PBE.vbs""$(BuiltOuputPath)"
PBE.vbs calling from PostbuildEvent of MSIProject. cscript //nologo "$(ProjectDir)PBE.vbs" "$(BuiltOuputPath)"
Dim pInstaller
Set pInstaller = CreateObject("WindowsInstaller.Installer")
Dim pDatabase
Set pDatabase = pInstaller.OpenDatabase(WScript.Arguments(0), 2)
Dim pView1
Set pView1 = pDatabase.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'")
pView1.Execute
Dim pRecord1
Set pRecord1 = pView1.Fetch
If (Not pRecord1 Is Nothing) Then
pRecord1.StringData(1) = "1.0.5"
Else
MsgBox "Error during ProductVersion."
End If
pView1.Modify 4, pRecord1
pView1.Close
'MsgBox "Product Version is: " + pRecord1.StringData(1)
Dim pView3
Set pView3 = pDatabase.OpenView("SELECT VersionMax FROM Upgrade")
pView3.Execute
Dim pRecord3
Set pRecord3 = pView3.Fetch
If (Not pRecord3 Is Nothing) Then
pRecord3.StringData(1) = pRecord1.StringData(1)
Else
MsgBox "Error during VersionMax."
End If
pView3.Modify 4, pRecord3
pView3.Close
MsgBox "VersionMax is: " + pRecord3.StringData(1)
Dim pView2
Set pView2 = pDatabase.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")
pView2.Execute
Dim pRecord2
Set pRecord2 = pView2.Fetch
If (Not pRecord2 Is Nothing) Then
pRecord2.StringData(1) = CreateGUID()
Else
MsgBox "Error during ProductCode."
End If
pView2.Modify 4, pRecord2
pView2.Close
'MsgBox "Product Code is: " + pRecord2.StringData(1)
pDatabase.Commit
Function CreateGUID
Dim TypeLib
Set TypeLib = CreateObject("Scriptlet.TypeLib")
CreateGUID = Left(TypeLib.Guid, 38)
End Function
C#控制台应用程序代码以重命名msi文件.
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using WindowsInstaller;
using System.Diagnostics;
// cscript //nologo "$(ProjectDir)WiRunSql.vbs" "$(BuiltOuputPath)" "UPDATE `Property` SET `Property`.`Value`='4.0.0.1' WHERE `Property`='ProductVersion'"
// "SELECT `Property`.`ProductVersion` FROM `Property` WHERE `Property`.`Property` = 'ProductVersion'"
/*
* That's a .NET wrapper generated by tlbimp.exe, wrapping the ActiveX component c:\windows\system32\msi.dll.
* You can let the IDE make one for you with Project + Add Reference, COM tab,
* select "Microsoft Windows Installer Object Library".
*/
namespace RenameMSI
{
[System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.Guid("000C1090-0000-0000-C000-000000000046")]
class Installer { }
class Program
{
static void Main(string[] args)
{
#region New code.
string msiFilePath = string.Empty;
if (args.Length == 0)
{
Console.WriteLine("Enter MSI file complete path:");
//msiFilePath = Console.ReadLine();
msiFilePath = @"D:\TEST Projects\TestWebsites\MsiSetupForAsp.netApp\TestWebApplicationSetup\Debug\TestWebApplicationSetup.msi";
}
else
{
Console.WriteLine("Argument Received args[0]: " + args[0]);
msiFilePath = args[0];
}
////Debugger.Launch();
StringBuilder sb = new StringBuilder();
string[] words = msiFilePath.Split('\\');
foreach (string word in words)
{
sb.Append(word + '\\');
if (word.Contains("Debug") || word.Contains("Release"))
{
break;
}
else
{
}
}
Program p = new Program();
string VersionMax = p.GetMsiVersionProperty(msiFilePath, "ProductVersion");
string productName = p.GetMsiVersionProperty(msiFilePath, "ProductName");
p.SetMsiProperty(msiFilePath, "ProductVersion", "mub.sni");
p.SetMsiProperty(msiFilePath, "ProductName", "mub.sni");
//p.setMaxVersion(msiFilePath, );
//p.RenameMSI(msiFilePath);
#endregion
#region old code.
//String inputFile = @"C:\\Install1.msi";
//// Get the type of the Windows Installer object
//Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
//// Create the Windows Installer object
//Installer installer = (Installer)Activator.CreateInstance(installerType);
//WindowsInstaller.Installer ins = (WindowsInstaller.Installer)new Installer();
//string MSIpath = @"";
//Database db = ins.OpenDatabase(MSIpath, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly); //// Open the MSI database in the input file
//// Open a view on the Property table for the Label property
//View vw = db.OpenView(@"SELECT * FROM Property WHERE Property = 'ProductVersion'"); // I'd like to pull from other tables besides Property as well
//vw.Execute(null); // Execute the view query
//Record record = vw.Fetch(); // Get the record from the view
////// Get the Label from the data
//string Label = record.get_StringData(2);
//String[] a = Label.Split('.');
//string MajorNumber = a[0];
//string MinorNumber = a[1];
//int RevisionNumber = 0;
//int.TryParse(a[a.Length - 1], out RevisionNumber);
//RevisionNumber++;
//Console.WriteLine("Before " + record.get_StringData(1) + ": " + record.get_StringData(2));
//record.set_StringData(a.Length - 1, String.Concat(MajorNumber, ".", MinorNumber, ".", RevisionNumber.ToString()));
//Console.WriteLine("After " + record.get_StringData(1) + ": " + record.get_StringData(2));
//while (record != null)
//{
// Console.WriteLine(record.get_StringData(1));
// record.set_StringData(1, RevisionNumber.ToString());
// record = vw.Fetch();
//}
//vw.Modify(MsiViewModify.msiViewModifyMerge, record);
//vw.Close();
//db.Commit();
#endregion
//Console.Read();
}
private void setMaxVersion()
{
}
private void RenameMSI(string msiFilePath)
{
StringBuilder sb = new StringBuilder();
string[] words = msiFilePath.Split('\\');
foreach (string word in words)
{
sb.Append(word + '\\');
if (word.Contains("Debug") || word.Contains("Release"))
{
break;
}
else
{
}
}
Program p = new Program();
string VersionMax = p.GetMsiVersionProperty(msiFilePath, "ProductVersion");
string productName = p.GetMsiVersionProperty(msiFilePath, "ProductName");
string newMSIpath = sb.ToString() + string.Format("{0}_{1}.msi", productName, VersionMax);
Console.WriteLine("Original MSI File Path: " + msiFilePath);
Console.WriteLine("New MSI File Path: " + newMSIpath);
System.IO.File.Move(msiFilePath, newMSIpath);
}
private string GetMsiVersionProperty(string msiFilePath, string property)
{
string retVal = string.Empty;
// Create an Installer instance
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)new Installer();
// Open the msi file for reading
// 0 - Read, 1 - Read/Write
Database db = installer.OpenDatabase(msiFilePath, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly); //// Open the MSI database in the input file
// Fetch the requested property
string sql = String.Format("SELECT Value FROM Property WHERE Property='{0}'", property);
//string sql = "SELECT * FROM Upgrade"; // "SELECT VersionMax FROM Upgrade"
View view = db.OpenView(sql);
//View view = db.OpenView(@"SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'");
view.Execute(null);
// Read in the fetched record
Record record = view.Fetch();
if (record != null)
{
retVal = record.get_StringData(1);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(record);
}
view.Close();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(view);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
return retVal;
}
private string SetMsiProperty(string msiFilePath, string property, string value)
{
string retVal = string.Empty;
// Create an Installer instance
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)new Installer();
// Open the msi file for reading
// 0 - Read, 1 - Read/Write
Database db = installer.OpenDatabase(msiFilePath, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeTransact); //// Open the MSI database in the input file
// Fetch the requested property
string sql = String.Format("SELECT Value FROM Property WHERE Property='{0}'", property);
View view = db.OpenView(sql); //View vw = db.OpenView(@"SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'");
view.Execute(null);
// Read in the fetched record
Record record = view.Fetch();
if (record != null)
{
record.set_StringData(1, value);
}
view.Modify(MsiViewModify.msiViewModifyReplace, record);
view.Close();
db.Commit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(record);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(view);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
return retVal;
}
static string GetMsiProperty(string msiFile, string property)
{
string retVal = string.Empty;
return retVal;
}
}
}
这篇关于之后无法重命名MSI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!