Wix ToolSet Patch Creation Using "Patch Creation Properties" - c#

First of all, I'd like to iterate that I am a complete noob regarding installers and patches, and have been living by articles from the interwebz.
Quick background: We've created an installer that "installs" a web app - creates IIS services, databases, etc. For the succeeding releases, we plan on using patches for the minor upgrades. We use .NET C# for this app.
I've been trying to create a patch for the project using the "Patch Creation Properties" tutorial from the wix site: http://wixtoolset.org/documentation/manual/v3/patching/patch_building.html
I managed to create a patch, and it does work, but I've noticed that it only changes html, js, and css files, along with the web config. Any changes that I made on .cs files were not reflected. I'm assuming that DLL files are not being replaced by the patch.
Below is my config for the patch.wxs:
<PatchCreation
Id="{real guid heere}"
CleanWorkingFolder="yes"
OutputPath="C:\Outputpath\patch.pcp"
WholeFilesOnly="yes" >
<PatchInformation
Description="Project 3.0.10 Patch"
Manufacturer="project"/>
<PatchMetadata
AllowRemoval="yes"
Description=" Patch v3.0.10"
ManufacturerName="ManufacturerName"
TargetProductName="TargetProductName"
MoreInfoURL="www.google.com"
Classification="Update"
DisplayName="ManufacturerNamePatch"
MinorUpdateTargetRTM="1"/>
<Family DiskId="5000"
MediaSrcProp="Patch"
Name="patchtest">
<UpgradeImage SourceFile="C:\output\test\new\admin\Setup.msi"
Id="UpgradeImage">
<TargetImage SourceFile="C:\output\test\old\admin\Setup.msi"
Order="2"
Id="TargetImage"
IgnoreMissingFiles="no" />
</UpgradeImage>
</Family>
<PatchSequence PatchFamily="SCMPatchFamily"
Supersede="yes" />
</PatchCreation>
I did a patch install with log, and noticed this:
MSI (s) (18:F0) [17:37:18:316]: File: C:\Location\Website.Web.dll; Won't Overwrite; Won't patch; Existing file is of an equal version
I've been scouring the net for answers and haven't found a fix for this.
Thank you very much.

The clue is in the message! Service packs, patches, hotfixes all depend on updating binaries based on the file version. Not only does this speed things up by not installing files that don't need changing, it ensures that you don't overwrite a higher version with an old version. Creation dates (as in the idea that a file should be replaced because mine is newer) do not apply. File versiions are also useful for identifying whether a client has an up-to-date version. So increment the file version, and if it's managed code you don't need to change AssemblyVersion, just add an AssemblyFileVersion for the files that have actually been changed, incremented above the existing installed versions.
https://msdn.microsoft.com/en-us/library/aa367835(v=vs.85).aspx

Related

How to build different editions of an ASP.Net Webform by excluding some folders and files?

I hope it's not a duplicated question since I searched enough about it but I found nothing, maybe that's because I didn't know the appropriate words describing my situation.
The question:
Summary: Can Visual Studio build different editions of an ASP.Net Webform just by a simple wizard or something like that? Some Cs, Js Or Css files or some folders shouldn't be involved in the final output.
Detailed:
We have had a very large ASP.Net project containing lots of folders and involving lots of features, we have been offering the whole project to customers and we have been protecting it by License approach (which applies Private and Public keys mechanism).
Now the company considers to offer different editions of the application based on the customer type, so if the customer is a small business it will be offered an application with less features since he is going to pay less money.
Keep in mind that we don't want to offer customers the complete application and then based on the permission which are defined in a table in the database he can get access to just the features we tend, It's no that good, beacuse after he are given the limited edition license, he is able to change his permission by modifying the related table in databadse or if he dissemble the related Cs or dll files (I have read about obfuscation to make it safer)
They wouldn't gain anything even if they grant required permissions complately to themselves beacuse they don't have required files.
I had hared of an application which is used to manage -or better to say customize- the project build process, what is the best solution? would you enlighten me?
I would highly recomend you to look into build configurations in visual studio. There you can choose what project files to build and control the output.
Check out the following for more details:
https://msdn.microsoft.com/en-us/library/kkz9kefa.aspx
I'm still looking for the best solution but for now, after searching a lot I found some solutions applying MsBuild, for instance to exclude some folders and some files from being published you can add following script in visual studio project file (.csproj):
<ItemGroup>
<ExcludeFromPackageFolders Include="Scripts\large">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFolders>
<ExcludeFromPackageFiles Include="Scripts\mash.js.chirp.config"/>
<ExcludeFromPackageFiles Include="Content\mash.js.chirp.config"/>
</ItemGroup>
This will cause the following folder and files to be excluded:
Scripts\large
mash.js.chirp.config
You should add above script in .csproj xml config file exactly below the line which says:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
Here's some useful links: This one and This one
Keep in mind that there is no visual studio project file in Web site so you can apply it in Web application but Website, Here is the source from MSDN.
Although here it's told that you can use MSBuild even if it's about Website, Take a look at this link so you'll learn how to create a project file for that purpose.

