InstallShield - Get version of a file - installation

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.

Related

Add Visual Studio 2010 custom property for .msi installer

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

Using ClickOnce exe as a Visual Studio external tool

I have a command line executable I built which is published on the network via ClickOnce. The main use of this tool is through Visual Studio as an external tool. When I set this up in Visual Studio I am able to set the command path to the shortcut under roaming data for my profile.
However, Visual Studio resolves this to a path such as:
C:\Users\ME\AppData\Local\Apps\2.0\CGR50YPV.W5E\RXBXM176.HH8\crea..tion_f423fce0316e1dfa_0001.0000_adecafbe6c6acba3\MyAppp.exe
So what happens is if I launch the exe and grab a new version, Visual Studio is still pointing at the old version (as indicated above). I can fix this by re-pointing the command value of my external tool to the shortcut of my exe, but this is a bit frustrating to deal with.
How can I make this work without having to update my command path every time?
You shouldn't access a ClickOnce application via the exe file. If you're going to do that, just xcopy the \bin folder of the application to the other machine. If you want to use the update features, you should always invoke the ClickOnce application by using the shortcut or by invoking the link to the deployment manifest on the webserver. (The deployment manifest is the application file). You can do a process.start on that link.
[edit -- add new info]
Ohhhhh, so you're accessing the shortcut in the folder under the user's profile? Am I getting that? Instead of looking for that one, can you point to the shortcut on the start menu? It will add one automatically when the user installs the application, if the application is online/offline. The shortcut is added to the start menu to the location of the Publishing Company / Product Name using those fields from the Options dialog.
I do this by setting the assembly information to the same values, and retrieving the assembly information programmatically. I always set the assembly description to be identical to the product name, and the assembly company to be the same as the publishing company. Then I can do this:
Assembly code = Assembly.GetExecutingAssembly();
string company = string.Empty;
string description = string.Empty;
if (Attribute.IsDefined(code, typeof(AssemblyCompanyAttribute)))
{
AssemblyCompanyAttribute ascompany =
(AssemblyCompanyAttribute)Attribute.GetCustomAttribute(code,
typeof(AssemblyCompanyAttribute));
company = ascompany.Company;
}
if (Attribute.IsDefined(code, typeof(AssemblyDescriptionAttribute)))
{
AssemblyDescriptionAttribute asdescription =
(AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(code,
typeof(AssemblyDescriptionAttribute));
description = asdescription.Description;
}
if (company != string.Empty && description != string.Empty)
{
string shortcutName =
string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Programs),
\", company, "\\", description, ".appref-ms");
}
(Sorry, I can't figure out how to make the code format prettier and show the indents properly, but you get the idea.)

How Do I Prevent the Installer from Running when Application Data Files are Removed?

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

Any quick way to run a file in Visual Studio?

Is there any quick way to run a file(.cs) in VS 2008 with a Main method ?
Often you'd want to test some mockup code, Going Alt+f7(Project->ProjectName Properties) and changing the Startup object from a dropdown list is quite cumbersome.
Get yourself the SnippetCompiler, it's made to run snippets (not inside of VS, but close enough) and may help you.
What about instead of mockups, writing those as unit tests. You can run those quickly without changing entry points. And the tests could stick around for later changes. Instead of writing to the Console, you would use Asserts and Trace Writes.
To compile one file C# programs I have created a .bat file, on which I drag and drop a .cs file and get a .exe in .cs file directory.
SET PATH=%PATH%;C:\WINDOWS\Microsoft.NET\Framework\v3.5
cd %~d1\
cd "%~p1"
csc %1
You can use this .bat file in a Visual Studio macro to compile active .cs file and run the application.
Sub RunCS()
If Not ActiveDocument.FullName.EndsWith(".cs") Then
Return
End If
REM Path to batch file
Dim compileScript = "C:\dev\compileCS.bat"
Dim compileParams As System.Diagnostics.ProcessStartInfo
compileParams = New ProcessStartInfo(compileScript, Chr(34) & ActiveDocument.FullName & Chr(34))
Dim compiling As System.Diagnostics.Process
compiling = System.Diagnostics.Process.Start(compileParams)
compiling.WaitForExit()
Dim programFile As String
programFile = ActiveDocument.FullName.Substring(0, ActiveDocument.FullName.Length - 3) + ".exe"
Dim running As System.Diagnostics.Process
running = System.Diagnostics.Process.Start(programFile)
End Sub
This will run only programs for which all code is in one file. If you want to quickly change projects instead, you can change your solution's Startup Project to Current selection
I keep a sandbox solution around that has a console project and other tiny project types that I use frequently. Snippet Tools are nice but usually don't come with the whole Visual Studio shebang like debugging etc.
Snippy, originally by Jon Skeet (who lurks on here I believe) and further developed by Jason Haley.

How do I embed a File Version in an MSI file with Visual Studio?

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?

Resources