Detect software uninstallation on Windows - windows

I would like to log the uninstall event onto my own web-server for my desktop application. Is there a way I can detect the uninstallation on Windows?

Your installer override the Installer.OnAfterUninstall method
http://msdn.microsoft.com/en-us/library/system.configuration.install.installer.onafteruninstall(v=vs.100).aspx
There, you can call back to your web server.
Be sure to program for the possibility that there is no internet connection at the time of uninstall. Also, note that some firewalls may block your attempt to connect to your server from the uninstall program, or prompt the user for permission to allow the connection.
If you are using an installer other than Microsoft's (e.g. NSIS or whatever) for the desktop application, there is probably a similar hook.

Related

Choose right Windows directory to install software and allow auto-updates

We are writing an installer for our Windows tool. As our tool uses an updater (wyUpdate) and we want that users WITHOUT Administator rights can performs updates. Which is the right directory to install the app to? The standard C:\Program Files requires Administrator rights, so we have discarded this option. After reading a bit on the Web, we have chosen AppData, i.e. C:\Users\USERNAME\AppData\Local.
Is this best practice? Or should we use another directory?
If you do not want to allow your users to mess with the installed program, you have to install it to a folder that needs Administrator privileges.
To allow an automatic update of such application, you need to develop/install a service that runs with Administrator privileges, which will update the installation. This is what Windows Update, Mozilla Maintenance Service, Google Chrome Elevation Service, Adobe Acrobat Update Service and similar services do.
If you do not want to implement a service, but you want the application to be used by all users of the machine, you need to install it to a folder that can be accessed by all users, yet does not need Administrator privileges. You can for example use C:\Users\Public. See also Is there a shared folder in Windows to which non-elevated users have write access?. You can use PUBLIC environment variable to resolve that path.
If the application is to be used by one user only, then you are ok with using C:\Users\Username\AppData\Local – {userappdata} in Inno Setup.
Related question: Deploying application with .NET framework without admin privileges

Why does the setup for my ActiveX .exe hang up when "Setup is updating your system"?