Keep only one copy of each ClickOnce dependency?

I'm publishing a ClickOnce application that has a few dependencies in the form of DLLs. When I publish the initial version 0.0.1 all the dependencies are copied into the deployment folder as I would expect.
If I make an update and publish version 0.0.2 all of the same dependencies, which are unchanged and have the same file hash, are copied into a second subfolder within the deployment folder.
The folder structure looks like this:
deployment/
MyApplication.application
setup.exe
Application Files/
MyApplication_1_0_0_1/
Dll_A.dll - Hash: 0x111111111111111
Dll_B.dll - Hash: 0x222222222222222
MyApplication_1_0_0_2/
Dll_A.dll - Hash: 0x111111111111111
Dll_B.dll - Hash: 0x222222222222222
Is there any way to only have one copy of Dll_A.dll/Dll_B.dll when they are the same file and only have a new copy if they change?
I'm referring to the size of the directory on the developer's end. Not the size of the download and cache that clients have as I understand ClickOnce already takes care to minimize that.
My issue came from a misunderstanding of how the Application Files directory works.
Yes there is a new folder with the same DLLs made each time, but for upgrades to work you do not need to keep all of the folders in it. You can erase all of them except for the most recent release and have no ill effects.
Even if someone is between versions/missed upgrades they will simply pull the latest version when their program updates. They don't need the intermediate versions they missed inbetween.
I don't believe ClickOnce allows for that granular of control.
Edit:
Found this, it may help with your question on the cleanup.
ClickOnce deployment is leaving multiple versions (yes, more than two)

Bringing C# application under assembly version and using it to create patches and manage them

We have a C# desktop application which we run for clients on various servers on a software as a service model. We are still on dot net framework 2.
The software has a architecture in which we have an independent application to catch external data thrown by some server. Then an application to make calculations based on it. Also one more application on which the client sees the output. The link between the 3 applications is another application which communicates with the DB.
The 4 solutions are on a SVN for sourcecontrol. But the release management is still manual and the patches are made manually by checking the log and including the dlls, pdbs, xml. etc for the projects for which the code has changed.
There is no assembly versioning implemented and the patch or release management is just done in the dark.
I want to know what is the industry practice for generating automatic patches from the code. Also I want a patch for each revision in the SVN. Also is assembly versioning helpful in this?
I have read much about continuous integration but it fails because we do not have unit tests and other fancy code to moniter the correctness of code.
The only thing at this time I would be interested is to implement a way to make patches which can be applied and removed easily. Also I want to know a way to determine the way we can monitor which release is at which level(or what patches have been applied) by some automated way rather than maintaining a log manually.
We use a build script which creates a SvnVersion.cs file containing the last commited revision. This file is placed in the root of the solution, and then added to all projects in the solution (but added as a link, not copied).
The template for the file (SvnVersion.Template.cs) looks like this:
using System.Reflection;
[assembly: AssemblyVersion("1.0.0.$WCREV$")]
[assembly: AssemblyFileVersion("1.0.0.$WCREV$")]
And we simply use TortoiseSVN to fill these placeholders in a batch script:
type "%TRUNKPATH%SvnVersion.Template.cs" > "%TRUNKPATH%\SvnVersion.tmp"
SubWcRev "%TRUNKPATH%\" "%TRUNKPATH%SvnVersion.tmp" "%TRUNKPATH%SvnVersion.cs" -f
IF ERRORLEVEL 1 GOTO ERROR
DEL "%TRUNKPATH%SvnVersion.tmp"
If you don't use TortoiseSVN, there are other ways to get this info in the file.
You will also need to remove this same information from your AssemblyInfo.cs files or you'll get a compile error. Also, to speed up Debug builds, this is only executed in Release builds (and in Debug builds only if the file doesn't initially exists, like after a fresh checkout).

