“The operation could not be completed” on closing VS.NET, Round #2 !

Remember my last post on this subject ?
Just to refresh your memory, I’ve come across a strange Visual Studio .NET (2003) + Visual Source Safe (6.0d) problem:
I got “The operation could not be completed” alert every time I’ve closed my solution. Man, It was frustrating, but I think I have a solution for it if you’re using the same versioning mechanism I’m using and that is – “Link File” between your Class Libraries. It seems that the “Link File” option mess the solution\VSS\projects up for some unknown and undebuggalbe(is that a word? no ah…, well, it is now) reason.


The solution is quite simple, remove the linked file and put it in each of your class libraries. I know, I hate this solution too, but at least it will keep the sanity of your solution which is much more important than “1 place”(except asp.net 1.1 project, which don’t support “Like File” option) version holder.


Now I’m “The operation could not be completed” FREE !

 

Automated build for my ASP.NET project using NAnt

As I’ve promised – I share with you my experience with NAnt while attempting to automate my build process for my ASP.NET project. After reading a lot on the subject, I must admit that the documentation is quite poor and the “open source” examples are not exactly what I’m looking for. Before I’ll start, if you don’t know what is NAnt or NAnt contrib, now will be a good time to do some reading, I’ll wait…


Requirements (What do you need to install before you can start):



  1. Download and install NAnt.
  2. Add the nant\bin directory path to your PATH variable (“System Variables”).
  3. Download and install NAnt contrib.
  4. Integrate between NAnt and NAnt contrib using these steps:

    1. Copy nant-contrib\bin\*.dll to nant\bin\ directory.
    2. Create the folder nant\bin\tasks\net (manually).
    3. Copy nant-contrib\bin\*.dll to nant\bin\taks\net directory.

  5. Download NAnt.UtilityTasks.dll and put it in nant\bin directory.

Let’s Start:

OK, now we’re ready to start the build process; So here is my solution structure:


MySolution
   – WebProject (ASP.NET project)
      – *AssemblyInfo.cs
      – Other files and directories (& porno, of course)
   – BusinessLayer (Class Library)
   – DataAccessLayer (Class Library)
   – EntitiesLayer (Class Library)
   – *SolutionInfo.cs
  – etc..


* Before I continue about the process itself, I must mention that I’m using “Link File” option in order to share my AssemblyVersion attribute in my ClassLibraries projects. In a perfect world, ASP.NET projects would be able to “Link File” as well, but (surprisingly) it’s not; So I have 2 places which hold the AssemblyVersion:
1. MySolution\SolutionInfo.cs (This file is being linked in all of my class libraries).
2. MySolution\WebProject\AssemblyInfo.cs.


Great, we can carry on –
I’ve discussed about the proper build process with my friends A&A (The Amir’s aka “The markowitz” and “The Engel”) and we’ve agreed that we require 2 processes – “Build”(complete new version) and “Rebuild”(rebuild the current version, it’s required after the Build process failed for some reason).

The desired processes work flow
:
Note: you don’t need to copycat my process, you’re a free human being, consider me as your Build mentor :-o

