Wednesday, September 2, 2009

Stuff you forget about AppDomain

I was working with a co-worker and getting a PowerShell script to call into a WCF service. We had to use svcutil.exe to create the proxy then compile it via csc.exe – he wanted to do everything from a PowerShell script.

When it came time to run the script which would call a WCF service we kept getting errors. One of the features of a .Net executable is that if you have configuration settings in the app.config, they get loaded up for you at run time. If you’ve worked at all with WCF then you know it is configuration heavy!

We needed to get our app.config settings loaded into PowerShell so we wouldn’t have to programmatically configure the bindings, etc. I’m new to PowerShell so we did some digging around and found that you could use the AppDomain.SetData method. Here’s how…

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "path to config file");



If we call that before we load our assembly into PowerShell, our configuration for the WCF service is loaded properly and we can call the service without any errors.



Enjoy!

Wednesday, January 28, 2009

Do you know what TFS is doing?

By default you won't. But you can easily change that! Go to your application tier and find where the TFS web services are located. Typically this will be

%PROGRAM FILES%\Microsoft Visual Studio 2005 Team Foundation Server\Web Services

Open the web.config file there and find the setting for "commandLogging."

        <!--  WEB METHOD LOGGING
Specify web method logging behavior. The default value is 'None'. Valid
values and their meaning are:
None (Never log web methods)
OnError (Include web methods that encounter errors)
ReadWrite (Include web methods that change database(s))
Normal (Above, plus web methods that don't change database(s))
LightWeight (Above, plus web methods that have minimal database access)
All (Above, plus always include web method request details when avail.)
-->
<add key="commandLogging" value="None"/>


Now change the value from "None" to "Normal" and logging is enabled. Swell, but how can we see the log? You have to use SQL Management Studio (or the sql command line). So, fire up SQL Management Studio and connect to your TFS data tier. There is a database appropriately named TFSActivityLogging - that's where all the logging happens. Use the following SQL to read all the logged activity:



select *
from tbl_command



You'll get the following columns:




  • CommandId - identity column


  • Application - which TFS application handles the web service call


  • Command - which web service command was issued


  • Status - uh...status.


  • StartTime - when the command was called


  • ExecutionTime - how long the command took to execute


  • IdentityName - name of the identity who issued the command


  • IPAddress - the IP address of the identity who issued the command


  • UserAgent - the user agent string of the executable that invoked the command. For example, you'll see values containing devenv.exe which corresponds to Visual Studio.


  • UniqueIdentitfier - GUID used to correlate multiple records. There are some commands, like check-in, that cause multiple web methods to be invoked. Nullable.


  • CommandIdentifier - name of the command line tool invoking the web method. Nullable.



Now you'll know what is happening with your TFS and who is requesting it. Enjoy!


Monday, January 5, 2009

Optimizing the build

Continuous integration (CI) is great. You get quick feedback regarding the health of your code base. One of the tenets of CI is to keep the build fast. This seems easy but can get out of hand if you have a lot of projects to build as part of your solution. If you are using TFS build then you are in luck.

After creating your build definition, open up the TFSBuild.proj file and add the following elements as children to the <Project> element:

<PropertyGroup>

  <SkipClean>true</SkipClean>

  <SkipInitializeWorkspace>true</SkipInitializeWorkspace>

  <ForceGet>false</ForceGet>

</PropertyGroup>

These settings will speed up the build process in the following ways:

  • the build will not delete the files from the last build (SkipClean)
  • the build will not initialize the workspace, which would create and synchronize files with the folder structure associated to the workspace of the build (SkipInitializeWorkspace)
  • the build will not get all files - it will only get the files that have changed (ForceGet)

Now, these setting are not for every build definition. Sometimes you want to start clean and make the build. I'd set these for the CI build but leave them out for the daily build. You do have a daily build, eh?

Friday, January 2, 2009

Size Matters: WorkItem Attachments

Workitems in TFS have a handy feature that allows you to attach files to them.

workitem_attachments

Notice the size column? It's not obvious but there is a size limit to attachments. The default setting is to allow documents less than 4 MB.

Great, but what if I need to attach a document that is bigger than 4 MB? Believe it or not this can happen quite easily if you have an big ol' image or some documentation that was kept in one single Word file. If you need to increase the attachment size you can make a call to the handy ConfigurationSettingsService web service. Here's the URL:

http://your.tfs.server:8080/WorkItemTracking/v1.0/ConfigurationSettingsService.asmx?op=SetMaxAttachmentSize

You'll need to access the machine that is running the App Tier of your TFS installation, usually by remote desktop. Then enter the URL in your browser and you should then get a page like this where you can enter the new maximum size in bytes and click "Invoke":

SetMaxAttachmentSize

Oh yeah, you need to be a member of the Adminstrators group on the Application Tier.

Now you can't just set it to any value - there is a maximum value of 2 GB that can't be exceeded. If you try to set a value larger than 2 GB you'll get this error:

System.Web.Services.Protocols.SoapException: TF51316: The maximum attachment size exceeds the allowable maximum of 2000000000 kilobytes. Upload a smaller file, or change the maximum value for the work item attachment size. 
at Microsoft.TeamFoundation.WorkItemTracking.Server.ExceptionManager.ThrowProperSoapException(Exception e)
at Microsoft.TeamFoundation.WorkItemTracking.Server.Global.WebMethodExceptionHandler(Exception e)
at Microsoft.TeamFoundation.Server.TeamFoundationWebServiceBase.HandleException(LogRecord requestRecord, Exception e)
at Microsoft.TeamFoundation.WorkItemTracking.Server.ConfigurationSettingsService.SetMaxAttachmentSize(Int64 maxSize)


Just remember that this setting changes it for all projects. So now we can increase the attachment size to let us upload that 800 MB Word document. Awesome.



Enjoy!