|
Custom actions can be run at any time, and even in response to user interaction. The problem is that the installer project in VS.NET is EXTREMELY limited unless you know how to manually edit MSI packages - trust me, I know. I've beta tested Windows Installer since before the beginning and also helped beta-test for Wise Solutions, maker of Wise for Windows Installer (the cheaper, easier alternative to InstallShield who allows FULL access to the tables LONG before InstallShield did).
You actually don't need a custom action here, and a .NET Installer custom action can't even help you here (without interop'ing the MSI automation server, getting the current session, and do a whole lot of crap that isn't necessary).
This can be, fortunately, done through the crappy UI. In the solution explorer, select your project. At the top is several buttons. The second to the last one (before the project config button) is the Launch Conditions button. Click it to open the interface.
Right click on "Search Target Machine" and select "Add Registry Search". Give it a name (any name - for your use only) and go to the Properties window. Type in a property name, preferrably in all capital letters (this allows for a secure property which can be passed from the command line to the execution sequence, meaning you could override this value if you wanted to). Select the registry hive from the Root and type the key (exluding the value key name, so just the "directories" that you'd see in regedit.exe) in RegKey. Finally, put the name of key in Value.
One of the first things that Windows Installer does (by default, this can be changed through some order is required for other actions to work) is check launch conditions and perform searches. This will read the value of that registry key into a property with the name you provided above. In the EditProperty# type the name of this property. That's it.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanx again. But I got some new problems, if registry key does not exists, my program just could not be installed, an error notification apperas that "Setup could not continue etc. etc."
Also I want to ask you one more thing:
If I have installed my program, and than in VS.NET I rebuild my project and lunch the msi file again, then error notification appears. In this message I have been told that:
"Setup could not continue because another version of my program was previously installed. Use Add/Remove programs to remove that program"
I guess it happens because I rebuild my Setup project and my build version changed.
So, I want be able to Install, Repair or Uninstall my program just by lunching msi file once again (without removing my program(previous version) through Add/Remove Programs).
It seems to me it would be perfect if I could overrid some function that allows me to UPGRADE my programm....
Thanx again for your advises.
Excuse my English
Regards, Alex.
|
|
|
|
|
dotnetdev@univ.kiev.ua wrote:
I guess it happens because I rebuild my Setup project and my build version changed.
No, it's because your installer version did NOT change. Windows Installer has full upgrade support built in to its core, but it isn't automatic. First, in your project properties set RemovePreviousInstall (or something like that) to true. Also, between versions change the Version number appropriately (it's only 3 numbers, not 4 which really isn't supported anymore for MSIs), be it a release, minor, or major version number change appropriate for your changes to your application. The file versions are only used when Windows Installer determines if a file should be overwritten (well, it's one way). When you change the project's version number, you're asked if you want to change the product and package codes, too. Click Yes. Your UpgradeCode remains the same so your product is still associated between versions, except that only one package with the same product code can be installed at a time. That's where your error is coming from.
That registry solution I told you would not produce an error. It would leave your property undefined (so you could actually use that in a launch condition by putting just the property name in there. If it was set, the condition is true; if it wasn't set, the condition is false). Something else is causing it. A better description of the error that doesn't include "blah blah" would be far more helpful.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Unfortunatly I did not find any property like RemovePreviousInstall or something else in my project options. Could you please tell me where I can find this option more detaily.
So, when I installing my program by launching msi file product installed correctly. And when I rebuild my Setup project and try to Install it one more time by lunching new (rebuilded) msi file again message with following text appears:
"Another version of this product ia already installed. Installation cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel"
And when I remove my program through Control Panel, and then instlling again from new(rebuilded) msi file all goes well. Can you tell me if there possible to remove my program just by lunching new(rebuilded) msi file, that no message appears, and I'll not have to remove old version through Control Panel.
Thanx.
|
|
|
|
|
thanx for your advise with Registry Search it works!
But now other problem occured: In Registry I keep value as string "User=www" and if I trying to get value from Registry through Registry Search it returns me "User=www" in my TextBoxex(A) form textbox value. And I want only "www" as my TextBoxex(A) form textbox value. So could you tell me how can I parse vlues from which I recieve from registry?
|
|
|
|
|
You normally don't store registry values like that. A much more common practice would be to name the key "User" and set the corresponding value to "www". Windows Installer has its limitations. If you insist on storing your values this way, then you're responsible for having to parse them and there's not an easy way of doing it. The only way possible would be to write a custom action (in C or C++, it'd be difficult and too inefficient to do so with a .NET Installer class) that gets a handle to the current session, gets the property and splits it into new properties, all before the dialog is displayed. Then you'll need another one to put them all back before the WriteRegistryValues action.
All this would also require manual hacking of the MSI since the VS.NET installer project will be of no help and won't let you do things like this. It is not meant to be a commercial deployment replacement.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Looking, it's RemovePreviousVersions. Honestly, it shouldn't have been that ellusive, should've it?
Again, set that aforementioned property to true and make sure you increment your Version number. Trust me, it will solve the problem if you do it right. The VS.NET installer project makes this easier, though it's not hard even if hacking the MSI itself with Orca or something that I use a lot. Just make sure you NEVER change the UpgradeCode unless you really know what you're doing, since you'd have to hack the MSI to fix it.
When you install the newer version, the older one is removed automatically in a transacted process, so that any critical failures leave everything the way it was before you tried to install.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Well, I opened my Install project and I go to the Project->Properties and I just could not find any RemovePreviousVersions option...
Where is it?
|
|
|
|
|
Select your project then look at the Property Grid found in the bottom-right corner of VS.NET by default. There's lots of properties there, including RemovePreviousVersions that's been there since VS.NET 2002.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
THANX A GREAT! It's interesting to me how do you know all these stuff? You must studuing during 24h a day?
|
|
|
|
|
I love to learn (and by learn, I mean to truly understand) all that I can about many things, especially application development. It's a never-ending process.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi,
Just a quickie. I have created a flashy interface using Picture Boxes as buttons and want to have them make a 'click' sound when pressed for user feedback. Is there a simple call which I can use? Or any piece of code to do the job,
Regards,
John
|
|
|
|
|
See http://www.codeproject.com/cs/media/windowssoundevents.asp[^]. Just find the key for the navigation sound in the registry (the article mentions where in the registry to find these events) and call PlaySound (as documented in the article) with that key.
Support for system sounds will be added to the FCL in .NET 2.0 due out in early 2005.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
How I can show the contents of the control PC to other clients in the LAN?
|
|
|
|
|
If you're using Windows XP, click on Start-<Help and Support. There is functionality to view existing Windows sessions already built into Windows XP, along with an invitation system. You could also install VNC (free download from the web - just google to find it) which allows you to connect to existing sessions, IIRC, but the Windows Remote Desktop Client won't work because it starts a different terminal session with each connection so they won't see your desktop session.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'd like to create a form that contains a number of controls that can be moved, and behave like forms. Similar to the Access relationship view. I've figured out that I need to do the following:
* External Form style border
* Move function upon mouse down on header (thick title bar in forms).
* Resize function upon mouse down on sides or base.
* Lock mouse pointer internal to form when moving object.
I was looking to set the border style to form, and then hoping that the header and side parts of the border could be used to fire events.
As for the mouse, i was looking at tying the mouse handle to the inside of the form, but i'm not sure how to do it, and the thought alone makes me wonder what could go wrong.
So i'm not sure how to go about this, does anyone know where to begin?
Cheers
Cata
|
|
|
|
|
One way is to implement .NET's drag and drop features for controls. I've mentioned this several times in the forum, so try a search. Just use some custom clipboard format (like ".NETControl" or something) and you can reposition controls that way.
You could also handle the MouseDown event and mark a flag. In the MouseMove event update the control's Location as you move if that flag is set. In MouseUp , reset the flag so that just simply moving the mouse doesn't move a control when your mouse passes over it.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
[EDIT: Ah, did a google search for drag drop controls, and got a working example. It's perfect. Only problem I have now is figuring out how to implement a Form style border on a control. If you can offer any help into that, i would be grateful]
Ah, thanks for the ideas Heath.
The second one would cause problems with moving the mouse outside the area, and while i could lock the box to the perimiter, it would still look unproffsional.
How does this work with object borders?
I've tried a bunch of searches, but still haven't found anything. Sorry to be a pain, but i've done a whole bunch of permutations of Move, Control, Controls, Drag, Drop, but come up empty handed.
Cheers
Cata
|
|
|
|
|
Ok, I have the Drag Drop working, but i'm interested in a couple of other things.
How can i stop the mouse pointer from leaving the form / control / container while in the process of dragging?
How would i configure a form type border on a control? I know they are sperate objects, but i've no idea where to start to set them up. Not sure what i'm looking for in google tbh.
Cata
|
|
|
|
|
See the Capture property. It won't stop the mouse from going outside the bounds of the container, but you can always stop the control from moving further through various means. I'm sure stopping the mouse is possible and, IIRC, have seen it done but I'm really not sure how and am sure it requires a lot of low-level notification message handling, perhaps even app or sys hooks.
You could, through quite a bit of work most likely, detect when the mouse is over a border (within a certain threshold) of a control and change the mouse cursor appropriately. The Mouse* events could be handled the same way as I mentioned in my previous post, only you would change the Size property (remember, you must create a new Size object since its a value type, or just change the corresponding properties of the control).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Ok, i'll look into that.
What about borders?
I've made something that looks like a 12 year old could do better. But it can detect when you select the header part, and the 4 side bits when the mouse is over them, change to resize arrows and can be re-sized.
The centre has a filled panel that is the content. It's really a sloppy job that isn't fully working yet. How would I make a windows type form with smooth corners?
|
|
|
|
|
See the ControlPaint class, which has several helper methods for drawing borders given a certain Rectangle (bounds).
As far as actually showing the control while dragging, you'll have to do what I mentioned before with the mouse events. This is pretty much what designers like VS.NET and SharpDevelop do, at least to some degree. Designers are also not magic - the controls themselves are instantiated and painted at runtime with various design-time decorators.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I found this article if you are interested. I'm going to go and try and implement it in C#, but it's something for you to add to your knowledge base:
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q179/1/92.asp&NoWebContent=1
(What's the tag to set it up as a link?)
|
|
|
|
|
Don't bother. After I noticed that all but one function that was declared in VB already exists in the .NET FCL (like Control.PointToClient ), I thought I'd look at the Cursor class and sure enough, there's a Clip property that takes a Rectangle that defines the clipping rectangle, in screen coordinates (so use Control.RectangleToScreen from your Control to get it's bounds in screen coordinates).
Ahh, the power of cheese research.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
ARG! I was so proud of finding that :P
Oh well, to bad.
Just the Form border thing to figure out now. Is there any Control that represents a forms border?
(hmmm... cheese...)
|
|
|
|
|