I have a setup created with InstallShield. During upgrade or uninstall, after Install validate process, I get a alert dialog box with the following message:
"The setup must update files or services that cannot be updated while the system is running. If you choose to continue, a reboot will be required to complete the setup".
I found the following in the MSI log file:
MSI (s) (4C:78) [18:17:52:182]: RESTART MANAGER: Detected that application with id 4, friendly name 'System', of type RmCritical and status 1 holds file[s] in use.
MSI (s) (4C:78) [18:17:52:182]: RESTART MANAGER: Did detect that a critical application holds file[s] in use, so a reboot will be necessary.
MSI (s) (4C:78) [18:17:52:182]: Note: 1: 1610
I want to understand why I get this message and how to avoid this.
( I already checked the following registry key and it had oldmsedge.exe, I don't think it is related to this issue)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\FileRenameOperations
You can set these properties:
REBOOT=ReallySuppress MSIRESTARTMANAGERCONTROL=Disable
Pending File Renames: The FileRenameOperations key holds a list of files and resources that are waiting to be updated (and / or renamed) upon reboot / restart. This is indeed something that can trigger the warning you see. The setup found files in use that your setup tried to replace, and hence wants to restart the computer to put the new file versions in place after all locks are released (via the restart).
Windows Service: There are many things that can prevent files from being replaceable. One common problem is running services that you don't shut down properly in your setup before trying to replace files that the service has in use. Fix this to have the service in question shut down by your setup. There are mechanisms in MSI to do so (provided the service works as it should - not at all guaranteed).
Running Applications: It is common advice to shut down all normal Windows applications (not just services) that are running when you install a setup. This is to release similar file and resource locks that would cause file overwrite or registry updates to fail.
Other Locks: Files can also be locked by other mechanisms, such as malware scanners, anti virus or similar security processes. Or several other things such as backup mechanisms, ad-hoc locked files opened manually by the user (if the app actually locks the file), ACL permission problems, and worst of all: real malware. And a number of further technicalities.
Restart Manager: Windows has the Restart Manager feature to deal with this problem - files and resources that are locked and can't be updated. It is essentially a way for applications to shut themselves down in a standardized way - via an API (method calls) - so that setups and system processes can instruct the applications in question: "shut yourself down" - and then the system will restart the applications when appropriate.
Technicalities: Advanced Installer - makers of leading deployment software - has a primer on the technical aspects of making your application support the Restart Manager feature. And there is: more on RestartManager here.
Links:
In-use files not updated by MSI-installer (Visual Studio Installer project)
Windows Installer-Avoid FileinUse dialog box when Installing a package
Reboot on install, Don't reboot on uninstall
RestartManager causes worker role to restart
Related
I have a simple msi written in WiX that installs a native NT service. After I have made some changes in the msi it fails at StartServices standard action with the error "service failed to start, verify you have sufficient privileges". If I press Ignore and start the service manually then it start successfully. The problem is definitely not in insufficient privileges. How can I diagnose/debug such issues? The verbose logs of the Windows Installer seem to not contain any helpful information.
The installer won't have any useful information because the error is only surfaced by the installer. Here's how I approach this.
Comment out the ServiceControl element so the installer doesn't try to start the service.
Run installer and all it to finish.
Manually start the service.
If the service starts, this indicates some type of race condition. One common scenario is the service has a dependency on a file being installed to the GAC or WinSXS. The installer puts these files there using the PublishAssemblies standard action. However since the GAC and WinSXS APIs don't support transational installation, PublishAssemblies waits until the commit phase to perform the work. This is after the installer attempts to start the service. Another common scenario would be if you had some custom action that was installing or configuring something that the service needed and you were doing it to late in the installation.
If the service still won't start, this generally rules out race conditions. You have to profile the service itself. Use tools such as depends, ildasm (if .net) and processexplorer (filemon / regmon ) to try to discover what the missing dependencies are. Update the installer then rinse and repeat.
As you've found, the Windows Installer does not provide useful information when it fails to start a service. However, when the dialog is displayed the machine is in the perfect state to determine what is going wrong. So, rather than cancel the install, start debugging. Try to start the service and see if that gives you more information. If not, break out the debugger and go to town.
I basically follow the process described in this FireGiant KB Article. This is the most direct approach to figuring out why the service fails to start. It's too bad the Windows Installer just couldn't provide better messages itself.
When I launch an application, a windows installer from a previously installed program keeps popping up. The program still exeists in the Server and it's working fine. The installer popup, after clicking "cancel" will eventually dissapear.
I'm not interested in solving this problem, I'm just wondering how does the windows installer decides what to install? I mean to say, what's the mechanism? How and who triggers the windows installer?
Thanks for any reply!
This is the self-repair mechanism triggered automatically by the OS. Along with the above enumerated reasons it can also be triggered if:
A feature having been installed as advertised/install on first use/install when required
Files inappropriately shared between components, features, or products, which can lead to the resource being uninstalled while a product is still using it
A product with per-user data having been installed on a multi-user system by one user and then launched by another user
To investigate the resource whose absence triggers self-repair, look in the Application section of the system's event log. Self-repair events are displayed with source "MsiInstaller".
If the installer is indeed trying to add a resource required by another application the best solution would be to let it finish, and it should no longer appear after that.
Usually this behaviour appears when one of the following is true:
the install process was not completed successfuly
the registry entries for this program were deleted / corrupted
(not finding an appropriate registry entry is a trigger)
the install program's updatemanager was corrupted / disconfigured / cancelled on the previous run
The solution usually is to completely uninstall the program, to check that all folders and registry entries were indeed removed and then to re-install the program.
I'm trying to prevent our wix installers from prompting the user for a reboot when uninstalling. Our services are set to be uninstalled and deleted on an uninstall. Unfortunately for us the RestartManager is prompting the user that a reboot will be required during the InstallValidate action. This action occurs well before the StopServices and DeleteServices actions.
Checking the logs, it seems that the RestartManager thinks that our service is a critical process:
"Detected the application with id 1234, friendly name 'abc', service short name 'xyz', of type RmCritical and status 1 holds files[s] in use."
The services are installed and running under the local system account. I'm not sure but I think if RestartManager was returning RmService instead of RmCritical then it wouldnt be prompting for a reboot.
Any help much appreciated.
EDIT:
MSDN states that for RMCritical:
A system restart is required to complete the installation because a process cannot be shut down. The process cannot be shut down because of the following reasons. The process may be a critical process. The current user may not have permission to shut down the process. The process may belong to the primary installer that started the Restart Manager.
The user does have permission to shut down the services, and the services are not anything to do with msiexec so I can only assume that our service is thought to be a critical process.... but why?
You can suppress window's RestartManager by setting the MSI property MSIRESTARTMANAGERCONTROL=
"Disable" (see documentation here - http://msdn.microsoft.com/en-us/library/windows/desktop/aa370377(v=vs.85).aspx). The only problem with this approach by itself is that instead of prompting users with a reboot-required dialog, they will see the file-in-use dialog (and be asked to shut down any applications that might be using those files/services). This dialog is displayed during the InstallValidate standard action of the InstallExecute Sequence.
If you want a sneaky way around either of these dialogs you can schedule a custom action before InstallValidate that manually shuts down any running services before the RestartManager has a chance to inspect the system. This does not follow standard MSI practices because normally you would mark a custom action that modifies the system as a 'deferred' action, but MSI doesn't allow any deferred actions to run before InstallValidate. So, you would have to mark the action as 'immediate', but in the code you would go ahead and modify the system by shutting down the services. The drawback here is that there's no such thing as an immediate rollback action, so if your uninstall/upgrade fails and does a rollback the services you stopped will be left in a stopped state. The upside is that users never have to see any additional dialogs during their uninstall/upgrade.
Ran into this also.
The problem is that the restart manager does NOT think the user has permission to stop the service even though it does because at the time that it checks (InstallValidate), the install has not elevated yet.
My solution is to give the Users group permission to start and stop the service. I used the sc sdset command to change the service permissions.
Or you can use a bootstrapper to start the MSI after elevating.
Restart Manager will not normally prompt for any files-in-use situations for services that are marked to be stopped in the current operation. In other words it goes through the ServiceControl table to see if the service will be stopped anyway, and will not automatically prompt for in-use files.
Unfortunately this behavior was compromised at one time by a bug - only the first entry in the ServiceControl table was checked. I don't know if this bug was ever documented so I can't cite anything. The original question was posted in 2011, so I would assume that this particular issue has been corrected. The only issues of this kind that occur now tend to be situations where the service is multi-process in some sense, or jacketed (some java services are like this) or when the service does indeed stop being a service but the containing process does not complete promptly, or the ServiceControl doesn't do a full wait and it is still in fact running.
I'm adding WMI publishing to a .net framework 3.5 based windows service that is running under the 'network service' account.
According to a document I came across on MSDN, the 'network service' account should by default have WMI publishing permissions. ("By default, the following users and groups are allowed to publish data and events: ... Network Service, ...")
However, when the service calls Instrumentation.Publish(myStatusClassInstance), it throws a DirectoryNotFoundException;
System.IO.DirectoryNotFoundException was unhandled
Message: Could not find a part of the path 'C:\Windows\system32\WBEM\Framework\root\MyWMINamespace\MyService_SN__Version_1.0.3686.26280.cs'.
..so it looks like System.Management.Instrumentation tries to generate code on the fly, and when running under network service it targets a directory where network service has no permissions.
What is the best fix/workaround for this? Can I override the code-gen target dir in app.config or in code? I don't want to have to fiddle around with file system permissions when deploying the service...
Update: I think this is a 'feature' where older FX code clashes with newer security settings in Win7. Internally the WMI managed classes retrieves the WMI installation directory from registry, and uses that as the output path for generated code. Unfortunately a lot of users are not allowed to (or supposed to) write stuff under %SystemRoot%... ...I filed a connect bug (#530392) to see if MSFT can bring any clarity and/or provide a fix or workaround.
Update 2: I'm guessing that for normal user accounts this is not an issue, because UAC virtualization will kick in and store the files elsewhere. However, apparently the 'network service' account is not covered by UAC virtualization..(?)
Update 3: Added 550pt bounty. Simple constraints: .net framework 3.5 based windows service, running as network service, need to be able to publish data through WMI using System.Management.Instrumentation on Win7 and Win2008[RTM & R2] with default permissions/security settings and without resorting to modifying framework internal/private members using reflection. 'Out-of-the-box' but clean solutions welcome. Will open a second related bounty-Q as a placeholder for another 550pt if SO allows.
Bounty update: I intend to double the bounty for this Q through a second hand-in-hand question that will serve as a bounty placeholder:
https://stackoverflow.com/questions/2208341/bounty-placeholder ( <-- Apparently this was not allowed, so the bounty placeholder question got closed by the SO etiquette police.)
Update 4: This gets better and better. I noticed that installutil was writing the missing files to c:\windows\syswow64...etc..., so I realized that I was using the 32-bit version of installutil to install the service, but the service was running as a 64-bit process. The obvious side effect was that code generated when installutil was running ended up under syswow64 (the 32-bit system directory), while the service was looking for it under the 64-bit system directory (system32). (<-- off topic, but I really like how MSFT managed to switch around the names there... :) ).
So I tried installing the service with the 64-bit version of installutil. That failed miserably with permission errors in the %sysroot%\wbem\framework...etc... path. Next I recompiled the service as x86 and registered it again using the 32-bit version of installutil. That resulted in an entirely new exception:
System.Exception: The code generated for the instrumented assembly failed to compile.
at System.Management.Instrumentation.InstrumentedAssembly..ctor(Assembly assembly, SchemaNaming naming)
at System.Management.Instrumentation.Instrumentation.Initialize(Assembly assembly)
at System.Management.Instrumentation.Instrumentation.GetInstrumentedAssembly(Assembly assembly)
at System.Management.Instrumentation.Instrumentation.GetPublishFunction(Type type)
at System.Management.Instrumentation.Instrumentation.Publish(Object instanceData)
at SomeService.InstanceClass.PublishApp(String name) in e:\work\clientname\SomeService\SomeService\WMIProvider.cs:line 44
at SomeService.SomeServiceService..ctor() in e:\work\clientname\SomeService\SomeService\SomeServiceService.cs:line 26
at SomeService.Program.Main() in e:\work\clientname\SomeService\SomeService\Program.cs:line 17
...getting closer...
I believe the problem is not with publishing data, but with registering that type in WMI for the first time.
If you examine the System.Management.Instrumentation code in reflector, or some other disassembler, you'll see that wen the assembly that is about to publish hasn't been registered, then the code will try to register the assembly and save the assembly info in a specially named sub directory under the WBEM installation folder.
I suspect that if you run code to publish the WMI data as an administrator first, it would register the assembly and then the Network Service account would have the permissions to do the normal publishing.
Have you inspected your assembly with the installutil? That should give you a log of the installation issues. (But since you can't run it as the Network Service account, it might not show the problem you're having.)
Also, are you sure this service must be run under the Network Service account?
Because of the vulnerability risk in running Windows services in privileged accounts, Microsoft has made these special service accounts with some limitations, which were strengthened in Vista and Win7. Since Vista, Microsoft has limited the number of services running under this account in favor of less-privileged ones (see this article). The Network Service account (aka "NT AUTHORITY\NETWORK SERVICE") can access the network (acting as the local machine account PCNAME$), but it has reduced rights on the local machine (unlike the Local System account).
Have you checked the WMI security permissions for the branch your assembly is using? Run wmimgmt.msc and dig in... When I did a quick check of some random branches, I could see that the Network Service account did not have write rights.
Lastly, I would suggest using Sysinternals' ProcMon, which would allow you to filter to just that process and see if there are any Access Denied errors in file or registry settings. This tool has solved many problems for me over the years.
Not sure if you raised it or someone else but please have a look:
http://connect.microsoft.com/VisualStudio/feedback/details/530392/wmi-publishing-fails-on-permission-error-please-provide-a-way-to-override-codepath-in-system-management-instrumentation-schemanaming-in-app-config-web-config
This may help you to understand the root cause of the issue better
This is the error that is thrown by our automated build suite on Windows 2008, while running ICEs (after migrating from WiX 2.0 to WiX 3.0):
LGHT0217: Error executing ICE action 'ICE01'. The most common cause of this kind of ICE failure is an incorrectly registered scripting engine. See http://wix.sourceforge.net/faq.html#Error217 for details and how to solve this problem. The following string format was not expected by the external UI message logger: "The Windows Installer Service could not be accessed. This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.". in light.exe(0, 0)
The FAQ is now deleted, however, the text from it said:
In WiX v3, Light automatically runs validation-- Windows Installer Internal Consistency Evaluators (ICEs) --after every successful build. Validation is a great way to catch common authoring errors that can lead to service problems, which is why it’s now run by default. Unfortunately, there’s a common issue that occurs on Windows Vista and Windows Server 2008 that can cause ICEs to fail. For details on the cause and how to fix it, see Heath Stewart's Blog and Aaron Stebner's WebLog.
Additionally, these are the errors that show up in the event log:
MSIInstaller: Failed to connect to server. Error: 0x80070005
Product: [ProductName] -- Error 1719. The Windows Installer Service could not be accessed. This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.
Intuitively:
VBScript and JScript were registered under admin.
Integration service has permissions for the desktop interaction and all the files
Builds succeed, when executed manually on the same machine by another user or even user logged in as integration account (via RDP)
I'm out of ideas so far.
How do I solve this problem while keeping ICE validation?
End of the story:
After fiddling with the permissions of the integration account, DCOM, service activation, etc. without any luck, I finally simply disabled ICE validation in the continuous integration build, while still keeping it in the local build.
To disable ICE validation you can set SuppressValidation to true in the .wixproj file:
<PropertyGroup>
<SuppressValidation>true</SuppressValidation>
</PropertyGroup>
Or pass the -sval command line option to light.exe.
Adding the TFS build controller account to local admin group and restarting the windows service did the job for me.
I found the root cause. I tried everything I found, including custom validator extension similar to one posted in Re: [WiX-users] light.exe failed randomly when running ICEs..
It's not a concurrency issue as suggested in various threads. It's caused by a too large Process Environment Block (PEB).
It turns out Windows Installer can’t handle a process environment block larger than 32 kB. In my environment, due to number of variables set by the build system and their size (for example, PATH variable containing multiple duplicated values), PEB was about 34 kB.
Interestingly, per Environment Variables, Windows XP and 2003 had a hard limit of PEB set to 32 kilobytes. That would probably cause an easy-to-catch build break in an earlier phase of the build. Newer Windows' doesn’t have such limit, but I guess that Windows Installer developers limited their internal environment buffers to 32 kB and fail gracefully when the value is exceeded.
The problem can be easily reproduced:
Create a .bat file which sets environment variables which size exceeds 32 kB. For example, it can be 32 lines of set Variable<number>=<text longer than 1024 characters>
Launch cmd.exe
Execute the batch file you created
From the same cmd.exe window:
Try building the MSI package using WiX with ICE validation on OR
Run smoke.exe to validate your package OR
Simply run msiexec /i Package.msi
All the above commands will end up reporting Error 1719 - Windows Installer could not be accessed.
So, the solution is - review your build scripts and reduce number and size of environment variables so they all fit into 32 kB. You can easily verify the results by running:
set > environment.txt
The goal is to get file environment.txt smaller than ~30 kB.
The correct description (without a solution, except if adding the CruiseControl account into local administrators group can pass as a solution) of the problem:
Quote from Wix 3.5 & Cruise Control gives errorLGHT0217:
ICE validation needs an interactive account or administrator privileges to be
happy. See for example WiX Projects vs. TFS 2010 Team Build (2009-11-14) or Re: [WiX-users] Help with building patch (2009-11-20).
imagi is totally right! I could not believe this is the true answer. Supressing validation and making TFS user Administrator are not good solutions. Plus I could not find NT\Authority to add it to Administrators group and was totally stuck in this.
I got the same error on Windows Server 2012 Datacenter as Build Agent.
To solve the problem :
List item
Go to Environment Variables on the build agent machine
Create two System Variables
"PF86" which is equal to "C:\Program Files (x86)"
"PF" which is equal to "C:\Program Files"
They are so short because I want to save characters.I made them without the final backslash because TEMP, TMP and others were made so and I decided to stick to MS standard for these variables.
Edit PATH variable by substituting every "C:\Program Files (x86)" with %PF86% and every "C:\Program Files" with %PF%
Close and build and enjoy!
It worked for me. :)
UPDATE
I found a better solution : Rapid Environment Editor will do all this and even more for you. Automatically.
I faced the same problem and did not like to suppress ICE validation. My setup: I used my own computer as a build agent on Visual Studio Online (VSO). My solution was to change the account used to run the service on my machine. Instead of using Network Service or Local Service I simply made the service log on with my own account which had all the necessary rights.
From http://wix.sourceforge.net/faq.html#Error217:
In WiX v3, Light automatically runs validation--
Windows Installer Internal Consistency Evaluators (ICEs)
--after every successful build. Validation is a
great way to catch common authoring errors that can lead to service problems,
which is why it’s now run by default. Unfortunately, there’s a common issue
that occurs on Windows Vista and Windows Server 2008 that can cause ICEs to
fail. For details on the cause and how to fix it, see
Heath Stewart's Blog
and
Aaron Stebner's WebLog.
I was getting same ICE error, but the problem turned to be corrupted Windows Installer Service.
This solution worked for me:
http://support.microsoft.com/kb/315353
Log on to your computer as an administrator.
Click Start, and then click Run.
In the Open box, type cmd, and then click OK.
At the command prompt, type msiexec.exe /unregister, and then press ENTER.
Type msiexec /regserver, and then press ENTER.
Restart Windows
Also, verify that the SYSTEM account has full control access permissions to the
HKEY_CLASSES_ROOT hive in the Windows registry. In some cases, you may also have to add Administrator accounts.
I have some suggestions.
Try updating the Microsoft Installer version on the build server
Make sure you use the newest release of WiX 3.0, since it's 3.0 release stable now.
If all else fails, try running the build service under a specific build user who you can fiddle with permissions for...
I got this error from my Azure build agent running on-premises.
My solution was to upgrade its user account from "Network Service" to "Local system account".
Go to your build machine and restart the Windows Installer service
None of the above suggestions worked for me, for me the anti-virus (mcafee) came into the picture and looks like it updated the vbscript.dll registry entry to a wrong DLL location. These are the things to keep in mind:
Some of the WiX ICE validations are implemented using VBSCRIPT.
So while compiling the MSI, the build server would need access to the c:\windows\system32\vbscript.dll.
Chances are that somehow the user that runs your build lost access to this DLL.
As mentioned in the above answers do look for the admin access/registry access and make sure your user has it.
Here are the steps that I took to fix the issue:
Open cmd (run as admin) on the build agent machine.
Run RegEdit
Select the root, then click ctrl + f and Search for the following registry entry : {B54F3741-5B07-11cf-A4B0-00AA004A55E8}
Look for the InprocServer32\Default Key
On my build agent, the path was replaced with a mcafee DLL location. I updated the path back to c:\windows\system32\vbscript.dll
Editing the registry entry was not easy, as it was a protected registry entry. I used the below link to get access permissions changed before I could edit the property: Edit protected registry entry
Once I updated the path, everything started working as usual.
My solution is similar to Vladimir's one. My CI user was admin of the computer.
But the following steps were mandatory to allow my jenkins build to succeed:
log in as CI user using rdp
open a dos command prompt
execute: %windir%\system32\msiexec.exe /unregister
execute: %windir%\system32\msiexec.exe /regserver
then i got a successfull job