Tablet UML News


News and commentary (and whatever else catches my eye)
from Martin L. Shoemaker, author of Tablet UML
and UML and Tablet PC instructor for The Richard Hale Shaw Group

Saturday, November 11, 2006

Fun with VS 2005
OK, this is a rather oddball Visual Studio 2005 quirk. Or pair of quirks, really, but they seem to be related. And I won't call them bugs, because I'm not sure they're wrong, necessarily; but they're certainly confusing.

I've been working on a new VS 2005 solution for a while, one that consists of a main app, a control library, and a number of class libraries for logic and data; and often when I rebuild after debugging, I get this message (names changed to protect the confidentiality of the project):


Unable to copy file ‘obj\Debug\ControlLib.dll' to 'bin\Debug\ControlLib.dll'. The process cannot access the file 'bin\Debug\ControlLib.dll' because it is being used by another process.


I looked for some process that might be using ControlLib.dll, but could find nothing. The only thing that "fixed" the problem was to close Visual Studio 2005 and reopen it. That's time-consuming and annoying. For a while, I put up with it; but I wasn't thrilled.

Today, I got a different error. I had added an Ink object to one of my data classes; and that data class was the type of a property of one of my custom controls. Well, when custom controls persist their properties as resources, they rely on .NET serialization for that work. And the Ink class is not serializable. (Thanks, Microsoft.) Since the Ink wasn't serializable, the data class wasn't serializable; and when I tried to rebuild the control library, I got this message:


The "GenerateResource" task failed unexpectedly.
System.Runtime.Serialization.SerializationException: Type 'Microsoft.Ink.Ink' in Assembly 'Microsoft.Ink, Version=1.7.2600.2180, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not marked as serializable.
at Microsoft.Build.Shared.ExceptionHandling.RethrowUnlessFileIO(Exception e)
at Microsoft.Build.Tasks.ProcessResourceFiles.ProcessFile(String inFile, String outFile)
at Microsoft.Build.Tasks.ProcessResourceFiles.Run(TaskLoggingHelper log, ITaskItem[] assemblyFilesList, ArrayList inputs, ArrayList outputs, Boolean sourcePath, String language, String namespacename, String filename, String classname, Boolean publicClass)
at Microsoft.Build.Tasks.GenerateResource.Execute()
at Microsoft.Build.BuildEngine.TaskEngine.ExecuteTask(ExecutionMode howToExecuteTask, Hashtable projectItemsAvailableToTask, BuildPropertyGroup projectPropertiesAvailableToTask, Boolean& taskClassWasFound)


It didn't take me long to remember that I had added the Ink field; but this is a rather perplexing bug at first, because it pops up in an odd place. You would hope that the error would pop up when compiling the data class library; but no, having an Ink field isn't an error in itself, and there's no attempt to serialize the class within the library itself. So you might expect to see the error when compiling the control library; but no, the library only defines the available properties of the control, without assigning them any values, and so never does any serialization. No, the problem occurs when I compile the application that uses the control in one of its forms. That's two steps removed from the actual error. So it took me a while to puzzle through it. What happens is that VS 2005 compiles your forms into resource files, allowing you to substitute other versions for other languages and cultures simply by providing new resource DLLs for each new language and culture. And when the resource compiler tried to serialize the main form which contained the control which contained the data class which contained the non-serializable Ink field, it threw an exception.

But once I fixed that error (I replaced the Ink object with a byte array), I was in the mood to chase down odd quirks, especiall since the "Unable to copy file..." problem kept popping up as I worked on the resource serialization problem. So I copied the error text into Live search, and found a number of references, including this one. It sounds like a very similar problem, if not the identical problem. And here's one suggested answer:


Can you edit the project file for your custom control, and add this line to the top of the project, and see if that causes the file locking issue to disappear? This will be fixed in a later release - but we are interested in finding out if this workaround will fix the problem for you.


<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>


<GenerateResourceNeverLockTypeAssemblies>true


</PropertyGroup>


Let us know what you find.


Note the bolded XML element: GenerateResourceNeverLockTypeAssemblies. Notice that it seems to relate to resource files, just like my earlier problem; and indeed, immediately after that suggestion came this response in the discussion thread:


I tried what you said, but still getting the same error.
We just moved our project from 2003 to 2005. From then i can't build my project from second time.
Getting:
Error 57
Unable to copy file "obj\Debug\XXXX.Controls.dll" to "bin\Debug\XXXX.Controls.dll".
The process cannot access the file 'bin\Debug\XXXX.Controls.dll' because it is being used by another process.


Boy, that sounds familiar...

I note that some of the folks posting about this problem only saw it after upgrading from VS 2003; and I also note that prior to VS 2005, using resources was not the default. You had to make a choice to use them. VS 2005 has added a new tool, ResXFileCodeGenerator, which makes it easier to use resources: it reads them and creates a class in your project which includes easy properties for reading the resources. My suspicion is that this tool is sometimes leaving a file locked, and thus preventing copying over that file.

Note that some people in the discussion thread said the suggestion didn't fix the problem for them; but so far, at least, it seems to be working for me. I'll post an update if I see more problems.