1. “Build” process –
   1.1 Increment my build version (SolutionInfo.cs & AssemblyInfo.cs)
         In order to do that, I’m using a great code snippet I found during my last weekend searches to 
         create a new version number. Afterwards, I’m checking-out the SolutionInfo.cs file and imprint the 
         new AssemblyVersion using <asminfo> task.
         Eventually I’m checking-in the SolutionInfo.cs file.

         * I’m using some properties – ${property_name} – for easy maintenance, you can see it in the 
            file I’ve upload (way over down).


   <vsscheckout username=“${vss.username}” password=“${vss.password}” 
      localpath=“${slndir}” recursive=“false” writable=“true” dbpath=“${vss.dbpath}” 
      path=“${vss.slnpath}/SolutionInfo.cs” failonerror=“true” />

   <asminfo output=“${slndir}\SolutionInfo.cs” language=“CSharp”>
      <imports>
         <import namespace=“System” />
         <import namespace=“System.Reflection”/>
         <import namespace=“System.Runtime.CompilerServices”/>
      </imports>
      <attributes>
         <attribute type=“AssemblyVersionAttribute” value=“${build.version}” />
         <attribute type=“AssemblyCompanyAttribute” value=“${company}” />
         <attribute type=“AssemblyProductAttribute” value=“${product}” />
         <attribute type=“AssemblyCopyrightAttribute” value=“Copyright (c) 2005, ${company}.” />
         <attribute type=“AssemblyTrademarkAttribute” value=“Trademark by ${company}” />
         <attribute type=“AssemblyDelaySignAttribute” value=“false” />
         <attribute type=“AssemblyKeyFileAttribute” value=“..//..//..//key.snk” />
         <attribute type=“AssemblyKeyNameAttribute” value=“” />
      </attributes>
   </asminfo>

   <vsscheckin username=“${vss.username}” password=“${vss.password}” 
      localpath=“${slndir}\SolutionInfo.cs” recursive=“false” writable=“true” 
      dbpath=“${vss.dbpath}” path=“${vss.slnpath}/SolutionInfo.cs”
      comment=“change build version: ${build.version}” />


         I use the same code (with minor changes) to update my AssemblyInfo.cs file as well.

   1.2 Put a label on the VSS with the current new version.
         This is even easier, I just use <vsslabel>(NAnt contrib) task:


      <vsslabel
           username=“${vss.username}”
           password=“${vss.password}”
           dbpath=“${vss.dbpath}”
           path=“${vss.slnpath}”
           comment=“New build version: ${build.version}”
           label=“${build.version}”
      />


   1.3 Get the files from the VSS to my local directory recursively using <vssget>(NAnt contrib) task.
      <vssget
           username=“${vss.username}”
           password=“${vss.password}”
           localpath=“${vss.outdir}”
           recursive=“true”
           replace=“true”
           writable=“false”
           dbpath=“${vss.dbpath}”
           path=“${vss.slnpath}”
      />


   1.4 If I’m required to (by property) – generate the projects pdb’s.
        This is great for release mode, I can pull the pdb’s for the version at the Production environment 
        and make some extreme production debugging using the pdb’s as symbols – 
        I must give the credit to “The markowitz” for the idea !
      


        The code is quite simple – build the solution in Debug mode and copy the *.pdb files
        to my “version_directory”\pdb\WebProject.
        You can see the code in the attached file.


   1.5 Build the solution.
         I’m using <solution> task and <webmap> for easy build.
         Again, nothing fancy, look in the attached file.

   1.6 Copy the web project output to my MySolution\Builds\[version_number] directory for 
        an easy XCOPY deployment. I’m using <copywebproject> task in order to do 
        this magic, it’s working like a charm.  
   <copywebproject project=“${slndir}\WebApp\WebApp.csproj” 
      todir=“${outdir}\WebApp” configuration=“${config}” />


   
2. “Rebuild” process – 
      Call steps 1.3 to 1.6.


TIPS:
I recommend that you’ll download VSTweak and let the VS.NET treat your .build file as .xml file.


TODO:
I’m going to add a NAnt task which will get all the *.js\*.htc files from the web project (.csproj) and format them
via Jazmin – this will cut down the size of the files(by removing comments and other not-required characters) for performance improvement (the smaller the file is, the faster the client will download it).


CREDIT:
If you’re using my file as your “template”, I would appreciate if you’ll add a comment and let me know about it, including new features you’ve added or planning to add. I’ve dedicated my time to share with you, please do the same grace with me. Thanks !


My (template) build file:
default.zip (3 KB)

How to run the build file ?
You’ll need to configure the default.build file I’ve attached (5 minutes max).
Go to your solution directory and copy the “default.build” file into it.
Now, activate “cmd” and navigate to that directory.
Type “nant build” and Voila !

 

Nailed you – Cannot copy assembly ‘xxx’ to file ‘path\xxx.dll’. Access is denied.

Hey folks,

I’m sure that all of you encountered this message at least once in your life as a programmer.
Well, I’ve managed to understand and fix one aspect(\scenario) of the beast:

In my project, I have a directory named “References” which holds all my compiled (in Release mode of course) Dlls which are being used as “black box” component (i.e file reference). Because of all these files are in the VSS and I put them as “Solution Items”(easier deployment), they downloaded to my computer as “Read-only” files. So at the first time the solution builds, no problem, The web project can copy those Dlls (they are not exist in his bin directory), afterwards it’s working fine as well (later builds) because there are no changes to this Dlls so the VS.NET simply don’t copy them again (like “he” don’t compile the ClassLibrary if no changes were made, he’s a smart fellow you know).