Deploy C# ActiveX in a CAB for Internet Explorer use

I am desperately trying to deploy an ActiveX for IE developed in C# as a CAB archive. I have read many resources (some of them from StackOverflow) and it appears a lot of people are having the same problems. I have tried 3 solutions: a) creating a CAB VS project, b) manually creating a CAB using CABARC with a COM registration in INF and c) manually creating a CAB with launching msiexec. None of them worked. I even tried d) creating a bootstrapper which launches msiexec to no avail (because some people suggested simply launching msiexec on Vista can't work).
I am running Windows Vista but my project fails to run even on IE6 on XP.
When I install ActiveX using MSI, all is fine on ALL Windows. Apparently CAB thing is not working and I could not find a proper way to debug this whole process yet.
Any help is appreciated.
Update: Note that this old but excellent answer is still a very good outline for how to approach solving this problem, at least as along the evolutionary scale as Win7 and IE11. I just succeeded making it all work using the Answerer's Firebreath.org toolset as a jumping off point. It's not simple but it can be done. I've added a reference to that project to the reference list below since it may make a more logical jumping off point for current developers than this overview is.
Hooray - I have just finished an identical project, so you'll be pleased to know that it's actually possible. I have only tested this on XP - I understand there may be issues where Vista/7 don't allow msiexec to be called.
Given that you have an assembly correctly exposing a COM interface, I did the following:
Strong-named the assembly.
Created an INF file
Created an MSI using the Visual Studio 2008 "Setup Project" template.
Created a CAB file using "iexpress.exe" bundled with Windows XP.
Create INF file
The *.inf file I used looks like:
[version]
signature="$CHICAGO$"
AdvancedINF=2.0
[Setup Hooks]
install=install
[install]
run=msiexec.exe /package """%EXTRACT_DIR%\SampInst.msi""" /qn
The only bit you should need to change is the SampInst.msi. Note I would use an 8.3 filename, as long filenames can cause issues. While testing, I would not use the qn switch either, as that is a silent install.
Create the Installer
The installer has to do only one thing, and that is register the assembly by calling RegAsm on it. Most installers will provide some method to easily do this. For example, an installer created through VS 2008 will simply need to have the “Register” property of the assembly set to “vsdrpCOM”. Note that vsdrpCOM should be chosen as it generates the appropriate registry entries at build-time. The vsdrpCOMSelfRegistration setting is likely to fail as it calls RegAsm at run-time, and will thus not work for non-administrators.
Package the installer into a CAB file
This can be done by any cab archiver. Windows XP contains iexpress.exe, a wizard driven archiver, while Microsoft’s CAB SDK contains cabarc.exe. Other 3rd-party tools are also available.
Note that you will need to reserve space in the CAB file for code-signing if you are going to sign the CAB.
You will need to CAB the INF file, and the MSI file. You will not need to CAB the Setup.Exe file.
Handy hint: The VS2008 Setup Project project type allows you to set a post-build step in the properties, so you can build and CAB in a single step. My post-build step looks like:
cd "$(ProjectDir)"
"%WINDIR%\System32\Makecab.exe" /f "VboCslib.ddf"
The DDF file format is documented.
Sample HTML page
The object tag is used to point to the cab file containing the installer. A very simple HTML page which would deploy an ActiveXControl would be:
<html>
<head></head>
<body>
<!--
ID : The id of the ActiveX control to be used in JavaScript.
CLASSID : The GUID associated with the ActiveX control.
CODEBASE: The location containing the CAB installer for the ActiveX
control. This could be a URL, or a relative path.
-->
<OBJECT ID="MyActiveXControl"
CLASSID="CLSID:FC36FAE1-48E0-4f6b-B469-E1B5A8C6D1AC"
CODEBASE="cabfiles\SampleCabFile.CAB#version=1,0,0,0">
</OBJECT>
<script>
MyActiveXControl.SomeMethod();
</script>
</body>
</html>
Handy hints
Ensure your installer installs on a "per-user" basis, not a "per-machine" basis. This will make it more likely to install if the user does not have admin privileges.
Trouble-shooting
Internet Explorer 6 actually provides a really useful diagnostic aid. Clear your Temporary Internet Files, then navigate to the web-page. If the installation does not work, go to your temporary internet files and you will see a couple of files in there. One of these will be an error log starting ?CodeDownloadErrorLog. Drag it to your desktop and open it in notepad, and it will give details on what it was trying to do when it failed.
References
Microsoft KB247257 – Steps for signing a .cab file
MSDN – About INF File Architecture
SN.EXE - Code Strong Programs with Strong Names
Nikolkos Craft – How To: Deploy .NET ActiveX Control
CodeProject – Create ActiveX .NET Step by Step
CodeProject – Downloading C# ActiveX Components through CAB file
MSDN - ALLUSERS Property (Windows)
MSDN – Non-Admin ActiveX Controls
MSDN – Microsoft Cabinet Format
Update: Firebreath.org has a toolset for generating browser plugins for many platforms. The IE/ActiveX code to solve the problem posed here is just a subset. But as of 6 Nov 2014, I found it easier to start with Firebreath and its instructions than to try to build up my dev environment and roll all my own solutions from scratch.

