Tuesday, January 06, 2015

Moving to http://www.nullfactory.net


I have moved my blog to http://www.nullfactory.net. The transition is pretty much done and all new posts will be published to the new location.

Enjoy!

Wednesday, December 24, 2014

List of Files Changed Between Changesets in Visual Studio Online using PowerShell

So recently I had the requirement of getting a list of files that changed between two different releases. We wanted to use this list to act as a verification to ensure that all artifacts were included in a release package.

I modified the code posted here in order to quickly write a console application to do the task. With the immediate problem solved, my colleges and I bounced the idea about porting the code into a PowerShell script which would allow us to enhance it better in the long run.

The solution would be built around the Visual Studio Online(VSO) REST service. This reduces any dependency on Team Foundation Server(TFS) specific client side assemblies or tools. The limitation is that, at the moment, it is only supported in Visual Studio Online and not all features are supported.

Pre-Requisites

Security and Credentials
In order make things simple, let's enable Alternate Authentication for access the account. This enables the script to use Basic Authentication when making request to the VSO REST service. This can be done by navigating to the profile page, selecting Credentials > Enable alternate credentials and providing new credential information. More instructions available here.

The credentials will be collected using the Get-Credentials cmdlet. This provides the standard windows credentials dialog for the user to enter information. Since this makes the script interactive, I debated about having the username and password as a parameter for the script, but in the end decided against it. Maybe the next improvement would be to include a silent version of the script.
The REST call
Invoke-RestMethod cmdlet will be used to make the actual call to the REST service. So what's the difference between Invoke-WebRequest and Invoke-RestMethod you may ask? While similar, the Invoke-RestMethod attempts to parse the returned JSON so that we do not have to do it manually within our script. Think of it as a super set of Invoke-WebRequest just like Invoke-WebRequest is a superset of System.Net.WebClient. Read more about it here and here.

I ran into strange issue when attempting to authenticate the request. The
Get-Credentials cmdlet would return a System.Management.Automation.PSCredential object as expected, but when passed into into the Invoke-RestMethod cmdlet, it was not generating the the basic authentication header token within the request. I still haven't figured out why this happens, but the workaround was to add the authentication header explicitly as shown here.

$basicAuth = ("{0}:{1}" -f $username,$password)
$basicAuth = [System.Text.Encoding]::UTF8.GetBytes($basicAuth)
$basicAuth = [System.Convert]::ToBase64String($basicAuth)
$headers = @{Authorization=("Basic {0}" -f $basicAuth)}

Making the call to the service

  1. First get a list of changesets related to the project within the timeframe that we're interested in.
    https://{account}.visualstudio.com/defaultcollection/_apis/tfvc/changesets?api-version=1.0&searchCriteria.fromId=100&searchCriteria.toId=200&searchCriteria.itemPath=$/{project}
    
    It took me a while to figure it out but you should notice this call is only allowed to be made against the entire Team Project Collection. So in order to filter out the project, provide the project path via the searchCriteria.itemPath filter. That is searchCriteria.itemPath=$/{projectname} where {projectname} is the one that you are interested in.
  2. Next iterate through each of the results to retrieve the detailed information on of each of the changesets. This result would include a collection of all the files that were affected.
    https://{account}.visualstudio.com/defaultcollection/_apis/tfvc/changesets/{changesetId}/changes?api-version=1.0
  3. Again, iterate through each of the changes and extract the path property of the json result set. This is the path and name of the file.
  4. Remove duplicates entries and folder creation entries as necessary.

Final Thoughts

You can download my implementation here.

The next steps would make this to its own cmdlet in order to make it more reusable in other scripts. Also check out the Curah! page that I created while working on this.

References

Monday, February 25, 2013

Bind Media Keys on the RC11 Air Mouse within Android

I recently bought a Measy RC 11 air mouse to complement the Rockchip MK808  and one thing I noticed right away was that the media buttons did not function. I guessed it had something to do with key mapping and learned that Android maintains mapping information within key layout files in the  path. My goal would be to edit the appropriate files to map the media buttons to the key codes (scancodes).

I essentially followed the instructions provided here while making slight adjustments to suit my own needs. The only prerequisite being that the device needs to be rooted.

The key layout files themselves can be stored in various locations and Android refers to them in the following hierarchy:
/system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
/system/usr/keylayout/Vendor_XXXX_Product_XXXX.kl
/system/usr/keylayout/DEVICE_NAME.kl
/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX.kl
/data/system/devices/keylayout/DEVICE_NAME.kl
/system/usr/keylayout/Generic.kl/data/system/devices/keylayout/Generic.kl
As Generic.kl file acts as the default file used in the case a mapping was not found, the documentation strongly recommends that we do not modify it.

The first step in the process was to make myself a copy of the Generic.kl using ES File Explorer File Manager. Temporarily rename the copy to Vendor_[VendorID]_Product_[ProductID].kl. The [VendorID] and [ProductID] will be replaced with the proper IDs once identified.  This will be our new mapping file.

Next, we figure out the the scan codes to the media buttons using the the keytest app written by Chris Boyle. Fortunately, the scancodes generated from the RC11 didn’t differ from the generic mapping. I updated it with my preferred mapping:
key 62    HOME
key 63    ENVELOPE
key 64    MUSIC
key 65    MEDIA_REWIND
key 66    MEDIA_PLAY_PAUSE
key 67    MEDIA_FAST_FORWARD
key 68    VOLUME_MUTE
key 87    VOLUME_DOWN
key 88    VOLUME_UP