BUT, in my scenario, I’ve updated one of those “black box” Dll and I tried to rebuild my solution. You can understand from the title that I got this annoying message that it can’t copy the Dll. After I’ve checked a little, I found out the problematic file in my webproject\bin directory is checked as read-only, So I’ve unchecked it, rebuild the solution and it worked faultlessly.


If found 2 solutions for this problem:



  1. Call attrib -r [path-to-web-project]\bin\*.dll on pre-build (Build Event) of any ClassLibrary project; I would’ve put it in my WebProject project but unfortunately it doesn’t support Build Events (why MS, why ?)
  2. Go to your “References” directory and manualy set all the files to *NOT* Read-only.

 

“The operation could not be completed” on closing VS.NET

For some reason, every time I closed my (specific) solution from Visual Studio .NET (2003) the IDE throw an “The operation could not be completed” error. After I’ve tried to open another(different) solution in the same IDE instance, the solution was not bounded to the VSS !
I swear, this is a regular solution structure… nothing fancy;
After digging a little, and talking about it with Amir (aka “The Markowitz”), we’ve come to the conclusion that the solution (*.sln) file have problems with the VSS. It became obvious when I tried to add a file to the Solution Items and I simply couldn’t check-in the new file.


I’ve start googling about “troubleshoot VS.NET log” but no luck, I can’t seem to find a log file which will give me some more data about the “The operation could not be completed” error. I hate the “restart-your-computer” solutions style, but after I’ve spent 2 hours exploring the *.sln files, *.csproj files and tried to reproduce the problem on a different solution(tester), I was getting tired and frustrated.

As last resort, I’ve unbounded the all solution, deleted (permanently) the $/MyProject directory from the VSS and reattached the all solution to the VSS again using the recommended guideline.


Now everything is good, weird ah ?

 

Changing VSS bounded ASP.NET project directory name.

Damn, such a long title… I must take a minute to relax; Done –


I had to change the directory name of my Web project in order to ease my build process.
Well, I must admit, this isn’t an easy task when you don’t remember the steps or you’re too
tired to messing around with it (rule of thumb: gather the required powers, it won’t get easier to adjust it later you know).


So, from my experience here are the steps for changing the VSS bounded ASP.NET project
directory name without killing your VSS\Solution:



  1. Close the solution if it’s open (i.e – close the Visual Studio .NET).
  2. Create the new directory name you want to address the ASP.NET project into.
  3. Go to the IIS (Ctrl + Q -> iis, oh wait, assuming you’ve followed my advice and installed SlickRun) and change the virtual directory path to point to the new directory.
  4. Open the *.sln file with notepad (right-click->open with…) and find “SccLocalPath[number]” which points to your current(unwanted) directory name; overwrite the directory name with the new directory name.
  5. Delete the *.suo file – NOTICE: this is a hidden file so you must check the option to view all the hidden files (OS configuration). This file keeps the user configuration about the solution (like what is my StartUp project\file etc.)
  6. Open the *.sln via VS.NET and you’ll get a window which will ask you to choose the web project path (http://localhost/VirtualDirectoryName_1) – remove the “_1” suffix and click OK.
  7. Delete the old web project directory. TIP: if you’re trying to delete the old web project directory and you’ll get an error that there are files in use – try to delete VSWebCach directory (in your c:\Documents and Settings\[username]) and then try to delete the directory again.
  8. Drink something and relax, you deserve it !

 

DOs and DONTs – Adding a Solution to VSS

Add a new Solution and Projects to the VSS:

 

DONT –

Count on the VS.NET => “Add Solution to Source Control…” to add your solution

and projects to the VSS.

It will create such a mess in the VSS, a mess you’ll find difficult to clean up later on, that you’ll be

sorry for the moment you’ve chosen this option.

In addition, it will not give the desired (and recommended) structure:

 

MySolution

   – MyWebProject

   – MyClassLibrary1

   – MyClassLibrary2

   – …

 

 

DO –

Follow the steps in this great post. I truly believe this link is a MUST

for every developer who’s working with VS.NET and VSS on a daily basis.

 

I hope this will help you all…