How do I add a custom property in visual studio 2010 for an .msi generated at build time.
The .msi file should have a property named "BUILDARCHITECTURE". If it's not difficult this property should be automatically changed to x64 or x86 when I change the build platform.
If this is not possible I can just hardcode it to x86 ( it will be deployed on 32 bit machines ).
In Orca I can just go to the Property Table then just right click and add row and it works.
But I need to add it automatically at build time in VS2010.
Best Regards
So after some research I've gone with a similar approach like Phil's.
Meaning I added a post build event :
set msiFile=$(OutDir)\setup.msi
if "$(Configuration)" == "Release" (
wscript $(SolutionDir)\..\Build\AddCustomProperty.vbs %msiFile%
VBS Script :
set o_installer = CreateObject("WindowsInstaller.Installer")
set o_database = o_Installer.OpenDatabase("path_to_your_msi", 1)
s_SQL = "INSERT INTO Property (Property, Value) Values( '<CustomProperty>', '<custom_property_value>')"
Set o_MSIView = o_DataBase.OpenView( s_SQL)
o_MSIView.Execute
o_DataBase.Commit
The script was taken from : Need a way to add one property to the msi properties table in setup project in VS2010
You can do it with a post-build step, and I'd start with WiRunSql.vbs from the Windows Kit SDK. It's a script that takes a SQL statement to update an MSI file. You want a SQL something like:
INSERT INTO `Property` (`Property`.`Property`, `Property`.`Value`) VALUES ('BUILDARCITECTURE', 'whatever')
However why do you need it there? An MSI knows its architecture with the VersionNT64 property, so inside the MSI you just use that, or pass it to your custom actions or whatever.
From outside the MSI you can get the architecture from the summary info stream template property, as in this dumb vbscript:
Option Explicit
Dim installer
Set installer = CreateObject("WindowsInstaller.Installer")
Dim sumInfo : Set sumInfo = installer.SummaryInformation("another.msi", 0)
dim someproperty
someproperty = suminfo.Property(7)
msgbox someproperty
set suminfo = Nothing
set installer=nothing
Related
This question may be a little stupid, but i'm curious if it is possible or not.
I have a file named library.xxx(contains vbscript code), which contains predefined functions. And i have an other file test.vbs(also contains vbscript code, just here i use the functions, which are defined in library.xxx). In test.vbs the library is "included", which means, i can use the functions from library.xxx. For example, there is a function called ProgramFiles, and if i call it in test.vbs, i will receive the Program Files folder location.
The problem is, that library.xxx is visible in this way. There is an application called ScriptCryptor. With this application, i can open my library.xxx and make an .exe of it, which would be better for me, since it is not clear text.
My problem is now, how could i execute the command which are called in test.vbs? I think i should read line by line the test.vbs file, and process it somehow. But how? How do i know if the line i read is a function or just a variable? Or both? And how to process them?
Is there some way to do that?
Hopefully it is understandable what i want.
Thanks!
By far the easiest way to accomplish this is to include "library.vbs" in to your "test.vbs" file.
For example:
Library.vbs:
Function ProgramFiles()
ProgramFiles = "C:\Foo"
End Function
test.vbs:
sub includeFile (fSpec)
dim fileSys, file, fileData
set fileSys = createObject ("Scripting.FileSystemObject")
set file = fileSys.openTextFile (fSpec)
fileData = file.readAll ()
file.close
executeGlobal fileData
set file = nothing
set fileSys = nothing
end sub
includeFile "library3.vbs"
wscript.echo ProgramFiles
Your question seems to indicate that you may already be doing this so if you are then I apologize.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
If clear text truly is bothering you then from what I have seen there is no way to make the executable from ScryptCryptor to be made available to your vbscript.
Instead you could create a COM Library DLL to be used as an object in your test.vbs file.
The downside to this is that it will be necessary to learn a new language. Visual Studio Visual Basic certainly is different from Windows Shell Script Visual Basic but it would work for what you want.
Steps to take:
Download Visual Studio 2013 Express for Windows Desktop (or trial version of Ultimate or whatever you feel is appropriate for you)
Open Visual Studio as an Administrator
Create a new Project. Select a "Class Library" under the "Visual Basic" templates
Copy and paste the code below
<ComClass(OurLibrary.ClassId, OurLibrary.InterfaceId, OurLibrary.EventsId)>
Public Class OurLibrary
Private userNameValue As String
Public Const ClassId As String = "40491A82-D53A-46A6-B7E0-1CDF78A33AB6"
Public Const InterfaceId As String = "B49C996C-B039-471D-BF17-0DDA5B3CF517"
Public Const EventsId As String = "6245E3DD-DEB5-4B75-AC03-F4430BC18FDE"
Public Sub New()
MyBase.New()
End Sub
Public Sub mycopy(mySource As String, myDest As String)
My.Computer.FileSystem.CopyFile(mySource, myDest, True)
End Sub
End Class
Click on Project -> ClassLibrary1 Properties
Click on "Compile" and check the box for "Register for COM interop"
Click on Build -> Build Solution
You now have a library that your test.vbs can use:
Set myLib = CreateObject("ClassLibrary1.OurLibrary")
mySource = "C:\mytextfile1.txt"
myDest = "C:\mytextfile2.txt"
myLib.mycopy mySource, myDest
If your like me test.vbs needed to be called as C:\Windows\SysWOW64\cscript.exe test.vbs
For more information about creating COM classes in Visual Basic see here: Walkthrough: Creating COM Objects with Visual Basic
One of the conditions for showing some UI controls in my Setup application is based on whether a file exists.
This check can't be done through custom actions since even the OnBeforeInstall event happens after install, and the dialog I want to alter is shown before that.
If I was using WiX it would be simple as
<Property Id="FILEEXISTS">
<DirectorySearch Id="CheckFileDir"
Path="[CommonAppDataFolder]Manufacturer\Product"
Depth="0">
<FileSearch Id="CheckFile"
Name="Filename.ext" />
</DirectorySearch>
</Property>
How to do it without WiX?
You can put the WiX code into a Merge Module project and then consume it in the Setup Project.
Redemption of Visual Studio Deployment Projects
FWIW, IMO, Setup Projects are just horrible. Microsoft killed it in VS2012 and there are thousands of complains on the user voice site by people who don't know anything about installers to bring them back.
If it was me, since you are doing custom UI work, I'd spend the $2000 on a single copy of InstallShield Professional and adopt merge modules using Windows Installer XML. Sure this can all be done using just WiX but the time saved is worth the $.
Augmenting InstallShield using Windows Installer XML - Certificates
You'll need a post build JScript for your MSI file. Or you can do it manually in Orca.
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var filespec = WScript.Arguments(0);
var msiOpenDatabaseModeTransact = 1;
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
Execute("INSERT INTO `AppSearch` (`Property`, `Signature_`) VALUES ('FILEEXISTS', 'CheckFile')");
Execute("INSERT INTO `DrLocator` (`Signature_`, `Parent`) VALUES ('CheckFile', 'CheckFileDir')");
Execute("INSERT INTO `DrLocator` (`Signature_`, `Path`, `Depth`) VALUES ('CheckFileDir', '[CommonAppDataFolder]Manufacturer\\Product', 0)");
Execute("INSERT INTO `Signature` (`Signature`, `FileName`) VALUES ('CheckFile', 'Filename.ext')");
function Execute(sql) {
view = database.OpenView(sql);
view.Execute();
view.Close();
}
I have an application written in VB.Net with Visual Studio 2005. The application allows the user to create and save project files. When I distribute the application, I include some demo project files, which I install in the common application data folder.
XP - C:\Documents and Settings\All Users\Application Data
Vista & 7 - C:\Program Data
I have discovered an unexpected behavior -- if any file in the common application data folder is removed, and the application is run from the start menu, then the install procedure will start and attempt to restore the missing file(s). If the MSI file no longer exists at its original location or has been changed, then the application will fail to run. I perceive that this is a "feature", but it is one I don't want. Can anyone tell me what is going on and how I can avoid it?
Some more details:
I created the setup package by using a Visual Studio deployment
project.
This behavior will not occur if I launch the EXE directly. I
expect, therefore, that the behavior has something to do with the
start menu shortcut. I've noticed that the shortcut isn't a normal
shortcut -- it doesn't have a "Target Location".
All advice is appreciated.
-TC
I have learned that this behavior involves something called "Install-on-Demand" (aka "Self Heal"). The unusual shortcuts created by the setup package are called "Advertised Shortcuts". Now that I have a name for the problem, it is easy to find information on how to fix it. Notably:
http://msdn.microsoft.com/en-us/library/aa368297.aspx
http://groups.google.com/group/microsoft.public.dotnet.distributed_apps/browse_thread/thread/401847045f104af3
http://blog.jtbworld.com/2007/11/enable-target-and-change-icon-of.html
Those pages contain a wealth of information. For the convenience of others who may stumble upon this post, I will summarize what they say:
Advertised shortcuts are special shortcuts which do some fancy things. Most notably, they reinstall damaged application before launching their target. There is some debate over whether they are good, evil, or harmless. In my opinion, they do something most users don't expect, and that makes them evil. Therefore, I'd like to disable them for my application.
Visual Studio setup projects automatically create MSI packages which generate advertised shortcuts by default. It is easy to override that default when installing the MSI package by using DISABLEADVTSHORTCUTS=1 as a command-line argument for Setup.exe. Also, with a utility like Orca, you can manually change the default by inserting DISABLEADVTSHORTCUTS=1 as a property of the MSI. However, if you want Visual Studio to automatically create MSI packages which don't create advertised shortcuts, that is harder. I did it this way:
First, I created a VBS file using the DisableAdvt code provided by Gary Chang in one of the links above (I've repeated that code below). Just create a text file, paste in the code. and save it as DisableAdvt.vbs.
Then, create a post-build event for your setup project. The exact syntax will depend on your file locations. Because my DisableAdvt.vbs is in a "Tools" subfolder of the solution folder, my post-build event looks like this:
"$(ProjectDir)..\Tools\DisableAdvt\DisableAdvt.vbs" "$(BuiltOuputPath)"
That's all I had to do. It works like a charm.
-TC
Some notes:
In Visual Studio 2005, Build events are accessed differently for setup projects than they are for other types of projects. Click on the project name in the solution explorer, then look for PostBuildEvent in the Properties pane.
Orca is a utility that can be used to manually insert the DISABLEADVTSHORTCUTS property into the MSI file. With my approach, Orca is not necessary. However, it is useful for verifying that the build event is making the expected change.
http://www.technipages.com/download-orca-msi-editor.html
In the build event, the misspelling "BuiltOuputPath" is intentional.
Here is Gary Chang's DisableAdvt.vbs code (note that I fixed a typo on line 21 -- Very important!):
Option Explicit
Const msiOpenDatabaseModeTransact = 1
Dim argNum, argCount:argCount = Wscript.Arguments.Count
Dim openMode : openMode = msiOpenDatabaseModeTransact
' Connect to Windows installer object
On Error Resume Next
Dim installer : Set installer = Nothing
Set installer = Wscript.CreateObject("WindowsInstaller.Installer") :
CheckError
' Open database
Dim databasePath:databasePath = Wscript.Arguments(0)
Dim database : Set database = installer.OpenDatabase(databasePath, openMode) : CheckError
' Process SQL statements
Dim query, view, record, message, rowData, columnCount, delim, column
query = "INSERT INTO Property(Property, Value) VALUES ('DISABLEADVTSHORTCUTS', '1')"
Set view = database.OpenView(query) : CheckError
view.Execute : CheckError
database.Commit
If Not IsEmpty(message) Then Wscript.Echo message
Wscript.Quit 0
Sub CheckError
Dim message, errRec
If Err = 0 Then Exit Sub
message = Err.Source & " " & Hex(Err) & ": " & Err.Description
If Not installer Is Nothing Then
Set errRec = installer.LastErrorRecord
If Not errRec Is Nothing Then message = message & vbLf & errRec.FormatText
End If
Fail message
End Sub
Sub Fail(message)
Wscript.Echo message
Wscript.Quit 2
End Sub
I am using InstallShield 2010 and was wondering if anyone knows how to do the following:
I want to get the version of my main exe within my installer and make it the name of my setup.exe InstallShield is generating. Any idea how to do that?
There are several ways you could do this....depending on your IS project type (MSI, installscript, etc.)
1) create a variable such as Product_Name in the Property Manager, set it in your installscript and retrieve it to modify your *.exe name
2) Using SQL, you can programatically get the product_name and set the *.exe name. Search the Direct Editor (Installation Designer -> Additional Tools -> Direct Editor) for the exact location of the table/value you need. For example (below), using VBScript, I modify the path to the installation root of the files I pull into the IS project. Similarly this can be done for any table in the IS Direct Editor. Using a tool such as Visual build Pro I believe would help you out as well. It's well worth the ~$100!
Set oMSI = CreateObject("WindowsInstaller.Installer")
On Error Resume Next
' open ISM file in transacted mode
Set oDB = oMSI.OpenDatabase("C:\Path\to\myProject.ism", 1)
strQuery = "Select * FROM `ISPathVariable` WHERE `ISPathVariable`.`ISPathVariable` = 'InstallTreeFolder'"
'////////////////////////////////////////////////////////////
'// Update Path Variable
' fetch the one and only samplesource record
Set oView = oDB.OpenView(strQuery)
oView.Execute
Set oRec = oView.Fetch
' change field 2, the Value field
oRec.StringData(2) = "%INSTALL_TREE_ROOT%"
' update the changed record
oView.Modify 2, oRec
' close the view, commit changes, clean up
oView.Close: oDB.Commit: Set oMSI = Nothing
I was able to use the Automation services to accomplish this, which is the programming interface for InstallShield. Whenever I build my project in Visual Studio for my exe I run an exe in the Post-build that sets the InstallSheild project to be the same version.
I have a setup project for my C# program, and this setup project has a Version in its properties. I'd like for the MSI file that is generated to have this Version embedded in it, so I can mouse over it in explorer and see what version the file is.
I'm using VS2008. How can I do this?
If you simply add the "Version: 1.5.0" text into the Description property of the Setup Project, the version number also shows on the MSI file like so:
http://screencast.com/t/A499i6jS
As far as I know MSI file will never show version. Simple reason is that MSI files are not PE files, they are sort-of database. Msiexec.exe then interprets this database to do the actual installation. The version property you mention is used by MSI engine internally for upgrades, uninstalls etc and is never displayed.
That's a good question but I don't know any setup tool that could do that. Moreover I never encountered an MSI file with file version resource embedded in it, so it's not a common practice. Usually if I want to find out version of an MSI file I have to open it in Orca and check ProductVersion property there (in Property table).
Open up the associated .vdproj file in a text editor. Look for the "Product" section, then modify the "ProductVersion", and the "Manufacturer" fields.
"Product"
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:tidAxCleanupScript"
"ProductCode" = "8:{0949AAAD-2C29-415E-851C-825C74C9CA81}"
"PackageCode" = "8:{8F012EF1-D5D0-43DC-BBFD-761A639DDB07}"
"UpgradeCode" = "8:{38DE1949-0782-4EF3-BDC2-080EB5B73EF8}"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:**1.5.0**"
"Manufacturer" = "8:**Default Company Name**"
"ARPHELPTELEPHONE" = "8:"
I might be wrong, but doesn't the msi version follow the version in the AssemblyInfo file of your startup project?