Now we identify the keyboard vendor id and product id codes. To do this I installed a copy of Android Terminal Server Emulator and used the cat /proc/bus/input/devices command to list the details about the devices attached attached. This contains the vendor as well as the product Id that we require.

The output should look similar to the one below:
I: Bus=0003 Vendor=0c45 Product=7403 Version=0100
N: Name="SONiX USB Device" 

P: Phys=usb-usb20_host-1.1.1/input0
S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1.1/2-1.1.1/2-1.1.1:1.0/input/input9
U: Uniq=
H: Handlers=sysrq kbd event1 keychord 

I: Bus=0003 Vendor=0c45 Product=7403 Version=0100
N: Name="SONiX USB Device"
P: Phys=usb-usb20_host-1.1.1/input1
S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1.1/2-1.1.1/2-1.1.1:1.1/input/input10
U: Uniq=
H: Handlers=kbd event2 keychord
B: PROP=0
Identify your device from the list and rename your previously created file to include the vendor and product Ids. Mine is now called Vendor_0c45_Product_7403.kl.

Now all that remains is to deploy the changes to the /system/usr/keylayout/ path. You would require root privileges to write to this folder. Once file has been copied over make sure that Group and Other entities have read permission on the file, I spent quite a bit of time trying to figuring this one out.

Rebooting the device or re-plugging in the keyboard receiver will cause the new mapping to take effect.

While my experience is specific to the RC11, this process can be adopted to meet your own requirements. I’ve attached my key layout file for your convenience.


As usual, bad things can happen when modifying system files, so please make sure to take all the appropriate precautions as well as backups. I am not responsible for anything you might break.

This has been a very fun learning experience for me. Look forward to more Android related posts from in the future.

References

Saturday, November 10, 2012

TF31003 Error: TFS + Visual Studio 2012 + Windows 8

I think anyone who's worked with Team Foundation Server for significant amount of time has run into this or a similar variant of the (TF31003: Either you have not entered the necessary credentials or your user account does not have permission to connect to the Team Foundation Server at https://***.visualstudio.com/. Ask your server administrator to add the appropriate permissions to your account) error message at least once. I ran into it earlier today while trying to connect to the online Team Foundation Service (http://tfs.visualstudio.com) using Visual Studio 2012 running on Windows 8.

As the error code to be a generic one and covers a wide variety of issues, it took a bit of trial and error before was finally able to narrow down the issue that was ailing me:
http://stackoverflow.com/questions/11034882/tfs-in-visual-studio-2012-under-windows-8

As suggested, clearing all the cookies in IE resolved the issue for me.

Here is another link to the exact problem/solution that I found after the fact:
http://caioproiete.net/en/error-tf31003-connecting-to-tfspreview-from-visual-studio-2012/

Wednesday, May 23, 2012

Bookmark Organizer 0.2 with SkyDrive Integration

I am pleased to announce the latest iteration of Bookmark Organizer. It now comes with the ability to synchronize your bookmarks with SkyDrive. Please read the original post for application pre-requisites and installation.

improvements

known Limitations

  • Synchronization is limited to the root folder of SkyDrive. I might include the ability to choose the location if there’s demand for it.
  • The app is limited to one way synching, its either Device to SkyDrive or vice versa. Source bookmarks are mirrored to the destination.
  • The available sync file extensions are restricted. This is a limitation imposed by SkyDrive. Please read more about it here.

disclaimer

The usual disclaimer applies; I am not responsible for anything you might break by using this application. Please use at your own risk.

download

Please feel free to suggest any improvements and I will try to accommodate you as best as I can.

Monday, May 07, 2012

xsd.exe and included schemas

Today I learned that the xsd.exe tool ignores all xsd:import statements. And the workaround is to explicitly provide all the schemas as command line arguments.

xsd.exe MainSchema.xsd  Reference1.xsd Reference2.xsd

According to the post here, the fact that the W3C Schema spec describes the schemaLocation attribute as a hint, not a true location might be a plausible reason to this behavior.

Monday, April 30, 2012

Visually Differentiate Dynamics CRM 2011 Environments (alternate)

I am a big fan of this hack to visually differentiate CRM environments and have been using it religiously in all CRM environments I have worked on.
I have since found an implementation of for CRM 2011 here. Although it served its purpose, I was not quite comfortable with changing the ribbon styles as it could be a annoyance when designing/implementing ribbon icons. So here is my take on it:
There are 2 files that require modification; main.css.aspx and theme.css.aspx (The theme.css.aspx file only needs to be modified if you want this to work with read-only forms). You can find them both under %programfiles%\Microsoft Dynamics CRM\CRMWeb\_common\styles folder.

main.css.aspx

div.ms-crm-TopBarContainerGlobal
{
/* background-repeat: no-repeat;
background-color: #ffffff; */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ff00', endColorstr='#0100ff',GradientType=1 ); /* IE6-9 */
}

div.ms-crm-TopBarContainerForm
{
/* background-repeat : repeat-x; */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ff00', endColorstr='#0100ff',GradientType=1 ); /* IE6-9 */
}

themes.css.aspx
div.ms-crm-ToolBar
{
<%--<% = this.GetStyleCss(CrmTheme.Current.Form.ToolBar) %>--%>
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ff00', endColorstr='#0100ff',GradientType=1 ); /* IE6-9 */
}

The gradients were generated using CSS gradient editor.

IIS Reset for the changes to take effect.


An here is the end result:
image

image

As this is an un-supported change, you would not be able to implement this in a CRM Online environment. Here is an alternate solution that works well with CRM Online.