Can ClickOnce install a single DLL for registration on end machine? - installation

I wrote a DLL (with a COM interface) and wonder if I can use ClickOnce to deploy it on end-user machines (to be called using CreateObject("My.DllClass") from the user VBasic app. All the documentation that I've read for ClickOnce (and the abortive attempts that I've made) seem to indicate that a real app (exe, etc) is required for ClickOnce -- it can't deploy a single DLL (and some txt files) and get the DLL registered for COM use on the target machine.
Q1. Is my understanding correct?
Q2. Is my best alternative to learn the Wix Installer?
Thank you

Q1: Yes, your ClickOnce application must have at least one launchable executable file. It's minimal requirement. But you can add any .net executable file there.
Q2: Yes/no. I will try to describe some things for you here. It'll let you make a right decision in your choose. Here is my point of view your task if you gonna choose a ClickOnce technology.
Abbreviate: ClickOnce application = Your.dll + dotNet-Some.exe
At the first you need to know a ClickOnce application locating in Users\[CurrentUser]\AppData\Local\Apps\2.0 after get installed by user. You can't effect on location, so if your client PC have more then one users, then second one must install your application for your self again. As me know your COM assembly must be registered by regasm.exe, there for your Some.exe can on launch register your dll by regasm.exe or some WinAPI functionality, so executable file won't be useless in this way.
Major question is update process, you must track your clickonce build number at the first, and for update operation user must launch your Some.exe for check and now workarounds from here. If this update process if fine, then you need re-register your assembly again (because clickonce add new folder for updated assembly) and user will be ready for use your class.
In the case of MSI package you have full control of install process, but you need always deliver this packages to your clients. Wix is good, if you are .NET developer take a look on WixSharp - let you create installer much more faster and have a lot of examples
If you don't gonna publish your ClickOnce application from Visual Studio then you can use Mage.exe / MageUI.exe for ClickOnce application preparation or use my builder utility from here second download link.
I hope what i said was a bit useful.

Related

Windows installer is too clever, tries to repair when tester deletes config file

Our application is deployed to the target machine with an msi file. All works nicely. Our tester has gone through his plan, and one of the tests requires deleting the application's configuration file. The application is designed to alert the user with a dialog on startup saying "missing config". However, what happens is that - somehow! - the software starts the installer again and retrieves the missing file from the msi! Which is nice, but not what we want. How do we disable that behaviour?
without going into much depth of the windows installer mechanics (if you interested in that there a plenty of articles about this), the shortcut of the software is probably advertised, which means the windows installer checks if everything is in its place before the software is started.
if you can edit the msi, make the shortcut non advertised.
if you can't, install it with DISABLEADVTSHORTCUTS
e.g. msiexec /i myMsi.msi DISABLEADVTSHORTCUTS=1
please note that this is only a quick (and dirty) workaround,
to fix this proper you need to understand the whole windows installer advertising (also called repair or self resiliency) mechanism.
but explaining all the causes and the mechanism of the repair is far beyond this answer and there are quite some articles and posts about that on the internet (and especially on MSDN and stackoverflow)
There is a more correct answer to this, and it is NOT DISABLEADVTSHORTCUTS. You set the component id to null in the MSI file to prevent repair of that individual file. See ComponentId comments here:
http://msdn.microsoft.com/en-us/library/aa368007(v=vs.85).aspx
Edit the MSI file with Orca to delete the Componenty ID, and write an uninstall custom action to delete the file at uninstall if it's there.
In addition, that's a redundant test. Windows will restore that file for you if it's missing, so the idea that you need a test to notify that it's missing is pointless. The true test should be that Windows will restore the file if it's lost, and your app needs to do potentially nothing about the missing file.
You don't mention what tool you are using to make your MSI but I'm going to go out on a limb and guess Visual Studio Deployment Projects (.VDRPOJ).
One of the (many) horrible things about this tool was that it fails to expose the foundational concept of components. Instead it makes every file a key file of it's own component and hides the existence of the component from you. I say 'was' because Microsoft killed this project type in VS. There are around 50k people complaining on UserVoice to bring this tool back and I'm guessing that 49,990 of them don't know what a key path is.
Windows Installer has a concept called the component rules and each component has a keypath. The keypath teaches MSI how to handle repair scenarios. But your tool has to allow you to be able to control this to make it work.
Windows Installer is functioning exactly the way it's supposed to function. You just aren't up to speed on what that is.
However, if you want to ignore Windows Installer best practices and continue using the tool you use today, the trick is to install the app.config file as a different file. Then have the application copy the file to the real file name on run. Windows Installer won't service what it didn't install.
Several answers have been provided that can work:
You can install the file with a blank guid. Then you need to remove it on uninstall using the RemoveFile feature. You will also run into issues if you want to replace it during an upgrade. Could be tricky at times.
You can disable the advertised shortcut(s), but this affects too much in my opinion.
Finally you can use my suggestion to install a separate non-advertised shortcut to use to launch the application. Such a shortcut bypasses the self-repair check. It may still be invoked by other means such as missing file associations, COM registration or similar, but those are exception states.
However, my preference is that an application can start without a config file present, if at all possible. I always suggest a good startup routine with "internal defaults" available. The startup routine should also degrade gracefully if faced with any file system access denied conditions.
Most importantly you should place this config file in the userprofile so you can generate the file on first launch for the user in question. It can even be copied from a read-only copy in the main installation directory.
When you generate a file from internal defaults and put it in a userprofile location, the file will have no interference with Windows Installer at all. The issues that results is how to clean up user data on uninstall. I discussed this with Stefan Kruger (MSI MVP) at one point, and I agree with his notion that user data is indeed user data and should not be automatically dealt with by your installer at all. Leave it installed, and clean it up via system administrator tools if necessary - for example logon scripts.

