Hi there, I am getting my hands on setup/installer portion of my project. After building my setup(Windows Installer), I have tested on Windows Vista( UAC Enabled), which is also my dev machine. The installation part is fine but when it comes to the uninstallaion an error message pops up saying somthing like (Translated from Japanese;therefore, might not be the exact phrasing of the message in English): "The installation program doesn't have special permission to modify file:<filepath>\<file>."
and then, installer rolls back uninstallation. I have Custom Actions(Detaching SQL Server 2005 Express database ) to be executed during uninstall process. So far as I know, it has somthing to do with the UAC feature of Windows Vista by testing on a UAC disabled mode. I wonder if there is a work around to this problem. Any help are greatly appreciated! I have tried the following attemp with no success: *Add manifest file to the Custom Action binary with
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
The method above does prompt the user during uninstallation but still throws the error..... *Set permission in Custom Action I have set the permissions in the code by following Walkthrough provided by MSDN http://msdn.microsoft.com/en-us/library/d9k65z2d(VS.80).aspx
<Security.Permissions.SecurityPermission(Security.Permissions.SecurityAction.Demand)> _
Protected Overrides Sub OnBeforeUninstall(ByVal savedState As System.Collections.IDictionary)
MyBase.OnBeforeUninstall(savedState)
'My custom code to detach sql database using sqlcommad
End Sub - Edited byCoder Jay Monday, August 24, 2009 5:06 AM
- Edited byCoder Jay Monday, August 24, 2009 6:55 AM
- Edited byCoder Jay Monday, August 24, 2009 5:46 AM
- Edited byCoder Jay Monday, August 24, 2009 5:44 AM
-
| | Coder Jay Monday, August 24, 2009 3:47 AM | Hi Coder Jay, After you handled the OnBeforeUninstall event and add file access security. You can right click that file/folder to view the "security" tabpage on the "properties" dialog. Does "Everyone " "Full Control " right listed there? Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't.- Marked As Answer byCoder Jay Tuesday, September 08, 2009 4:59 PM
-
| | Kira Qian Tuesday, September 08, 2009 5:51 AM | Hi Coder Jay, Do you build the setup in Visual Studio? When you try to uninstall it, do you see UAC popup? After I read you post, I found you have used custom action in your project. Do you try to modify some system protected files in your custom action? Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't. | | Kira Qian Wednesday, August 26, 2009 3:45 AM | Hi Kira Qian,
Thanks again! You have been a great help here!
>Do you build the setup in Visual Studio? When you try to uninstall it, do you see UAC popup?
Absolutely YES. I built the setup project with Visual Studio 2005 Std Edition (You may have figured it out by reading my the other post:-)) Yes, the UAC dialog poped up during unintallation, and I clicked "Allow" button afterwards but it still shows the same message as I mentioned above.
>After I read you post, I found you have used custom action in your project. Do you try to modify some system protected files in your custom action?
Well, the piece of code in my Custom Action does nothing fancy but checking if SQL server service is running at the time of uninstallation, and if it is running then the sql command will be called to detach a local SQL database resides under the installation folder specified by the user. If the service is not running then the service will be started and thenthe local database will be detached.
All of above actions occurs @ OnBeforeUninstall, and then I will have the Windows Installer to take care of deleting automatically. I am using "Service Control" object to detect and start the service.
By my experiments, "Add manifest file to the Custom Action binary" didn't do anything better but prompting UAC dialog again while installer is executing the Custom Actions.
I am getting frustrated with the Vista UAC and File Permissions. Please help me to find a solution on this! | | Coder Jay Wednesday, August 26, 2009 3:16 PM | Hi Coder Jay, You mean the application can no longer be uninstalled due to that error? Oh, that was a bad news if you cannot uninstall it. You need to delete it from application folder and delete the related registry key. If you can uninstall it, then you can put break point in your custom action code to debug when you uninstall it. You can add "System.Diagnostics.Debugger.Break();" to your code. When uninstall, it will popup Visual Studio to let you debug. That can locate the problem more exactly. Hope this can help you. Please inform me the result. Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't. | | Kira Qian Thursday, August 27, 2009 2:04 AM | Hi Kira Qian,
>You mean the application can no longer be uninstalled due to that error?
Yep, that's the problem I am facing right now. I would take it as a critical one because after the error was thrown out Windows Installer is gonna recognize it and start to roll back uninstallation. I have tried the in-the-box 'Repair' feature provided by Windows Installer but the same problem would occur.
>Oh, that was a bad news if you cannot uninstall it. You need to delete it from application folder and delete the related registry key.
Yep, like I just wrote above. It's a unpleasant result I am getting. Fortunately, My application doesn't have to make any entry in the Windows Registry;otherwise, I would end up with a BOD or somthing else.
The walkaround I figured isgo through the following step:
1.Disable UAC feature of Vista
(which isreally "painful" andunpleasant to do,'cuz I amnot going to tell my client like "hey, you know what if you get the UAC feature disabledyou caninstall my application on Vista as well". The security risk is too high to do so.)
2.Reboot the machine
(as required by Vista after disable UAC feature)
3.Uninstall my application via "Add and Remove Programs" in the Control Panel
Please help me! I really need a solution for solving this problem.
>If you can uninstall it, then you can put break point in your custom action code to debug when you uninstall it. You can add >"System.Diagnostics.Debugger.Break();" to your code. When uninstall, it will popup Visual Studio to let you debug. That can locate the problem >more exactly.
Thank you for your advice. I would definitely try it out and post it again! Sorry, I am newbie for debugging the setup project. Would you please tell me where should I insert this line of code("System.Diagnostics.Debugger.Break()") in my Custom Action? Thanks. | | Coder Jay Thursday, August 27, 2009 10:03 AM | Hi Coder Jay, There is one way you can try to uninstall the app. 1. Change that custom action code, comment the code that result in the error. Then rebuild that assembly. 2. Find the folder where your application installed . Replace the assembly that contains the custom action code with the newly built assembly. 3. Try to uninstall the application. When you uninstall the application, it will read custom action code from the new assembly, that won't have error. So you can uninstall it. Here is the hint, when you try to add custom action code in your project, please put all these code into try-catch block . So once the exception occurs, it can uninstall correctly without rollback. Put the code outside try-catch block is not safe . Wish you can take my advice and avoid this kind of situation. Wish you good luck! Please inform me if you meet any problem in doing this. Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't. | | Kira Qian Friday, August 28, 2009 2:37 AM | Hi Kira Qian, I followed the steps above but with no success. I am still getting the same error message. I have literally comment out all Custom Action code for uninstallation , but it still doesn't work. Would you please tell me where should I insert this line of code("System.Diagnostics.Debugger.Break()") in my Custom Action in order to debug the Custom Action code? And also, what steps do I need to take in order to debug with Visual Studio? I know that code without Try-Catch block could end up with a mess, so I have already wrapped up my code with Try-Catch block in appropriate section of the code. I have posted the my Custom Action code for you to examine below. Hopefully, my code would make everything clear.
Imports System.ComponentModel
Imports System.Configuration.Install
Imports System.Data.SqlClient
Imports System.IO
Public Class DetachDB
Dim instNames() As String
Public Sub New()
MyBase.New()
'This call is required by the Component Designer.
InitializeComponent()
'Add initialization code after the call to InitializeComponent
End Sub
<Security.Permissions.SecurityPermission(Security.Permissions.SecurityAction.Demand)> _
Protected Overrides Sub OnBeforeUninstall(ByVal savedState As System.Collections.IDictionary)
MyBase.OnBeforeUninstall(savedState)
GetInstanceNamesbyRegistry()
ServiceController.ServiceName = "MSSQL$" & instNames(0).ToString
Try
If (ServiceController.Status = ServiceProcess.ServiceControllerStatus.Stopped) Then
MsgBox("SQL Server Service is stopped. This service has to be started in order to run Uninstallation." & _
vbCrLf & "Starting SQL Server Service.", MsgBoxStyle.Information, "Warning")
ServiceController.Start()
ServiceController.WaitForStatus(ServiceProcess.ServiceControllerStatus.Running)
ElseIf (ServiceController.Status = ServiceProcess.ServiceControllerStatus.Paused) Then
MsgBox("SQL Server Service is paused. This service has to be started in order to run Uninstallation." & _
vbCrLf & "Starting SQL Server Service.", MsgBoxStyle.Information, "Warning")
ServiceController.Continue()
ServiceController.WaitForStatus(ServiceProcess.ServiceControllerStatus.Running)
End If
Catch ex As Exception
MsgBox("Errorï¼?quot; & ex.Message, MsgBoxStyle.Critical)
Throw ex
Finally
ServiceController.Close()
End Try
Dim sqlConn As New SqlConnection("Data Source=.\" & instNames(0).ToString & ";Initial Catalog=master;Integrated Security=True")
Dim sqlCmd As New SqlCommand("sp_detach_db @dbname = N'HRM_DB'", sqlConn)
Try
sqlConn.Open()
sqlCmd.ExecuteNonQuery()
Catch ex As Exception
MsgBox("Errorï¼?quot; & ex.Message, MsgBoxStyle.Critical)
Throw ex
Finally
sqlConn.Close()
End Try
End Sub
Public Sub GetInstanceNamesbyRegistry()
Try
'Get local SQL server instance name from registry of installed machine
Dim regKey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", False)
If Not IsNothing(regKey) Then
If regKey.ValueCount > 0 Then
instNames = DirectCast(regKey.GetValueNames(), String())
End If
End If
Catch ex As Exception
MsgBox("Errorï¼?quot; & ex.Message, MsgBoxStyle.Critical)
Throw ex
End Try
End Sub
End Class
| | Coder Jay Friday, August 28, 2009 6:13 AM | There's nothing you can do in a new setup that will fix the system. The product is already installed, and when it does the uninstall it uses a copy of your original MSI file that is already on the system.
You have two choices: 1. Do what Kira says. Build an assembly in which OnBeforeUnInstall does nothing at all but call the base.Replace the brokenassembly on the system with this new one and do the uninstall. It will call the new code that does nothing and your uninstall should work. I don't know why you are throwing exceptions in your code. Who is going to catch them? That's perhaps why your uninstall is rolling back.
2. Find the cached MSI on the system and hack it.This is an option if 1 can't work for you.
In future use virtual PC or some other VM software and do this kind of thing in a VM instead of a real machine, then you're not so badly stuck - just revert the VM and start again. Phil Wilson | | PhilWilson Friday, August 28, 2009 10:01 PM | Hi Phil,
Thanks for your reply.
I have tried the first choice that you provided but still gets the error. I guess I have to take the second step to get the package uninstalled but I don"t know where is the cached MSI resides. Can you tell me the exact directory path for the cached MSI?
In addition, uninstall the broken package isn't the only problem that I am facing. I want to get above code/setuppackageto work on Vista as well as XP(Being tested on XP and works fine). Will you point me to the right direction for solving the REAL problem?
>I don't know why you are throwing exceptions in your code. Who is going to catch them? That's perhaps why your uninstall is rolling back.
Well, the reason is simple since the setup project is causing me a lot of trouble, I would like to have it throw exceptions if anything goes wrong during installation or uninstallation for the sake of testing.
>In future use virtual PC or some other VM software and do this kind of thing in a VM instead of a real machine, then you're not so badly stuck - just revert the >VM and start again.
Yep, that's a good idea. It may save my time to get it uninstalled properly, but has nothing to do with solving the REAL problem.
| | Coder Jay Sunday, August 30, 2009 3:07 AM | Hi, For the first question, you can use MSI cleanup utility. Look at this article. http://support.microsoft.com/default.aspx/kb/290301 For the second question, could you please put debug code at the first line of your OnBeforeUninstall method, Protected Overrides Sub OnBeforeUninstall(ByVal savedState As System.Collections.IDictionary) MyBase.OnBeforeUninstall(savedState) System.Diagnostics.Debugger.Break() ... ... End Sub Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't. | | Kira Qian Monday, August 31, 2009 1:46 AM | Hi,
Sorry to bother you again.
I could uninstall the broken MSI by using MSI cleanup utility. Thank you very much.
Well, by implementing the second method for debuging, I found that the error message poped up before the MSI execute my Custom Action Code. In other words, the message poped up during "Preparing for uninstalltion..." stage while Windows Installer is collecting uninstall information.
As it was before, the error message is pointing to the SQL database file(.mdf) and associated log file(.ldf).
By knowing that, I navigated to the application folder and tried delete the files manually, and then Vista prompts a dialog saying that I don't have the access right to the folder. After clicking on the "continue" button(with a elevated right shield icon), I could successfully delete the files.
Does Vista has special file permission on the SQL database file? It appears to me that the Windows Installer has difficulty dealing with SQL database files on Vista.
If it does, how do I set permission for MSI to solve this problem? Thanks. | | Coder Jay Monday, August 31, 2009 5:01 AM | Hi Coder Jay, I think you can try to add permission for "Everyone" using File.SetAccessControl. Looking at the following sample http://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol.aspx Pay attention to this code Sub AddFileSecurity (ByVal fileName As String, ByVal account As String, _ ByVal rights As FileSystemRights, ByVal controlType As AccessControlType) ' Get a FileSecurity object that represents the ' current security settings. Dim fSecurity As FileSecurity = File.GetAccessControl(fileName) ' Add the FileSystemAccessRule to the security settings. Dim accessRule As FileSystemAccessRule = _ New FileSystemAccessRule(account, rights, controlType) fSecurity.AddAccessRule(accessRule) ' Set the new access settings. File.SetAccessControl(fileName, fSecurity) End Sub This method can be called in your custom action before delete action to give a special file "Everyone full control". Pass "Everyone" for the account parameter, FileSystemRights.FullControl as rights parameter, Allow for the controlType parameter. After that I think it will give everyone right to delete the file. Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't. | | Kira Qian Monday, August 31, 2009 8:46 AM | Hi, Thanks for your note on setting permissions. Since I do not explicitly tell the Windows Installer to delete the files, could you tell me where I should call AddFileSecurity() method in my Custom Action? Or which installer method listed belowthat I should use for calling AddFileSecurity() method?
I think we are very close to the solution of this problem. I have tried call AddFileSecurity()in either "OnBeforeUninstall" method or "Uninstall" method but neither works. | | Coder Jay Monday, August 31, 2009 1:40 PM | Umm...It seems like nobody has an idea. I am still "Hunting" for the solution. Please help me with this! | | Coder Jay Tuesday, September 08, 2009 3:30 AM | Hi Coder Jay, After you handled the OnBeforeUninstall event and add file access security. You can right click that file/folder to view the "security" tabpage on the "properties" dialog. Does "Everyone " "Full Control " right listed there? Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't.- Marked As Answer byCoder Jay Tuesday, September 08, 2009 4:59 PM
-
| | Kira Qian Tuesday, September 08, 2009 5:51 AM | Hi Kira Qian,
Thanks for your tips. You pointed me to the right direction of thinking.
All I have figured is that the file in question doesn't have appropriate permission. After granting "Full Control" permission to the user account, I could uninstall the package under Vista successfully.
I think the method you've told me would work just fine. Well, I will definitely give you a feedback on it after employing your method.
By the way, besides adding file access security to the OnBeforeUninstall event handler during uninstallation stage, I could also add file access security to the OnAfterInstall event handler in order to set appropriate file permissions during installation stage. Either way can set the right permission so that the file can be properly handled during uninstallation.
ps. By solving this problem, I realize that:
An account belongs to the Administrators group doesn't give you the power of Administrator(Full control access, ...etc) in Windows Vista as it does in earlier versions of Windows. | | Coder Jay Tuesday, September 08, 2009 4:58 PM | Hi Coder Jay, I am glad you can solve it at last. You are correct, administrator doesn't have full control to all folders/files even in Windows XP/2003. Some folders/files protected by the system doesn't offer permission to administrator groups. Add Everyone FullControl is the way to make sure each groups and users have full control permission. Sincerely, Kira Qian Please mark the replies as answers if they help and unmark if they don't. | | Kira Qian Wednesday, September 09, 2009 1:46 AM | Hi Kira Qian,
Thank you for your tips.^^ Well, instead of assigning "Everyone" account with FullControl, Modify permission is good enough as a solution. By followingthe concept of least privileges needed, I think assigning Modify permission to the account is enough for the user to do the uninstallation properly.
In my point of view, "Everyone-FullControl"may cause some security issues.
Thank you all! | | Coder Jay Wednesday, September 09, 2009 4:23 PM |
|