English 中文(简体)
System.EnterpriseServices.RegistrationHelper Doesn t Release File
原标题:

We developed a small MMC snap-in that installs various components of the application. In particular, it registers .NET assemblies with COM+ using System.EnterpriseServices.RegistrationHelper. The logic is simple: first, uninstall existing assembly, then copy new file over, then install the new assembly. The code looks like this:

if (File.Exists(destination))
{
   try
    {
       new RegistrationHelper().UninstallAssembly(destination, ComPlusHelper.ApplicationName);
    }
    catch (Exception ex)
    {
        Log.LogError(...);
    }
}
File.Copy(source, destination, true);

However, the File.Copy call fails with the error "The process cannot access the file xxxx because it is being used by another process". I spent a day reading MSDN and googling, but couldn t find a solution.

Does anyone have any suggestions?

问题回答

If the COM+ application is running, it will continue to hold the file open. Any time you want to remove components, you should disable and shutdown the application while removing the component, then enable the application again afterwards.

You have to use the ICOMAdminCatalog or ICOMAdminCatalog2 family of interfaces to do this. Any search engine will turn up numerous examples of doing the following tasks in VBScript. I am not aware of any .NET wrapper projects around COM+ administration.

A flow of the logic that I think is a best practice:

  1. Disable the application
  2. Shut down the application
  3. Monitor and wait for active calls to shut down
  4. Uninstall the component
  5. Enable the application

You can start the application as well, but it should start automatically with the next call to the application.

Each of these steps uses different aspects of the administration classes, and some of them are already solved as individual answers.

Organization

Before you write COM+ administration code, you should understand the hierarchy of the system. Microsoft has this well documented: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687763%28v=vs.85%29.aspx

Disabling

You will need to fetch the Application from the Applications collection. The property to set is "IsEnabled". Don t forget to save changes after changing the property.

Shutting down

Here s a good answer: How do I restart a COM+ application on a remote server from .NET?

It is safe to call ShutdownApplication on an application that is not running.

Monitoring

You ll need to look for the application in the ApplicationInstances collection. If it is not found, then it must have shut down (or was never running in the first place). If it is found, sleep for an acceptable period of time and look for it again from a refreshed instance of the collection.

Uninstall/Reinstall

You ve got this part solved already.

Enabling

The process of enabling is the same as you followed for disabling the application, but with a different IsEnabled property value.





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签