post installation code in ClickOnce

Is there any way to place code (C#) that will be executed after ClickOnce installation, without running the application?
I saw Microsoft's 'custom installer', which is a nice way to say "why don't you create an installer application", which I prefer not to (I want my users to have a single - well, double - click and that's that).
Any ideas will be appreciated.
ClickOnce applications run when installed - so you could essentially just bootstrap your own application.
You could either put some code at the start of the main entry point. Or, my preferred approach, you could create a second wrapper application. You would make the wrapper be the app installed by clickonce and install the real exe along side it. In the wrapper write your custom code and then when you're done launch and real exe using the Process class.

Visual Studio setup project "PackageAs" "extremely loose"

We were hoping to create a setup project which would allow for a pick-n-mix approach to which files were included for each local client installation.
Basically we've got a core setup.exe which we only want to build once, and which contains most of the product. But for each client there's a custom DLL which fits their solution. The custom DLL is loaded dynamically at runtime by the software and that's working fine. The problem is in the setup.
Of course we could 1) write an individual custom Setup.exe for each client too 2) keep a single setup.exe and customise it each time we want to do a build for the customer
But both those approaches are problematic.
For reasons too complicated to go into, the below approach is going to be the safest and most straightforward:
Maintain a single setup project
add all the custom DLLs to the setup project but set them to PackageAs=Loose (and also Vital=False)
then, every time we want to rollout the install files to the customer we send the setup files minus all the custom DLLs except his own
Our problem is that this approach falls down when you run the setup.exe on the client. Everything's fine except that the setup.exe still knows about all the DLLs you've quietly removed from the file system for this customer. And the installer starts shouting if it doesn't find all the files where it expects to find them:
Actually, this isn't a problem because you can hit Continue and then everything works fine.
Except that actually it is a problem because if you're selling to Pepsi (we're not, but say we were) you sort of don't want the installer to moan that it can't find CocaCola.foo.dll in the middle of its install.
We almost want an additional setting of Extremely Loose for the PackageAs field so that the installer knows not to even worry if it doesn't find the file.
Is there a solution within our existing approach without having to learn a third-party installer?
It sounds like your optional components should be created as Merge Modules and then you'd need a specific installer created that includes only certain modules. It sounds like you have some client specific libraries you don't want exposed to your other clients. Of course this means you'll need a build for each client, but that is something that could be automated.

Multiple Instances of ClickOnce app

Some background to my problem...
We are currently using ClickOnce to deploy part of our solution which was working a treat until we encountered a scenario where we are now required to have multiple instances of our application installed on the same PC. We are able to achieve this internally and have this working perfectly as we know what instances we have so our build process will update AssemblyName to include the instance name before publishing the installer, this means we are able to have multiple instances on our PCs internally (ie, test, live and demo etc).
Our external deployment process is slightly different, we take one of the ClickOnce installers created in our build (along with all our other components that make up our application) and as the ClickOnce installer is deployed on a server we update the app.config along with the manifest files and resign so they now have client specific details. If a client chooses to have multiple instances of our product installed the ClickOnce will now fail when a second instance is installed on a desktop PC as all instances share the same assemble name.
So finally to the question, does anyone know of a way to update the manifest etc after the clickonce package has been created to allow multiple instances to be installed? We could go down the route of building many clickOnce installers but I dont think this will really work for us, is there perhaps an alternative to ClickOnce which provides a similar upgrade experience for non-admin users?
Hopefully someone will be able to share their experiences and help me resolve this.
Thanks in advance
Doug
I don't know of another technology that allows such a simple auto update process. So sticking with ClickOnce... I think this link might be useful. It explains what you need to do to have the same app installed twice. Essentially changing the assembly name and product name should do it.
Hope that helps.
Greg

Creating Basic MSI that invokes another msi installation

I have asked this exact question on the Flexara forum, but got no response up to today, so I want to ask it here.
We currently have a InstallScript project which runs fine. The resulting setup can be made unattended/silent fine.
In this setup we have some features and invoke a number of third-party installations (that are a prerequisite for running our software).
However, we have customers that want an MSI file and therefore we resorted to the Basic MSI project type.
The setup is made without too much hassle (I'm fairly new to InstallShield) and I can generate a .exe and .msi from this project.
However the only issue I have left is invoking one of the third-party installers.
That third-party installer (made with NSIS) on its turn invokes another installer which is MSI based.
This results in having error 1500 - the fact that you cannot run a msi type installation while another is running.
I've tried scheduling the CA (that are used to invoke the third-party installers) as the first action and as last, but no success.
Before resorting on the more unorthodox scenarios (like creating a task on Windows Task manager that runs after our installer finishes, or at the next reboot and forcing a reboot - which our customers don't like) or a scenario that we don't bundle the 'faulting' installer (we really like to be able to hand over a single intaller and not multiple), I'd thought I ask your input.
I've tried searching for solutions everywhere on the internet, but either I'm failing due to wrong keywords or I just didn't stumble on the right post yet.
Are there any options left for us to create a single MSI installer that is able to invoke this third-party installer (which invokes a msi installer on its turn)?
Since an EXE bootstrapper is not acceptable, there is only one solution:
store the prerequisite installers in Binary table of your MSI
create some custom actions which extract them from this table and launch them
schedule them in InstallUISequence, for example right before Progress dialog
use searches to detect if the prerequisites are installed or not
condition your custom actions with the search results
Basically, you need to launch them during the installation UI. It won't work if you launch them during InstallExecuteSequence.
I don't think the basic MSI project supports this, but it may be supported by more advanced project types. Other setup authoring tools offer direct support for this.
You can try InstallShield's "Chained .msi Package" feature.

Resources