I thought this was an interesting post that Robert Scoble did on the building 43 site with a startup that allows you to build a kinda “Virtual Conference Hall”. Pretty interesting stuff.
I see more and more conferences being streamed realtime, Mix, PDC, ETC. With all those being streamed online, I’m wondering what the future of these big conferences are? Are they more like meet ups now?
Recently I was playing around with Citrix WorkFlow Studio 2.0. Specifically I was writing some custom activities to help with data connections, etc. Before I get into the tech contents, lets provide a little background on WorkFlow studio and how we can extend it with our own code. If you want to see an brief unabridged of WorkFlow studio click the link below. You can also check out the Citrix site here
Click here to download the Workflow Cache Cleanup Utility
WorkFlow Studio Overview (Click me to expand the overview)
The interesting thing about WorkFlow Studio (because its built on Windows Workflow Foundation) is that you can write your own activities and make them available for use in other activities and allow other users of WorkFlow Studio to use them as well.
So, developing your own custom activities is certainly an iterative process, write some prototype code, deploy it to the GAC (Global Assembly Cache), test the results. Rinse and repeat
.
While doing this, I noticed a interesting thing happening. I would deploy my test activity to the GAC, then I would add it to workflow studio. All is peachy
. Then i would remove it from the GAC, but it would still show up in workflow studio. This was puzzling me. WorkFlow Studio must be caching the information somewhere!
I dug around a little, but couldnt really pin point where this was happening, so I figured, go right to the source
, so I shot an email over to Pete Shulz, Product Manager for WorkFlow Studio (you can follow him on twitter at http://twitter.com/schulzpm)to see if caching was indeed happening. Well, Pete did inform me that WorkFlow Studio does indeed cache previously added components. He also pointed me to this articles up on the Citrix Developer Network, which explains it in more detail.
(http://community.citrix.com/display/wf/Tips,+Tricks,+and+Best+Practices)
I thought this was good, but I didn’t really want to dig around in files every time I wanted to clean up my orphaned activities, so, like Tim Allen, I wanted more power!! What I wanted was a quick little utility that i could run that would list the cached activities and then allow me to selectively delete the ones I wanted to. So, I had some extra time last night so figured I would through something small together. that’s what I build. You can download the app here. Its not a pretty app, but it does get the job done. NOTE: Before we modify anything in the config file we always make a backup of it. Those backups are located in the “C:\Users\John\AppData\Local\Citrix\Workflow Studio\WorkflowStudio\2.0.0.0’ directory and will have a “Backup” prefix to the file. Like the following screen shot.
Initial loaded screen. It lists your currently cached activities. Here we show you the name, assembly name, weather or not it is shown in the toolbox, and what the toolbox path is (this is where you can find the activity in the activity folder structure)
Once the activities are loaded, you can them multi-select activities and right click, from the popup menu, you can then choose to delete the selected from the cache.
So that’s it for this article. You can download the app from here, but remember, I provide this only as a utility, because I use it during my development process. Please use this tool at your own discretion.
As always, you can contact me via this blog, or ping me on my twitter account (http://www.twitter.com/johnmcbride)
Tags: citrix, Citrix WorkFlow Studio, WorkFlow
Recently the the Microsoft AJAX team released Ajax Preview 6 up on codeplex (Check it out here). With this release they also released an Ajax Minifier tool that will allow you to crunch or minify JS files. There are several ways to use the minifier tool, you can incorporate in into your build process using msbuild, you could run command line tool manually and create an output file, or you can use the minifier dll that gets distributed with the tool in your own applications. It is this third option that sparked my interest so I thought I would whip an application that allows you to load Javascript into an editor and then “crunch” it with the Ajax minifier object and visually see the output. Below is a screen shot of the final output. (I am adding a settings option so you can control how the minifier works)
If you just want to grab the zip fie that has the exe in it to run, you can grab it from here.
The first thing we will need to do is grab and install the Ajax Minifier from here. Once installed you will find the ajaxmin.dll file in the install location, like the following. It is that file that contains all the “crunching” code and the file you will need to reference in your project.
Once you have referenced the ajaxmin.dll file in your solution you will be able to “crunch” some javascript. In order to “crunch” the javascript you will need to make a call like the following.
- string Js = @"function ()
- {
- //these are some javascript comments
- var testVar = 'this is some alert text';
- alert('Hey What are you doing!!!!, Crunch this stuff…..');
- }";
- Microsoft.Ajax.Utilities.ScriptCruncher sc = new Microsoft.Ajax.Utilities.ScriptCruncher();
- string CrunchedJS = sc.Crunch(Js);
I also want to give credit to the #develop guys over at ic#code for putting out a excellent open source IDE for .NET development. I am using the #develop’s code editor control in this project to obtain the syntax highlighting, etc. Great work guys!!
you can check them out over at http://www.icsharpcode.net/OpenSource/SD/
That’s it for now and as always if you have any comments or questions you can comment here at the blog or catch me on twitter at http://twitter.com/johnmcbride
A friend of mine and I (Check out Ritch’s twitter feed here and his blog here) were talking a while back about the iPhone and the adoption into the business environment. Yes there are apps out there for business, but very few and not very many which people would use everyday in business. Now, coming from and IT/Dev background we also noticed a lack of enterprise management utilities that were native iPhone apps.
That lead to a few idea’s for iPhone projects, some of them I can’t talk about right now, but stay tuned I’ll blog about them in the near future. Just think Healthcare, iPhone
.
The first of these projects is an app we are calling Xeni (Pronounced Xen-eeee) and is one of the apps that will give enterprise admin’s and alternative application to help perform their daily job functions. Can you guess what it is?
Well, this iPhone application is all about managing your XenServer environment, from the XenServers to the Virtual Machines to the user sessions and beyond, all from a native application on the iPhone. We are not releasing this application yet to the appstore as we are still in the testing phase but wanted to let the community know what is coming down preverbal pike
and show off some screenshots.
In developing this app we did not really want to bake in a lot of services into the app itself, so we choose to write a few other SOA type services. One of these services, called WCFforCitrix Services, we wrote specifically for allowing access to Citrix based products from the service layer. Since we always like to give back to the community, we are now opening sourcing the WCFforCitrix project under the MSPL license and hosting it up on codeplex. We are in the process of uploading the source files in the next few days so be sure to keep monitoring the WCFforCitrixServices project here for more information. We are adding more features to this project daily so keep an eye on it.
So without further delay, lets take a look at some of the application screen shots here.
I haven’t posted all the screen shots, but I will be putting up a few more blog posts of the features of the app including more screen shots of the addition items. But hopefully, given the app store approval process, when testing is done the Xeni app should hit your iPhone or iPod soon.
As always, feel free to contact me via my twitter feed here or from the comments section (or you can email me here). Hope you guys like it
On and off for the last few weeks I have been trying to get VirtualBox 3.0.2 installed on my Windows 7 RC device with no real success
. During every install I ended up getting the dreaded “Setup wizard end prematurely” and subsequently VirtualBox wouldn’t get installed and it would be back to the drawing board.
Well, after some troubleshooting and some customizing of the MSI file I have finally got VirtualBox installed and running
but wanted to put this post together for those that are running into the same issue.
So, let’s get to it
First, let me define what my system is
1) Windows 7 Ultimate RC 64bit.
2) No previous version of Virtual Box installed on this device.
What your going to need:
1) Orca MSI Editor
2) Windows Driver Kit (MSDN Downloads)
Running the downloaded install of VirtualBox you will get the following installation error. The dreaded “Setup wizard ended prematurely”! That’s never good!
After looking at the log file, you will notice a curious error
”DIFXAPP: ERROR – The operating system you are running on is not supported. Only Windows 2000, Windows XP, Windows Server 2003 and Windows “
After, looking at the above message it appears that DIFXAPP is having a problem some where, my first theory is that the VirtualBox installer is using an older version of the DIFXAPP dll.
So, armed with the above theory, lets update the MSI installer with the updated versions of DIFXAPP dlls.
The first thing we need to do, is to download the Windows Driver Kit (Specifically I downloaded the driver kit for Windows 7). This download contains the updated DIFXAPP file that we are going to need to replace the ones in the MSI. Right now it looks like this download is on the MSDN Subscribers site so you will probably need a MSDN Subscription in order to download it. You can access the site here.
After you have downloaded and installed the Windows Driver Kit we are going to need to update the MSI with these new updated files. I know what your thinking, We didn’t get an MSI when we downloaded, we got an EXE. No problem, let me explain. When we run the virtualbox insaller, the EXE extracts and MSI called VirtualBox-3.0.2-r49928-MultiArch_amd64.msi, as see in the following image.
Now, where exactly is this file? The MSI file will get extracted to the users temp appdata folder. On Windows 7 it will be located in the following location
C:\Users\[YourUsername]\AppData\Local\Temp\VirtualBox
So, now that we have all the necessary files, we need to put it all together and update the MSI file with the updated DIFXAPP dlls. The first thing we are going to want to do is to open up the above MSI file in the Microsoft ORCA MSI Editor. Once you do you will see the following. Note the Binary item in the left pane in selected and in the right pane you can see the DIFX*.dll files that we are going to need to replace.
The next thing we need to do is to delete the DIFX*.dll items from the MSI. You can do this by right clicking on the DIFxApp.dll and selecting “Drop Row” from the menu that pops up. You will need to do this for the DIFxAppA.dll as well. Like the following
The next thing is is to re-add the updated DIFX files we got from the updated Windows Driver Kit to the MSI file. We can do this by right clicking and selecting “Add Row”
Now we need to select the updated DIFxApp.dll we extracted from the Windows Driver Kit we downloaded earlier. In my installation it is located here
C:\WinDDK\7100.0.0\redist\DIFx\DIFxApp\WixLib\amd64
Make sure the Name Attribute is the exact name as the DLL name. For example, the name for the DIFxApp.dll you be DIFxApp.dll
You will need to do this once for the DIFxApp.dll and once for the DIFxAppA.dll files. Like the following screen shots.
Once that is complete, you will need to save the MSI file from ORCA. Make sure you just do a File->Save. If you do a SaveAs the MSI will lose information and it will not work.
Once you complete the save you will now be able to run the MSI and get VirtualBox installed.
I am working on a quick video to show the results and should have it up soon. If you have any questions/comments feel free to comment and ping my on twitter twitter.com/johnmcbride
In this series of post’s let’s start to explorer the Citrix XenServer SDK and how we can start to use it in different types of applications to build interesting solutions.
So, Let’s set the stage
.
To start delving into the SDK, lets create a SharePoint webpart that will list all virtual machines on a given XenServer and allow the user to stop, start and pause each virtual machine through the webpart UI.
Here is a screenshot of what the part will look like when finished. You can also get the WSP file below if you want to install it into your SharePoint rig to play around with it. Note that this just a prototype app, but I intend on extending it to additional functionality. If you want to download the SharePoint solution file you can get it here.
In order to make this web part more re-usable we are going to have to be able to set some properties specific to our environment. We can do that enabling custom properties on the webpart. Below is a screen shot of the properties window of the web part. This allows you to add a XenServer and the XenServer information so the webpart can be used with multiple XenServers.
So, in order to build this webpart we are going to use a couple of different technologies.
1) jQuery (This will allow us to make some ajax calls to a wcf service that return XenServer information.
2) WCF (Windows Communication Foundation). This is a really simple WCF get enabled service to return different XenServer information.
3) SharePoint WebPart Development. (I wont get to detailed in this, but we will be using WSPBuilder to package up the SharePoint solution and a feature receiver to create some needed files upon activation of the web part.
WCF Implementation
While we could strictly put all the XenServer SDK code directly in the web part, this would make it more difficult for perform ajax based query’s and make the interface much more post back based. To eliminate this, we are going to implement the XenServer API in a service layer (Seperate DLL), and then package that up in our solution deployment. Remember this is a sample app, so the service implementation is pretty bare bones (Something I plan on adding to). Side Note: In order to get sharepoint to host WCF services I have included in the solution a DLL that is a virtual path provide to help with the hosting.
As with any WCF implementation, the first this we need to define is the interface for implementation. In this simple implementation all method will be REST aware and will return either a string or an XML response.
There are four main methods here that are of interest
1) GetVirtualMachines – This method will return a list of VirtualMachine objects and will accept parameters for the host, port, username and password
2) StopVM – This method returns a Boolean stating weather or not the call was sucessful and will accept parameters for the host, port, username, password, and VM UUID.
3) StartVM – This method returns a Boolean stating weather or not the call was sucessful and will accept parameters for the host, port, username, password, and VM UUID.
4) PauseVM – This method returns a Boolean stating weather or not the call was sucessful and will accept parameters for the host, port, username, password, and VM UUID.
The definition of the Interface is below.
1: [ServiceContract]
2: public interface IXenServer
3: {
4: [OperationContract]
5: [WebGet(ResponseFormat = WebMessageFormat.Xml)]
6: string ServiceStatus();
7: [OperationContract]
8: [WebGet(ResponseFormat = WebMessageFormat.Xml)]
9: List<Classes.VirtualMachine> GetVirtualMachines(string host, string port, string username, string password);
10: [OperationContract]
11: [WebGet(ResponseFormat = WebMessageFormat.Xml)]
12: bool StopVM(string host, string port, string username, string password, string XenServerVMUUID);
13: [OperationContract]
14: [WebGet(ResponseFormat = WebMessageFormat.Xml)]
15: bool StartVM(string host, string port, string username, string password, string XenServerVMUUID);
16: [OperationContract]
17: [WebGet(ResponseFormat = WebMessageFormat.Xml)]
18: bool PauseVM(string host, string port, string username, string password, string XenServerVMUUID);
19: [OperationContract]
20: [WebGet(ResponseFormat = WebMessageFormat.Xml)]
21: string GetVMStatus(string host, string port, string username, string password, string XenServerVMUUID);
22:
23: }
Now, in our Interface definition method GetVirtualMachine we specify that this method will return a list of VirtualMachine objects. This virtual machine object is simply a class that we need to define that has some properties on it, specifically a Name property, a description property, a UUID property and a Status property. The class definition with the properties is defined below. Remember since this is a WCF return class, we need to decorate the class with the datacontract attribute and for each property we want returned, they need to be decorated with the DataMember attribute.
1: [DataContract]
2: public class VirtualMachine
3: {
4: [DataMember]
5: public string Name { get; set; }
6: [DataMember]
7: public string Description { get; set; }
8: [DataMember]
9: public string UUID { get; set; }
10: [DataMember]
11: public string Status { get; set; }
12: }
So now we have our Interface definition and our return class definition, now we can implement our class that adheres to the Interface definition.
1: public class XenServer : IXenServer
2: {
3: internal XenAPI.Session GetSession(string host, int port, string username, string password)
4: {
5: try
6: {
7: XenAPI.Session _session = new XenAPI.Session(host, port);
8: _session.login_with_password(username, password);
9:
10: return _session;
11: }
12: catch (System.Exception loginError)
13: {
14: return null;
15: }
16: }
17: internal bool SessionLogout(XenAPI.Session Session)
18: {
19: Session.logout();
20: return true;
21: }
22:
23: public List<Classes.VirtualMachine> GetVirtualMachines(string host, string port, string username, string password)
24: {
25: System.Collections.Generic.List<Classes.VirtualMachine> _returnVirtualMachines = new System.Collections.Generic.List<Classes.VirtualMachine>();
26:
27: XenAPI.Session _session = this.GetSession(host, Convert.ToInt32(port), username, password);
28:
29: System.Collections.Generic.List<XenAPI.XenRef<XenAPI.VM>> _allVMs = XenAPI.VM.get_all(_session);
30: foreach (XenAPI.XenRef<XenAPI.VM> _xenRefVm in _allVMs)
31: {
32: XenAPI.VM _vm = XenAPI.VM.get_record(_session, _xenRefVm);
33: if (!_vm.is_a_template && !_vm.is_control_domain)
34: {
35: Classes.VirtualMachine _newVm = new Classes.VirtualMachine();
36: _newVm.Name = _vm.name_label;
37: _newVm.Description = _vm.name_description;
38: _newVm.UUID = _vm.uuid;
39: switch (_vm.power_state)
40: {
41: case XenAPI.vm_power_state.Halted:
42: _newVm.Status = "Halted";
43: break;
44: case XenAPI.vm_power_state.Paused:
45: _newVm.Status = "Paused";
46: break;
47: case XenAPI.vm_power_state.Running:
48: _newVm.Status = "Running";
49: break;
50: case XenAPI.vm_power_state.Suspended:
51: _newVm.Status = "Suspended";
52: break;
53: case XenAPI.vm_power_state.Unknown:
54: _newVm.Status = "Unknown";
55: break;
56: }
57: _returnVirtualMachines.Add(_newVm);
58: _newVm = null;
59: }
60: }
61: this.SessionLogout(_session);
62: _session = null;
63: return _returnVirtualMachines;
64: }
65:
66: public bool StopVM(string host, string port, string username, string password, string XenServerVMUUID)
67: {
68: XenAPI.Session _session = this.GetSession(host, Convert.ToInt32(port), username, password);
69:
70: XenAPI.XenRef<XenAPI.VM> virtualMachine = XenAPI.VM.get_by_uuid(_session, XenServerVMUUID);
71: if (virtualMachine != null)
72: {
73: XenAPI.VM.hard_shutdown(_session, virtualMachine);
74: }
75:
76: this.SessionLogout(_session);
77: _session = null;
78:
79: return true;
80: }
81:
82: public bool StartVM(string host, string port, string username, string password, string XenServerVMUUID)
83: {
84: XenAPI.Session _session = this.GetSession(host, Convert.ToInt32(port), username, password);
85:
86: XenAPI.XenRef<XenAPI.VM> virtualMachine = XenAPI.VM.get_by_uuid(_session, XenServerVMUUID);
87: if (virtualMachine != null)
88: {
89: XenAPI.VM.start(_session, virtualMachine, false, true);
90: }
91:
92: this.SessionLogout(_session);
93: _session = null;
94:
95: return true;
96: }
97:
98: public bool PauseVM(string host, string port, string username, string password, string XenServerVMUUID)
99: {
100: XenAPI.Session _session = this.GetSession(host, Convert.ToInt32(port), username, password);
101:
102: XenAPI.XenRef<XenAPI.VM> virtualMachine = XenAPI.VM.get_by_uuid(_session, XenServerVMUUID);
103: if (virtualMachine != null)
104: {
105: XenAPI.VM.suspend(_session, virtualMachine);
106: }
107:
108: this.SessionLogout(_session);
109: _session = null;
110:
111: return true;
112: }
113:
114: public string GetVMStatus(string host, string port, string username, string password, string XenServerVMUUID)
115: {
116: string _tmpStatus = null;
117: XenAPI.Session _session = this.GetSession(host, Convert.ToInt32(port), username, password);
118:
119: XenAPI.XenRef<XenAPI.VM> virtualMachineObject = XenAPI.VM.get_by_uuid(_session, XenServerVMUUID);
120: if (virtualMachineObject != null)
121: {
122: XenAPI.VM virtualMachine = XenAPI.VM.get_record(_session, virtualMachineObject);
123: switch (virtualMachine.power_state)
124: {
125: case XenAPI.vm_power_state.Halted:
126: _tmpStatus = "Halted";
127: break;
128: case XenAPI.vm_power_state.Paused:
129: _tmpStatus = "Paused";
130: break;
131: case XenAPI.vm_power_state.Running:
132: _tmpStatus = "Running";
133: break;
134: case XenAPI.vm_power_state.Suspended:
135: _tmpStatus = "Suspended";
136: break;
137: case XenAPI.vm_power_state.Unknown:
138: _tmpStatus = "Unknown";
139: break;
140: }
141: }
142:
143: this.SessionLogout(_session);
144: _session = null;
145:
146: return _tmpStatus;
147: }
148:
149: public string ServiceStatus()
150: {
151: return "Running";
152: }
153:
154: }
Lets examine the GetVirtualMachinesmethod here start to dig into the XenServer API.
The first thing we need to do is to get a session to the XenServer server. Everything in Xen works on the session so we need to create/attach to one
The following line will do that (along with the internal function).
internal XenAPI.Session GetSession(string host, int port, string username, string password)
{
try
{
XenAPI.Session _session = new XenAPI.Session(host, port);
_session.login_with_password(username, password);
return _session;
}
catch (System.Exception loginError)
{
return null;
}
}
XenAPI.Session _session = this.GetSession(host, Convert.ToInt32(port), username, password);
System.Collections.Generic.List<XenAPI.XenRef<XenAPI.VM>> _allVMs = XenAPI.VM.get_all(_session);
foreach (XenAPI.XenRef<XenAPI.VM> _xenRefVm in _allVMs)
{
XenAPI.VM _vm = XenAPI.VM.get_record(_session, _xenRefVm);
if (!_vm.is_a_template && !_vm.is_control_domain)
{
Classes.VirtualMachine _newVm = new Classes.VirtualMachine();
_newVm.Name = _vm.name_label;
_newVm.Description = _vm.name_description;
_newVm.UUID = _vm.uuid;
switch (_vm.power_state)
{
case XenAPI.vm_power_state.Halted:
_newVm.Status = "Halted";
break;
case XenAPI.vm_power_state.Paused:
_newVm.Status = "Paused";
break;
case XenAPI.vm_power_state.Running:
_newVm.Status = "Running";
break;
case XenAPI.vm_power_state.Suspended:
_newVm.Status = "Suspended";
break;
case XenAPI.vm_power_state.Unknown:
_newVm.Status = "Unknown";
break;
}
_returnVirtualMachines.Add(_newVm);
_newVm = null;
}
}
JQuery Implementation:
Using JQuery in a SharePoint web part is pretty simple, well, simple with a few helper functions
. The basic jist here is you will have to inject the JQuery script tag into the sharepoint page that the webpart is on from the webpart code. Use can use this same method to include any JQuery plugin’s that you want to use in your webpart. In our example we are going to use the following JQuery files.
1) JQuery-1.3.2.js (Main JQuery file)
2) impromptu.js ( JQuery plugin that enables a login box to appear when clicking on the actions for each VM)
3) jquery.datatable.js (JQuery plugin that enables a databound datagrid)
4) XenServerVMManegment.js (WebPart JavaScript responsible for making all the AJAX calls to the SCF services, etc)
Once you have the file in your WSPBuilder project, you are going to have to write code to inject the script tags into the sharepoint page where the part lives on I use two helper functions that allow me to add both JS files and CSS files dynamically from code. They are as follows.
Helper function to add JavaScript files to the SharePoint page.
public static void RegisterScript(string scriptPath, WebPart webpart)
{
string IncludeScriptFormat = @"<script language=""{0}"" src=""{1}""></script>";
if (!webpart.Page.ClientScript.IsClientScriptBlockRegistered(scriptPath))
{
string includescript = String.Format(IncludeScriptFormat, "javascript", scriptPath);
webpart.Page.ClientScript.RegisterClientScriptBlock(webpart.GetType(), scriptPath, includescript);
}
}
Helper function to add CSS files to the SharePoint Page.
public static void RegisterCSS(string cssPath, WebPart webpart)
{
ContentPlaceHolder _Header = (ContentPlaceHolder)webpart.Page.Master.FindControl("PlaceHolderAdditionalPageHead");
if (_Header != null)
{
CssRegistration cssControls = new CssRegistration();
cssControls.Name = cssPath;
_Header.Controls.Add(cssControls);
}
}
Once you have these two helper functions in your webpart code, you can add the following code to the CreadChildControls method in your webpart code. By using the methods above, it will allow us to register our scripts and CSS so we can then start using them within the sharepoint webpart.
RegisterScript(this.StripHTTPAndServer(_classResourcePath) + @"\JS\jquery-1.3.2.js", this);
RegisterScript(this.StripHTTPAndServer(_classResourcePath) + @"\JS\jquery.dataTables.js", this);
RegisterScript(this.StripHTTPAndServer(_classResourcePath) + @"\JS\impromptu.js", this);
RegisterScript(this.StripHTTPAndServer(_classResourcePath) + @"\JS\jquery.throbber.js", this);
RegisterScript(this.StripHTTPAndServer(_classResourcePath) + @"\JS\XenServerVMManagement.js?nocache=" + System.DateTime.Now.ToString("MMddyyyyhhmmss"), this);
So after the webpart has been loaded and shows up in the sharepoint page, the JavaScript/JQuery will now kick off.
//JQuery, when the DOM document is ready call a specific function.
$(document).ready(customReadyFunction);
//Document ready function. This is the function we tell JQuery to execute when the DOM is ready to reaverse.
function customReadyFunction() {
//Create the data table.
xenServerVMDataTable = $("#xenServerVMMachines").dataTable();
//call the WCF service to get all VM's
var serviceURL = "/_XenServerWCF/XenServer.svc/GetVirtualMachines?host=" + xsServer + "&port=" + xsPort + "&password=" + xsPassword + "&username=" + xsUsername;
$.ajax({
url: serviceURL,
type: 'GET',
dataType:'xml',
success:getXenServersSuccessCallback,
failure:getXenServersFailureCallback
});
}
The JQuery/JavaScript above sets up and calls a custom function when the DOM is ready. This custom function is responsible for calling the WCF XenServer Service via an AJAX call.
SharePoint:
While the majority of the code resides in the JavaScript files, there are a couple of items we can touch on related to sharepoint.
The first is we have defined several custom properties that will allow the users to change XenServer settings. Like the following.
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("XenServer Settings")]
[WebDisplayName("XenServer Host Name (or IP)")]
[WebDescription("This field should be the netbios name or IP address of you XenServer")]
public string XenServerHost
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("XenServer Settings")]
[WebDisplayName("XenServer Host Port")]
[WebDescription("This is port or your XenServer that is listening for requests (Typically 80/443)")]
public int XenServerPort
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("XenServer Settings")]
[WebDisplayName("XenServer Username")]
[WebDescription("This should be a username on your XenServer that will be used to traverse and obtaing a list of Virtual Machines.")]
public string XenServerUsername
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("XenServer Settings")]
[WebDisplayName("XenServer Password")]
[WebDescription("This should be the password to the above XenServer username.")]
public string XenServerPassword
Along with these, we also have a feature receiver, which take on the function of creating some specific directories and files to enable the WCF services and registering some http models.
Ok, that’s a brief overview of the webpart, but i am going to break each part of this post out into more detailed posts each one can be targeted at each technology.
Feel free to comment or contact be via twitter (twitter.com/johnmcbride) and through comments on this blog.
Before we get into this post, I first want to state I fully understand that both Visual Studio 2010 and the ASP.NET MVC out of band installer are beta products, so this issue may be fixed, but i wanted to put it out there to see if anyone else has encountered a similar problem. This is an open ended post as I am searching for answers on this issue, but will continue to research this as I have time. If you have any suggestions or a fix drop me a line and we can chat.
The Problem: When creating a out of the box MVC application and adding a custom class to the model folder, trying to reference that data class within a view causes Visual Studio 2010 and the VisualStudio Web Server to crash. The same application works fine with Visual Studio 2008.
Lets show an example.
Visual Studio 2008
In Visual Studio 2008 let create a new MVC application. Create or dont create the test cases, it doesnt really matter.
Once the application is created, Lets add a class to our model folder, with the following definition.
1: public class TestFolder
2: {
3: public string Name { get; set; }
4: }
Now, Lets go ahead and create a new controller from the VS UI. Right click on the Controllers folder and select Add->Controller. Let call this controller TestContoller so we can access the page from a new URL.
In this new controller class we need to create an instance of our TestFolder class so that the view can traverse it. Here is the code for the controller class.
1: public class TestController : Controller
2: {
3: //
4: // GET: /Test/
5: List<Models.TestFolder> myFolder;
6: public ActionResult Index()
7: {
8: myFolder = new List<MvcApplication2.Models.TestFolder>();
9: myFolder.Add(new MvcApplication2.Models.TestFolder { Name="Folder one" });
10: myFolder.Add(new MvcApplication2.Models.TestFolder { Name = "Folder two" });
11: myFolder.Add(new MvcApplication2.Models.TestFolder { Name = "Folder three" });
12: myFolder.Add(new MvcApplication2.Models.TestFolder { Name = "Folder four" });
13: //Response.Write("<h1>Test Controller PAGE</h1>");
14: return View("Test", myFolder);
15: }
Now, lets add a view, right click anywhere in the controller class we have just created and AddView. We need to make sure that we select the strongly typed view (our TestFolder class ) and select the list as the view content.
Here is the View Code
1: <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcApplication2.Models.TestFolder>>" %>
2:
3: <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
4: Test
5: </asp:Content>
6:
7: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
8:
9: <h2>Test</h2>
10: <%foreach (var folder in Model) { %>
11: <h1><%= folder.Name %></h1>
12: <%} %>
13: </asp:Content>
Now, we can run the application and navigate to the http://servername/Test controller and you should see the following.
All is working fine, the MVC app
Visual Studio 2010
If we follow the exact same scenario above but ue Visual Studio 2010 with the MVC extensions and we run it in debug mode we get the following errors.
Visual Studio 2010 crashes and restarts.
The Visual Studio Development Web Server crashes as well, but the following screenshots.
In addition to this these are logged in the Windows event viewer.
This is an open ended post as I am searching for answers on this issue, but will continue to research this as I have time. If you have any suggestions or a fix drop me a line and we can chat.
As developers, we are always looking for platforms to build upon right? Did you know that Citrix can be viewed as a developer platform? I think many enterprises still view Citrix as the infrastructure company (Although, that view has been gradually changing over the last few years) that they have come to love. I believe those enterprise and the enterprise developers in them need to start looking at Citrix as a developer platform and realize that they can start building better experiences for the end users, weather it be IT Admins or the traditional end users. Citrix can be viewed as and *is* a developer platform, specifically one that needs to start being built upon.
If we think of Microsoft, we think traditionally of a system where a developer can pretty much tap into as much stuff as he wants (in addition to the Steve Ballmer Developers Developers Developers speech!
). They have an enormous API set for windows itself, and for the most part, every product they produce has a “Developer Story”. Some examples of this are Office has the VSTO model, Want to host Windows Workflow Designer in your custom app, no problem, Need to talk to SharePoint, use the Web Services. This developer focus is what enables so many people to write for the windows platform.
Now, if we look at Citrix, they have a similar story, although its not promoted as much as the Microsoft Developer focus. One that I feel needs to be promoted more, and hence this article
. For example, did you know that Citrix has a total of 34 SDK’s that are available to developers? Everything from XenApp to Password Manager to NetScaler. I have tried to break them out below. To download them, you can go to the community site over here
| Category | Related # of SDK’s | Notes |
| XenApp | 13 | This covers things like MFCOM,Password manager, WI, Virtual Channel SDK, etc |
| XenServer | 5 | XenServer Related SDK’s |
| XenDesktop | 1 | XenDesktop Related SDK’s |
| NetScaler | 12 | NetScaler Related SDK’s |
| Workflow Studio | 1 | Workflow Studio SDK’s |
| Citrix Online | 2 | These are the GotoMeeting and GotoAssist SDK’s. Now even though you have to have a GTM or GTA account to get and use these, the point is they are still there. |
So your saying, great! I’m buying into this and now i want to start using these SDK’s to build the next great app for my enterprise, but I don’t have a datacenter or server farm running this stuff and I cant afford to purchase licenses. Well, don’t fret. If you want to start developing for XenApp (Presentation Server), then Citrix offers a developer’s version of XenApp as well as the Dev license (1 year in length). This will get you up and running for XenApp/Wi/Powershell/Access Console/etc development. No cost, no hassle (There is not one yet for the XenApp 5.0 on Windows 2008 though).
Now, for the other products like NetScaler, Password Provisioning,etc, I’m not aware of Developer versions of these, although I believe that there should be some type of scaled back, one user (maybe two), type of offering to allow more developers to code up those one of a kind applications that are just sitting there waiting to be written
. I mean Citrix is a Developer Platform so lets start to utilize all of the platform to build those apps.
You can download the Developer Edition of XenApp at the following location. Remember, you will need a MyCitrix Account in order to download.
Now, my point here is not to compare Citrix to Microsoft but simply to provide a reference point and to inform developers that Citrix is a platform that we can build on. There are enough SDK’s available that we should start using them to build up some interesting experiences.
You may be saying, well how much stuff can we do, automate publishing an application? Well, what could be some interesting user experiences we could think of where the SDK’s could help. How about a single interface for all of your apps no matter what kind they are (See my previous post here), Maybe a silverlight alternative to Web Interface (I think there is one like this already, at least there was long time ago), Maybe integrate Web Interface into you windows app (or a subset of it to facilitate some launching mechanism)? Maybe integrate MFCOM into your custom provision system to add users to an application when they get access to it or write some Workflow Activities and make them available to the community? All of these things are possible with the use of the SDK’s provided by Citrix and its time that we as developers start viewing Citrix as a Developer Platform, at least in my humble opinion
. These tools are not just for admin functions anymore, lets start to push the envelope!
Thats my .02, Tell me what you think? do you have any cool XenApp code that could benefit the community, head on over to the Citrix Community Site and participate.
If your running XenServer, you have learned to love the command line interface right?
. Well, Citrix has made available a virtual appliance for XenServer call XenCenterWeb. This ia a preconfigured virtual appliance, that enables you to do some virtual machine management from within a browser. The site itself is written in PHP, so all the code is available on the VM/Appliance. You can get the Virtual Application from this link.
I have also put together a quick screencast on setting up and configuring XenCenterWeb. Check it out below.
As I recently have rebuilt my laptop to run Windows 7 RC, I decided to download and install the XenServer Powershell extensions (available here) to start evaluating them. I was going to start writing my own extension but then stumbled across the ones that Citrix has developed and figured instead of writing my own, I would post some videos pertaining to the Citrix distributed ones. As a side not, Citrix has also released the source code to the PowerShell extensions. A very cool move in my humble opinion. I believe more companies should contribute to the open source community, and props to Citrix for taking this step.
After the installation, I checked the readme and saw an important item
“3. Determine the current execution policy, like this:
PS> Get-ExecutionPolicy
If the current policy is Restricted, then you need to set it to
RemoteSigned, like this:
PS> Set-ExecutionPolicy RemoteSigned
You should understand the security implications of this change. If you
are unsure, see Microsoft’s documentation on the matter:
PS> Get-Help about_signing
If the current policy is AllSigned, then this will work, but will be
very inconvenient. You probably want to change this to RemoteSigned,
as above.
If the current policy is Unrestricted or RemoteSigned, then this is
compatible with XS-PS, so there is nothing to do.”
After adhearing to the above documentation
, lets go ahead and run the XenServer Powershell Snapin from the start menu. ![]()
The resulting output from powershell is the below screenshot. Basically Powershell is telling us that it cannot find the XenServerPSSnapIn snapin, which typically means that the xenserverpssnap dll did not get registered properly during the installation. At least that is the initial theory
Maybe we need to run the installer as administrator, sometimes I forget to do this, but I thought this might be an issue so lets make sure and reinstall as admin. Well, that didnt work in my case so on to the original theory.
To make sure that this is indeed the case, lets fire up Microsoft Orca (MSI Editor tool) and edit the XenServerPSSnapIn-5.0.0-3.msi to see if we can find a custom action or something that takes care of the registration process. After searching around within the MSI indeed there is a custom action that is supposed to register the xenserver snapin on the machine as shown below.
To further confirm that the snapin did not get registered during the installation process let check the registry. You can locate all registered PowerShell snapins by checking the following key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellSnapIns
Side Note: If your developing PowerShell snapins using C#/VB.Net once you compile your snapin dll you will need inform PowerShell that it is installed on the the machine and you want to load it into PowerShell. This is a two step process.
Step 1: use the installutil.exe utility to register the DLL onto the system the syntax is something similar to the following
%windir%\Microsoft.Net\Framework\v2.0.50727\installutil.exe [full path to your dll]
Step 2: once you have registered your dll on the system you need to add it to Powershell. You can do this by issuing the Add-PSSnapIn command from within powershell, like the following
Add-PSSnapIn –name [Your SnapIn Name]
So, now we know what the problem is we can work on fixing it so we can start using the SnapIns
The first step in the process is to register the snapin DLL on the the machine. Check out the side note above. We can achieve this by issuing the following command from within powershell. (Note: You will need to run PowerShell as administrator, especially if you are running on Windows 7).
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe [Path To XenServer DLL]\XenServerPSSnapIn.dll
Once issuing this command you should see something like the following screenshot.
Now, from here you should be able to execute the XenServer Powershell Snapin from the start menu, and you will get the resulting powershell window ,with the snapin registered and ready to go, like the following. As you can see we have connected to out test XenServer ![]()
To further show that the the snapin is indeed loaded, we can issue the command Get-PSSnapin and it will show that the XenServer snapin is loaded. ![]()
Now, if you want to load the snapin into a regular powershell window, you would need to issue the Add-PSSnapIn command and that will load up the snapin for use within the current powershell window, like the following
Add-PSSnapin XenServerPSSnapIn ![]()
This will load the snapin and make the commands available for you to use.
Now, at this point, I’m not sure why the install did not properly register the XenServerSnapin.Dll on my Windows 7 RC system, but I am trying to do some further research on this and as soon I find out more info I will post it here. I hope this post helps out.
As always you can reach me through comments on here, follow me on twitter (http://www.twitter.com/johnmcbride) or friend me on FaceBook.
Tags: citrix, Powershell, xenserver

SharePoint Developer,Architect,General all around technologist (ESX Server, Web Development, .NET, Windows 7, Citrix,etc), husband and father of three 