I am currently trying to install my vb6 app on a Windows 8.1 computer via TeamViewer (it's kind of like remote desktop). However, the installation always hangs up after all the files are copied and this message is displayed:
Setup is updating your system
We've tried it on our own Win8.1Pro desktop (via Remote Desktop this time) and Win2008Server(both via Remote Desktop), and it installed just fine.
Right now, we've narrowed it down to one culprit - MyProjectInfo.exe the actual ActiveX .exe. Whether it is me trying to run the .exe for the first time to register it to DCOMCNFG or whether it is the setup.exe running the script $(EXESelfRegister) it just freezes up.
What differences should i look for between 1) our win8.1Pro and win2008server and 2) their win8.1? If it some coding/reference/dependency issue, what could be the cause for why it doesn't error in our desktops?
Thank you for all the help.
Uhmm... this is getting embarrassing.
Avast (present in the other person's Win8.1) was blocking MyProjectInfo.exe from running (which is basically what is does with $(EXESelfRegister).
To properly proceed with registering my ActiveEXE program, I had to turn Avast off for a while. And that was that.
This problem may also occur with other anti-virus scanners as well.

Porting serial daemon + PHP to Windows

I have a Linux system with:
a daemon that communicate with another device via RS232 port.
a php + javascript web site that talks to the daemon through a
socket.
Now the boss wants to find out how much of an effort is required to port all these onto Windowze.
Having never really programmed on Windows before, I'd like to ask how easy/hard this is going to be and what the options are.
Thanks,
PHP will probably run as is. Javascript runs in the web browser, and will run as is. Your daemon is a service on windows. Apparently it listens on a socket for commands from the web page via javascript.
You did not state what language you are targeting for the service. Some languages such as C# dot Net, have built-in libraries for making clean services that can pause, stop, start, and interact with the Windows Service Control system. C# would be a good choice to make a service that can install and remove itself easily, and it supports nice high level socket control to listen to the PHP and javascript code. I have used perl, C#, C++, and even Visual Basic running as a service, so the choice is yours.
If your choice of Windows language is that compiles to some .EXE, then a low-level way to add a service is as follows. You will need INSTSRV.exe and SRVANY.EXE, which come on the Windows Resource Kit, or can be downloaded easily with a quick web search.
The short version :
After you get the server runnign when you are logged in and debugged, install the APP server as normal to the C:\Program Files\APP directory. This would be the app that connects to the serial port and does what you want via sockets.
Copy instsrv.exe to your C:\WINDOWS\system32 directory/
Copy SRVANY.EXE to C:\Program Files\YOURAPP
From command prompt, run this command – INSTSRV YOURAPP "C:\Program Files\YOURAPP\srvany.exe"
Run the Registry Editor (REGEDT.EXE)
Under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\YOURAPP: create a ‘Parameters‘ key (folder)
Under the this key, create a REG_SZ string value called Application and add in this data C:\Program Files\YOURAPP\YOURAPP.exe
Close Regedit, then open the services console in administrative tools, or start, run, services.msc, confirm it is set to start automatically and the logon account is LocalSystem. Then unclick the Allow Service to Interact with Desktop. If you click this, it will interrupt you on Windows 7 boxes whenever it writes to the screen.
Start the service, check in Task Manager, you will see YOURAPP.exe inthere, and if you stop the service then YOURAPP.exe will disappear.
The long version
Details on this are at http://support.microsoft.com/kb/137890

Where should I store shared resources between LocalSystem and regular user with UAC?

My application consists of two parts: A Windows Service running under the LocalSystem account and a client process running under the currently logged in regular user.
I need to deploy the application across Windows versions from XP up to Win7.
The client will retrieve files from the web and collect user data from the user.
The service will construct files and data of it's own which the client needs to read.
I'm trying to figure out the best place (registry or filesystem, or mix) to store all this. One file the client or service needs to be able to retrieve from the net is an update_patch executable which needs to run whenever an upgrade is available.
I need to be sure the initial installer SETUP.EXE, and also the update_patch can figure out this ideal location and set a RegKey to be read later by both client and server telling them the magic location (The SETUP.EXE will run with elevated privileges since it needs to install the service)
On my Win7 test system the service %APPDATA% points to:
C:\Windows\system32\config\systemprofile\AppData\Roaming
and the %APPDATA% of the client points to:
C:\Users\(username)\AppData\Roaming
Interestingly Google Chrome stores everything (App and Data) in
C:\Users\(username)\AppData\Local\Google\Chrome
Chrome runs pretty much in exactly the way I want my suite to run (able to silently update itself in the background)
What I'm trying to avoid is nasty popups warning the user that the app wants to modify the system, and I want to avoid problems when VirtualStore doesn't exist because the user is running XP/2000/2003 or has UAC turned off.
My target audience are non-tech-savvy general Windows users.
Chrome doesn't have any services running under the LocalSystem account, though.
If you want to have files that can be shared between accounts on the same system, store them under the %ALLUSERSPROFILE% folder.
If you just want to be able to auto-update programs, then doing what Chrome does is fine: just make sure you launch the updated elevated when UAC is turned on.

Starting a Windows service in an interactive session

A colleague has a batch script program which needs to to run on a Windows Server in console mode, so that it has access to a Windows interactive session. The server is rebooted at regular intervals automatically (there's an unrelated closed-source application that runs on this machine that we have no control over). After a reboot he wants to automatically start a Windows interactive session and have this script run, plus the service needs to also have access to network resources (CIFS drives, in particular).
Here's what we've tried so far:
Start as Windows service. This failed, since a Windows service can either have access to interactive session or to network resources, but never both.
Used Microsoft management console to add the script to run at startup, however this did not work.
Used an HKLM registry key to start to run this script, however it only gets started when we manually open a remote desktop session on the server.
Creating a scheduled task. The program invoked did not have access to interactive windows session.
Any other suggestions? (Or maybe he missed something when he set up one of these suggestions?)
In case "Interact with desktop" on the service is not enough (I have seen a handful of cases where it is not), you can combine it with AutoAdminLogon. Create three (or four for a domain) REG_SZ values under HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon:
DefaultUsername
DefaultPassword
DefaultDomain
AutoAdminLogon
AutoAdminLogon should be set to the string "1", the others are self-explanatory.
Obviously this has security issues big enough to fly Jupiter through.
Have you tried having your script run as a Windows service, but allowing it to interact with the desktop?
Specifically:
Go to the service properties page
Click on the "Log On" tab
Select "Local System account"
Check "Allow service to interact with desktop"
See my similar question and real answer to it: How to start a process from windows service into currently logged in user's session
NOTE: "Interact with desktop" checkbox is not enough at all.
I recommend going about this another way. You could build another Windows app that communicates via IPC to the Windows Service and that could be what deals with the closed souorce application. But if you must, you can specify an option in the service (you can do this through MMC, registry, etc). Basically, you can see this option by going to Computer Management->Services and Applications->Services->Right click your service->Change account to Local System and check "Allow system to interact with desktop."
However, again, I recommend choosing another path.
I had to do something similar recently; a route that I found but discarded due to security concerns is to have the interactive service set self as running in interactive mode and then run the ImpersonateUser function in the win32 API, which I think will provide the benefits of both a user and the interactive session available from the LocalSystem.
Needless to say, if someone broke into a service that did that, they would have total control of the machine.

Resources