How to force deployment project to update files during installation of newer version?

I have a Deployment Project for my VS2008 C# application. When installing a new version of my application I want to make sure that files are updated with the files contained in the installer.
I want my installer to automatically remove any old version of the installed application. To do that I follow this procedure (also described here):
Set RemovePreviousVersions to True
Set DetectNewerInstalledVersion to
True
Increment the Version of the
installer
Choose Yes to change the ProductCode
For the assemblies I make sure the AssemblyVersion is set to a higher version:
[assembly: AssemblyVersion("1.0.*")]
Everything is working as intended except for my configuration files (xml files). Since I cannot find a way to "version" these files I cannot make sure that the files are updated if they have been modified on the target machine.
Is there any way to do this and how?
UPDATE: I have tried the approach/solution/workaround found here
Include the file directly in a
project with the following
properties: "Build Action -> Content
file" and "Copy to Output Directory
-> Copy always"
Then add it to the deployment
project via Project
Output->Database->Content Files
Unfortunately it did not make any difference. The behavior is exactly the same.
Add the following property to the Property table of the MSI:
Property REINSTALLMODE with Value amus
Note: This will cause all the files in the MSI (versioned and nonversioned) to overwrite the files that are on the system.
If you're willing to use Orca (there may be another way to do this method, but it's the only one I know of) you may be able to set up RemoveFile directives.
See here for a typically light-weight MSDN document -- could be a starting point.
http://msdn.microsoft.com/en-us/library/aa371201.aspx
Alternatively you could always create a very simple bootstrapper executable that simply calls "msiexec /i REINSTALLMODE=oums" (or whichever command-line switches are needed). Call it setup.exe if you like...
Better option long-term may be to switch to InstallShield or similar -- VS2010 includes a light version of IS and I believe they're moving away from vdproj projects.
Have you tried the approach/solution/workaround found here?
Include the file directly in a
project with the following
properties: "Build Action -> Content
file" and "Copy to Output Directory
-> Copy always"
Then add it to the deployment
project via Project
Output->Database->Content Files
I may be incorrect here, and therefore I am exposing myself to down votes, but here goes anyway!
I believe it is on purpose that config files do not automatically get overwritten; the principle there being that you would not normally want your application's configuration overwritten when you install the new version of the program... at least not without numerous warnings and/or chances to merge configuration first.
Having your application configuration get overwritten by an updated version of a program could make for a very upset end user (in this case, web site admin).
Further, I know that sometimes, the developer may be the person doing the deployment. In such a case, this behavior might not seem so logical when deploying a single site to a single server; but when roles are split and/or you have multiple servers with different configurations, this can be a life saver.
You need to include the new version of your files in your custom installer and manually install these file during Custom Install routine is called
This must be applied to any file that does not have version that can be tracked by the installer.

Categories

Resources