Archive for April, 2009

Why I love ballroom dancing

Sunday, April 26th, 2009

The wozI hate ballroom dancing. I would never want to do it. Dancing in general isn’t that interesting to me and doing it slowly to bad music with a bunch of people in stuffy clothing even less so. Also those people probably like ballroom dancing… but so do I. I love it in fact. I love a lot of things that I don’t like but have absolutely no effect on my life.

I want the whole world to be full of things that I don’t do. Variety is the spice of life some say. I don’t say it but others do and I agree with them in principle. Life would be less interesting if we all did and thought the same things. At the very least the lines for those things would be longer.

I’m not sure what the internet is doing to underground culture but it is certainly making it more accessible. It used to be if you wanted to do something a little non standard you had to really look to find info about it. For me it was radio controlled cars or paintball. You would find a magazine or go to some little shop and talk to people there. Now all you have to do is google (v. to google, also see yahoo).

I had a Western Civ professor in college who claimed pop culture began with the Sears Catalog. One big piece of mass marketing that everyone got so we could all know what to buy. I don’t know if he was the first to think of that but it makes sense. Suddenly everyone had the same options as what to buy. Given the same limited options do we all tend to gravitate to the best options? I don’t know, I’m just making all this up but the internet is both consolidating certain experiences such as shopping with amazon.com or giving us seemingly infinite options for in-depth info on any edge case hobby we want.

What does it all mean? I don’t know but I love the fact that there is a whole world full of stuff I don’t like and know nothing about. It means there are plenty of options of new things to do and others that I don’t need to worry about.

Canceling Workflow in Code in Microsoft CRM 4.0

Sunday, April 26th, 2009

No, I don’t write a lot about coding on here often but since my mission statement for my blog is all things me and I just spent the last few hours digging through SDK to figure out how to cancel a workflow with the CRM 4.0 SDK I figured I should write a blog post. Google had nothing about it so hopefully the next person will find this. Be forewarned, I haven’t fully tested this so use it at your own risk. One thing I haven’t tested is how CRM behaves when you try to change status on something that is waiting for resources. I expect it will work but who knows.

The gist of it is instances of workflows are now contained in the asyncoperationbase table and entity. Go retrieve the asyncoperations you are interested in. In my case I would know the workflow name I was after as well as the CRM objectID of the record the workflow would be running on. Once I have that list I check and see if the status is an a status that I want to cancel. The statuses and states are listed in the SDK. You have to set both the status and state for the operation to take effect. It doesn’t throw an error like I recall CRM 3.0 doing about mismatched status and state combination’s, it just goes along its merry way and doesn’t change anything.

In CRM 3.0 you could use the SetStateWFProcessInstanceRequest but since everything around WFProcess was deprecated I am doing it with the TargetUpdateAsyncOperation as seen below.

TargetUpdateAsyncOperation operation = new TargetUpdateAsyncOperation();
operation.AsyncOperation = singleWorkflowInstance;

UpdateRequest update = new UpdateRequest();
update.Target = operation;
UpdateResponse updated = (UpdateResponse)service.Execute(update);

So here is the code I wrote to do it and it does indeed cancel a workflow. The Utils.GetCrm4Service() method is my own and you will need to either implement it yourself of just instantiate the crmService yourself in place. There are plenty of examples on how to do it. I’d love feedback if you use it or if you know of a better way.

public static void KillWorkflow(string workflowName, Guid entityId)
{
string error = “”;

CrmService service = Utils.GetCrm4Service(null, false);

ColumnSet colsWf = new ColumnSet();
colsWf.Attributes = new string[] { “name”, “statuscode”, “asyncoperationid”, “regardingobjectid”};

ConditionExpression conditionName = new ConditionExpression();
conditionName.AttributeName = “name”;
conditionName.Values = new string[] { workflowName };

ConditionExpression conditionRegardingObjectId = new ConditionExpression();
conditionRegardingObjectId.AttributeName = “regardingobjectid”;
conditionRegardingObjectId.Values = new string[] { entityId.ToString() };

FilterExpression filter = new FilterExpression();
filter.Conditions = new ConditionExpression[] { conditionName, conditionRegaridingObjectId };
filter.FilterOperator = LogicalOperator.And;

QueryExpression query = new QueryExpression();
query.ColumnSet = colsWf;
query.EntityName = EntityName.asyncoperation.ToString();
query.Criteria = filter;

BusinessEntityCollection results = service.RetrieveMultiple(query);

if (results.BusinessEntities.Length > 0)
{
for (int i = 0; i < results.BusinessEntities.Length; i++)
{
asyncoperation singleWorkflowInstance = (asyncoperation)results.BusinessEntities[i];
if(singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.WaitingForResources ||
singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.Waiting ||
singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.Pausing ||
singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.InProgress)
{
try
{
Status statusCanceled = new Status();
statusCanceled.Value = AsyncOperationStatus.Canceled;

AsyncOperationStateInfo state = new AsyncOperationStateInfo();
state.Value = .AsyncOperationState.Completed;

SetStateWorkflowRequest request = new SetStateWorkflowRequest();
singleWorkflowInstance.statuscode = statusCanceled;
singleWorkflowInstance.statecode = state;

TargetUpdateAsyncOperation operation = new TargetUpdateAsyncOperation();
operation.AsyncOperation = singleWorkflowInstance;

UpdateRequest update = new UpdateRequest();
update.Target = operation;
UpdateResponse updated = (UpdateResponse)service.Execute(update);
}
catch (System.Web.Services.Protocols.SoapException ex)
{
error = “KillWorkflow Error ” + ex.Message + “” + ex.StackTrace;
}
catch (Exception ex)
{
error = “KillWorkflow Error ” + ex.Message + “” + ex.StackTrace;
}
}
}

if (error != null && !error.Equals(“”))
{
throw new Exception(error);
}
}
}