I'm writing an installer on NSIS that registers a shell extension.
On uninstall and upgrade, the old extension can't be deleted/overwritten since explorer.exe locks it, and killing-restarting the process is ruled out.
So I extract the new extension with a different name, mark the old extension for deletion (uninstall/upgrade) and rename the new extension to its original name (upgrade only) via PendingFileRenameOperations registry key. So far, this works fine.
The problem is, I have to register the new shell component on startup, since PendingFileRenameOperations only works on reboot. Is there a way to schedule a regsvr32 operation after rebooting?
I can't depend on doing this via a .bat execution on RunOnce, since logging off/logging on also triggers RunOnce operations.
Thanks in advance.
The simplest way I have found to resolve this issue, is to create a registry script that deletes all related registry keys and values. Run the registry script in the (un-)installer, and schedule a "delete on boot" for the COM DLLs. There might be a better way to do this, but I have yet to find it.
Related
Is it possible to get a C++ application running in Windows to request administrator privileges from the operating system at run time?
I know it can be done at compile time, but can't seem to find anywhere whether it can be done at run time.
Thanks for your help!
EDIT: What if I want the current instance to have elevated privileges? For example, I might have data stored in memory which I want to keep.
If you want the application to always elevate, you can give it a manifest, either by building one in (not compiling technically) or by putting an external manifest in the same folder as the exe. If you want to decide, as a person, to run it elevated, you right click the exe or short cut and choose Run As Administrator. If you are launching it from code, then as #vcsjones comments, you use the runas verb when you launch that process. For example:
ShellExecute( NULL,
"runas",
"c:\\windows\\notepad.exe",
" c:\\temp\\report.txt",
NULL, // default dir
SW_SHOWNORMAL
);
You can elevate a process only during its creation. When a process already runs, there's no way to change its security token: it either runs elevated or not.
If your application needs to perform an administrative task, and it usually runs non-elevated, you have to create another .exe which will request elevation with its manifest. To start a process elevated, you have to use ShellExecute or ShellExecuteEx function. From your main process you will need a way to pass the commands to that new process that will run elevated.
For more information about UAC, read Designing UAC Applications for Windows Vista series.
Not quite, but you can do the opposite—you can drop privileges if you already have them. So, you can have your program start out running as an Administrator, using one of the methods listed by Kate Gregory. Then, drop your unneeded privileges; see Dropping privileges in C++ on Windows for how to do that.
Add a manifest file into your EXE as described here.
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Your process (and threads) have a token assinged to them. That token already have all your groups set up. Under UAC, the Administrator group is disabled. UAC will remove that disabled group so you end up with a full administrator token.
To acheive the same, you must have the TCB priviledge. In other words, to elevate a process at runtime, you will need help from a process running under the SYSTEM account, and Microsoft isn't providing one, nor an API to control the current UAC implementation. Otherwise, it would defeat the purpose.
For the sake of completness, there is a whitelist of process that can perform some elevated operations without prompting. In short, your executable needs :
To be signed by Microsoft
To perform predefined operations, like with IFileOperation
The best explanation I found is this hack. It has been fixed since then, but is sheds some light on the whole thing.
I'm looking for a registry key that handles which .dll are loaded on startup of a program. Does such a key exist? For example I add the value example.dll. Now every program loads example.dll on startup. For some reason I think this key exists.
AppInit_DLLs in HKLM is for DLLs that get loaded by every process.
See AppInit_DLLs in Windows 7 and Windows Server 2008 R2
You added " Now every program loads example.dll " . It's impossible to add kind of hook. Even if skills worked, antivirus gonna detect it as malware or PUP.
and i am smelling something bad.
Some installation applications stop (or appear to stop) the normal windows booting. The computer starts, the user logs in and then the installation program starts before others (like Windows explorer).
How can I replicate this behaviour in my own program?
E.g.
OS Boot
Login
The program runs, updates etc.
The rest of the programs run (e.g. windows explorer and what ever runs on startup)
If you want to start an application before the shell starts, you can add a value to the Userinit value in the registry. In this key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
There is a value named Userinit. Change it so your program is run before userinit.exe. For example, to start notepad before the shell/everything else is initialized:
C:\WINDOWS\system32\notepad.exe,C:\Windows\system32\userinit.exe
Use commas to separate the programs that should be started.
This works for Windows XP, Vista, and 7.
I have not tried it but I assume that this is done by the registry entry
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup
There are even more registry keys - see the complete list documented here:
Definition of the RunOnce Keys in the Registry
But for your use case I would recommend to start your application as desktop shell similar to the proposed solution by "vcsjones". When your program has finished you can call explorer.exe to start loading the regular desktop.
You could possibly wrap a windows batch file .bat around explorer.exe
#echo off
something.exe
explorer.exe
But that wouldn't really make sure it's always started before explorer.exe
You could possibly change some registry value to select another 'shell' instead of explorer for that . .
If that is what you are actually looking for.
You should have a look at Windows Task Scheduler. Tasks can be scheduled to execute when a user (specific or any) logs on. The UI provided out-of-the-box by Windows illustrates what can actually be done with this standard Windows feature.
Another solution is to write a Windows service (the .msi Windows Installer is in fact a service).
I'm not sure you will be able to block Windows Explorer though...
Sometimes after I install a program, a window appears on the screen and tells me, "To complete the installation, restart the system".
Now, I just want to know when a program requires a reboot and so my question is:
What kinds of operations does a program do that require a reboot?
One of the most common reasons is if you need to replace files that are in use (such as, say, what Windows Update does), then you have to tell the system to replace it on the next reboot.
Generally speaking, it's to replace/modify files that are in use by the system (and locked), so they can be updated on boot, before they are locked again.
Often when they install special drivers / hooks in Windows itself, like creating a virtual drive with DaemonTools. Either they need to replace files that are in use or a reboot is needed for the program to merge in the OS's inner layers.
The main reason for a reboot is files that in use that the installer could not replace. You can look at the registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\FileRenameOperations and see which files will be removed or renamed after the reboot.
Windows 7 is caching some of the COM class information. Older OSs didn't do this. After the OS looks up theHKCU\Software\Classes\CLSID\{GUID}\LocalServer32 value, it caches the value, and doesn't look it up again.
When we update our software, we place the new updates in a different directory, and then update the HKCU\Software\Classes\CLSID\{GUID}\LocalServer32 value to reflect the new path. The next time the software runs, it will use the latest files if running under older Windows OSs. However, on Windows 7, it will continue to use the older file, until the OS is rebooted.
I ran process monitor, and discovered that under Windows 7, it never reads the registry key again, after the first read. On older OSs, it reads that key every time.
My question is: Is there any way to force Windows 7 to re-read the LocalServer32 information from the HKCU hive each time a new out of proc COM object is created?
I have only been able to solve this problem by...
1: Stopping the Process
2: explicitly unregistering using regsvr32 the library ( or exename /unregserver)
3: Registering the new component
4: Starting the process back up.
I would suspect that it is the Un Reg part that is failing for you. If you are just changing the registry key directly then you should call RegSvr32 /u instead.
Also make sure the new directory location is the current directory when you call RegSvr32.
Note that I have always stopped the process and then unregistered, this is probably a significant detail.
As this is a top result in Google for this narrow-ish problem, I thought it would be valuable to add my troubleshooting outcome for this problem.
I found this response on SO: C# : How to change windows registry and take effect immediately
And linked solution from that answer: Registry Watcher C#
Both of which seem viable options for managing changed keys without forcing a reboot. For us (like the OP) this was when installing updates. For us (possibly unlike the OP) this is infrequent and we decided the effort to implement and test a fix as described was outweighed by the simple solution of requiring a reboot: a process Windows users have come to expect with installing software anyway.