21.09.2010 г.

Can't debug Silverlight in Firefox - the solution!

Some months ago I was actively developing a Silverlight designer,about which I posted here.
Lately I found a small irritating bug in the designer and started debugging it. The strange thing was that I was practically unable to do that. The debugger was telling me that no debug symbols had been loaded for my silverlight application. For me this is one of the most annoying errors.
However, I spent some time trying to enable silverlight debugging with no success. I debugged it with MessageBox.Show(); and then forgot about the problem.
Today I found myself another bug and decided that it is time to get deeper into the debugging problem.
So to be sure that you will be able to debug silverlight applications:
1) Be sure to check the option for debugging Silverlight in the hosting Web project.
Web project -> Properties -> Web -> under Debuggers
2) There is a tab Silverlight Applications in web project's properties. You should add your project there.
3) Be sure that your ClientBin (or the folder where your web application expects your silverlight xap-s to reside) folder has the latest .xap packages. If not make sure that after building the silverlight project the result .xap goes there. That can be done with postbuild events.

If nothing of these helps, as it happened with me, read further:
This is a solution for debugging with Firefox:

Here’s how to ensure the VS debugger attaches to the Silverlight app for debugging:

* In Firefox address bar type about:config
* Read the warning, choose your preference to always remind you or not and accept
* In the search bar of the config options now type: npctrl
* You should then see the entry: dom.ipc.plugins.enabled.npctrl.dll
* Change the value from true to false (simply double-clicking will change this for you)
* Restart Firefox

Firefox solution source

BTW there is also some valuable comments under this guy's post.

24.04.2010 г.

Extending the US keyboard layout with some German symbols

Have you ever missed some symbol on your keyboard layout? I have.
I learn now german and I miss the symbols that are not part of the english alphabet.
They are as follows:
ä - U+00e4
Ä - U+00c4
ö - U+00f6
Ö - U+00d6
ü - U+00fc
Ü - U+00dc
ß - U+00df

For generating a keyboard layout you need to download the Microsoft Keyboard Layout Creator.

Start the application and open an existing keyboard that you want to inherit, or create one from scratch. Don't be worry, there is no chance that you screw some of the existing layouts. When you double click on a particular key from the keyboard preview, a form for editing will appear. There you should make the changes.
For the german symbols you should use the codes above. I guess these codes are the Unicode representation of the symbols.
The software gives you the ability to simulate that some of the special (ctrl,shift,caps lock) keys or a combination of them is pressed. Also you can test the keyboard layout that you've just created(Project->Test keyboard layout) by manually writing some of the "new" symbols. Then it is a good thing to Validate the layout(Project->Validate layout). After the validation make sure to fill the properties of your layout(Project->Properties). Finally again from the 'Project' menu build the new layout. A setup will be generated. I've tested a layout on W7, Vista and Windows XP. It works just fine. Except the fact that on Windows XP the combination Left Ctrl + Left Alt + symbol worked only for ä. But this may be due to the specific PC, I don't know. However instead of Left Ctrl + Left Alt you can use AltGr that worked perfect even on XP.

Just to mention: If you don't have a well-grounded reason for checking the last 2 checkboxes on the properties form, my advice is DON'T!

I hope this will be useful for somebody except me.
Enjoy.

Here are some screenshots:





26.03.2010 г.

Using the Microsoft .NET CodeDom Framework

Recently I learned some CodeDom stuff that I consider worth sharing.

CodeDom is an API,included in .NET Framework, that gives us an object oriented way of dealing with the csc.exe (The C# compiler). Visual studio uses this console application for compiling your projects. CSC.exe accepts a whole bunch of parameters. For instance parameters for the path to output to,path for looking for referenced assemblies, parameter that tells the compiler whether to create a library or an executable and so on. The list is really long. Good thing is that you don't actually need all of the parameters. HERE is a reference for the compiler options. I will mention and explain below just the ones I needed in my case.

My task consisted in creating an API for parsing source code that the user of the system creates and compiling that source code in a separate assembly. After that these assemblies are executed on some events in the system.
Example:Lets say your system logs to the windows event log on error. However some of you clients want to send e-mail on every error in the system. So with the "custom code" approach you can just raise event on error in the system. Then for every client wish you can create separate implementation... you know one for writing to the windows event log, another for sending an e-mail to the system administrator etc. And the last step is hooking these implementations to the event. This is a good way for code injection.
To be honest I didn't came to this architecture alone. My project manager gave me this idea and after I developed it and saw it in action, I should admit that it really rocks.

So lets get down to the nitty gritty.

First of all lets see what kind of input I expect for the source code that is going to be compiled.


1: assemblyName:Test.dll
2: className:TestClass
3: include:System.dll
4: include:System.Core.dll
5: include:System.Xml.dll
6: include:NotFrameworkAssembly1.dll
7: include:NotFrameworkAssembly2.dll
8: include:NotFrameworkAssembly3.dll

9: using System;
10: using NamespaceFrom.NotFrameworkAssembly1;
11: using NamespaceFrom.NotFrameworkAssembly2;
12: using NamespaceFrom.NotFrameworkAssembly3;

13: public class TestClass : SomeBaseClass
14: {
15: public override void Method1FromTheBaseClass()
16: {
17: //TODO Add some code that you can execute later
18: }

19: public override void AnotherMethodFromTheBaseClass()
20: {
21: //TODO: Send e-mail
22: }
23: }

Between lines 1 and 8 is the needed information apart from the actual code. There are:
1 - The name of the assembly to be created;
2 - The name of the class ,which name will be used later to create an instance of.
3..8 - List of the assemblies that will be included as referenced assemblies
9..23 - The actual code.

I created a class that represents the raw data above. The class has some properties that I need and I initialize them by passing the raw data to the 'ParseRawSource' method.

public class AssemblyGenerationInfo
{
public List ReferencedAssemblies { get; set; }
public string SourceCode { get; set; }
public string ClassName { get; set; }
public string AssemblyName { get; set; }

public void ParseRawSource(string inputStr)
{
}
//THE MAJORITY OF THE CODE IS OMITTED


Here is finally the actual code for compiling the assembly. There are some key things that are worth of mentioning:
1) Adding a 'lib' param that points to thePathWhereTheReferencedAssembliesReside;
2) Setting the 'CompilerVersion' to 'v3.5';
3) Assigning 'buildOutput' out parameter so that whoever calls the method will get eventual build errors.


public bool CompileAssembly(AssemblyGenerationInfo agi, out string buildOutput)
{
string outputDirectoryPath = "some path";
string thePathWhereTheReferencedAssembliesReside = "some path";
if (agi == null)
{
buildOutput = string.Format("Code to compile was not provided!");
return false;
}

CompilerParameters parameters = new CompilerParameters(agi.ReferencedAssemblies.ToArray());
parameters.IncludeDebugInformation = false;

parameters.CompilerOptions = string.Format(@"/lib:""{0}""", thePathWhereTheReferencedAssembliesReside);
string fullPathToTheCompiledAssembly = Path.Combine(outputDirectoryPath, agi.AssemblyName);

if (!Directory.Exists(outputDirectoryPath))
{
Directory.CreateDirectory(outputDirectoryPath);
}
parameters.OutputAssembly = fullPathToTheCompiledAssembly;


CSharpCodeProvider csc = new CSharpCodeProvider(new Dictionary() { { "CompilerVersion", "v3.5" } });

CompilerResults results = csc.CompileAssemblyFromSource(parameters, agi.SourceCode);
if (results.Errors.Count == 0)
{
buildOutput = null;
return true;
}
else
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors)
{
sb.Append(error.ToString() + Environment.NewLine);
}
buildOutput = sb.ToString().TrimEnd();
return false;
}
}


I hope this post was interesting and helpful.
Enjoy.

13.02.2010 г.

Blend 2 and Blend 3

Before starting this post I promise myself to make it short. If you take a look at my last 2 ones you will understand why. So Blend. What can I say? Not much of course. Blend is a designer tool and I pretend to be a developer. However for some reasons I had to use it, because I had no other option. VS2008 has no designer for silverlight. And I think it is a very good product. You can make animations (storyboards in terms of xaml), to move things around, to edit properties and I'm sure many many other things.
Let me first write something about Blend 2. It is not so good. It supports only silverlight 1.1 projects. To open and edit SL 2.0 projects you need to install Blend 2 sp1. But that brings you just the ability to edit SL 2.0 projects. The same problems Blend 2 has are still present in sp1. It can't show inherited forms. Also you can't select a control by clicking it in the designer. Instead you need to find it in the control tree and then select it. And I'm sure Blend 2 has some other bugs too.

Blend 3 is something different. Again I can give a good review because I use maybe less than 10% of its features, but I think it is much better than Blend 2. The problems mentioned above are solved here. Also Blend 3 is in my opinion faster. It loads the projects faster and also working with it is easier.

However both versions of Blend share a huge disadvantage. They can't work with Visual SourceSafe. So the designer we have at the office needs to install Visual Studio just to check out the files she needs to edit. And then to check them in.
That is not right. Microsoft should do something about this.

And to keep the promise I gave myself I stop here.

What I hate about Silverlight

Don't get me wrong, I like silverlight. It is great. It is fast. It is different.
However some things really drive me crazy.
Silverlight 1.0 was just an advertising campaign. Its purpose was only to make developers anxious for the upcoming versions. I understand that.
I haven't used much of silverlight 1.1 but I know it was a huge leap forward.
Then came 2.0 that was announced as the first version that can be used to write sensible and powerful solutions.
Then came 3.0 which was expected to be also a major release.
I started to use silverlight just after version 2.0 was released. There were some things that were irritating me in 2.0. Those things still irritate me in 3.0. Actually I thing the difference between 2.0 and 3.0 is not so big that I expected.
I read somewhere that 3.0 introduces support for using the 3D power of your video card and also support of using the wheel of the mouse. Hello! Is this the most important.
But what really drove me crazy was that just a few months after releasing SL 3.0 Microsoft announced 4.0 beta. What to expect from this new version?! Maybe voice recognition, which will totally smash the Adobe rival.

So let me point some features I miss in Silverlight.

1) The designer. I miss a designer for silverlight in VS2008. How to create my GUI without designer. Hot to compute the margins? I heard that a powerful XAML designer will be available in VS2010. I'm waiting for it. As designer I use MS Expression Blend, which is very very good tool and even I can work with it. About Blend I will write a separate post.

2) Can reference only silverlight library projects. What about the whole bunch of code that you have. In my case we have some code dll-s that all the other projects use.I have some clues about this restrictions, but they are not worth sharing. However you can always link a file if you need. That btw, I mean the restriction of referencing dll-s != silverlight, has also a good side. Because it is vital to reference as less as possible dll-s. Because every single referenced assembly is then added to the package that every single user of you silverlight control downloads. Also I think there might be some performance penalty when having many assemblies, but I haven't tested that. Also I think here's the place to mention that you must be very careful with memory usage. Try not to hold references to huge collections and objects. Make sure you don't prevent the garbage collector to dispose them.

3) The most annoying one. The design time exceptions. You write some code, compile.Everything seems good. And then when you run it you get AG_E_UNKNOWN_ERROR or G_E_PARSER_BAD_PROPERTY_VALUE. Then you see some line and some position. It took me quite a time to start getting some hints on where the problem is. Was it so hard to make exceptions more detailed? Btw the majority of the exceptions I get are because I omit to implement a event handler in the .xaml.cs file. And I have declared it in the markup. This is a design time exception. Was it so hard to catch it design time? So to sum up I think Silverlight exceptions suck and Microsoft should do something about it instead of dealing with the mouse wheel.

4) Inheritance (of silverlight controls)- there is a workaround to do this. I admit that. But it is not as straightforward as it has to be. To inherit from other "form" you need to mark this in the codebehind file and also in the markup file. There are some other details that are however not relevant. Lets say, yes inheritance is possible. But, as "forms" are not meant to support inheritance there a lots of bugs in the whole thing. I needed all my forms to have some common behavior. For this I needed to handle 3 events. I wanted to hook for the events and write the handlers in the base form. And then all other forms to inherit from the base and to share the base behavior. But I failed. That was not supported. I got exceptions. And yes they were "AG_E_UNKNOWN_ERROR" like :). So I needed to hook in every single form and also needed event handlers for all the 3 events. In those handlers I called the three methods that I had written in the base class. What a mess. So to sum up: Microsoft guys, please do some work on inheritance.

5)And last. Some framework classes omit some of their methods. For example I will point the Enum.GetNames and the Color structure. And you can't use System.Drawing.Color, because System.Drawing is not a silverlight library.

Below is a workaround I use to get the names of all members of particular enum and also a method to get a color from its hex representation. To be honest the second one is not available in System.Drawing.Color too.
public static List GetEnumNames(Type enumType)
{
List enumMemberNamesFuckSilverlight = new List();
System.Reflection.FieldInfo[] fiArray = enumType.GetFields(
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Static);
foreach (System.Reflection.FieldInfo fi in fiArray)
{
enumMemberNamesFuckSilverlight.Add(fi.Name);
}
return enumMemberNamesFuckSilverlight;
}

public static Color ConvertStringToColor(string source)
{
Color blackDefaultColor = Color.FromArgb(255, 0, 0, 0);

try
{
if (string.IsNullOrEmpty(source))
{
return blackDefaultColor;
}
else
{
source = source.Trim(new char[] { '#' });
if (source.Length != 8)
{
if (source.Length == 6)
{
//Correct color representation, omitting the alpha.
source = "FF" + source;
}
else
{
//Incorrect color...Sorry!
return blackDefaultColor;
}
}

byte a = (byte)Int32.Parse(source.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
byte r = (byte)Int32.Parse(source.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
byte g = (byte)Int32.Parse(source.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
byte b = (byte)Int32.Parse(source.Substring(6, 2), System.Globalization.NumberStyles.HexNumber);

return Color.FromArgb(a, r, g, b);
}
}
catch (Exception exc)
{
return blackDefaultColor;
}
}

Some experience with Silverlight

So as I promised here is the article about what I learned about Silverlight from my first serious touch with it.
As I mentioned before, from some time I'm working on a Silverlight project, that is some kind of workflow designer. Briefly said I have nodes and routes between them and nodes plus routes make a task.I will not deepen on the purpose of this architecture, because it is related to our specific needs. So actually this WF designer is not a general purpose one, but it is specifically designed to serve us. However it was a good experience for me, because you know, the best way to understand some new technology is to start using it. Then comes Google :).

I had some challenges before I start to write.

First of all was the data model.The objects I described above(tasks, nodes and routes) were represented as database tables. To spice the things up, the node object had some bunch of dependent objects, that were not presented as database tables but serialized as XML and stuck in a text column of the node table. So there was a serialize/deserialize process when dealing with the nodes. However this part was already done for an old windows forms application with the same purpose as the silverlight designer. Btw the silverlight designer was meant to replace the old windows forms one. I had the XML <-> objects conversion done. However I couldn't use those objects, because they were not marked as Data contracts. But for that I will write below.
So enough for the issues regarding the data and its representation.

The second challenge was how to get this data from the server and serve it to the client and vice versa. Here the solution was straightforward.

The last major problem was how the hell to implement a GUI for editing the whole bunch of objects. The problem was that I needed to mitigate the complication of the data model and to do the GUI as simple as possible for the user.

So let me start with the decisions I made.
About the data model, I decided to create a mirror object to every object I needed to transfer across the wire. So lets say as example that I had three objects - NodeSettings, NodeCoordinates, NodeSomethingElse. Remember, all these objects are serialized to XML and the result XML is saved in a text column of the node table. Also I had an API to work with these objects. Lets name the "mirror" objects for these three ones respectively NodeSettingsTransfObj, NodeCoordinatesTransfObj and NodeSomethingElseTransfObj. They were marked as data contracts. To work easily with both the framework ones and the transfer ones I created for each of the objects an extension method. Did I mentioned that extensions rule! So for example the pair NodeSettings <-> NodeSettingsTransfObj. I created on NodeSettings an extension method named ToTransfObj and on the NodeSettingsTransfObj an extension method named ToFrameworkObj. All the extension methods I put in a single class. The name of the class can be whatever you want, but the class needs to be static. After this really hard and boring work you will be using the extensions on a single line.

Here is the whole picture:


About the second challenge - the actual transport between the server and the client:
Here as I said the choice was clear. WCF is the only way to transfer information when we talk about silverlight. So there was no other option for me but WCF. And I don't complain. WCF is marvelous. It is bullet fast, extremely stable, reliable and very flexible and easy to configure. But not everything is so pink with WCF services called from silverlight. The key thing here is that you can call operations of the service only in Asynchronous manner. This is a little bit tricky. In some scenarios you will need the synchronous calls desperately but sorry - you just can't do this. I spent a whole day to dig for a workaround in the Internet with no success. I don't exclude the chance that a workaround exists, I simply say that I didn't manage to find a real good one. One of the workarounds was actually helpful. It was using a separate thread for the call to the service operation and also it was using the BeginXXX and EndXXX methods of the service operation. However to assure the thread has finished its work and the call to the operation has returned a result I needed to block the main thread and join the service calling one. This is important: never block the main thread. The main thread appears responsible for handling the communication with the service API. So actually when blocking the main thread you get yourself in deadlock situation. The main thread is needed to handle the response from the service and as it is blocked it can't do that. Also the supporting thread can't finish its job while the call is in progress. Well I hope you got the picture, cause I can't explain it better. It is already blur for me, because it's a month since I fought that problem. But the picture was something like that. So I had to stick to the natural design, because the whole "thread using solution" didn't seem to be stable and reliable. The last thing related to the WCF part and its asynchronous calls is actually more like an advice. Whenever possible do call the service operations before they are actually needed. For example you have a form (or window if you like) that you use to edit object of type NodeSettings. This object lets say has a property that is collection of type SomeType. This collection you edit on a separate form that is shown when you click a button on the first form (a button saying for example "Edit Members"). So the best practice in my opinion is to call the operation that will return all the "members" of type SomeType before the user clicks the button. So to sum up: Call the operations ASAP! These calls are not expensive. WCF is very very fast.

The last one is the GUI. GUI has always been a pain in my ass. My designer abilities are are enough good to realize that my GUI sucks :). However with this project I had to face some issues. I will just mark them briefly, because this article became bigger than planned. First of all I consider a good practice to use a single instance of each form rather than creating and disposing one every time. So I have lots of hidden forms on the visible area of the silverlight application and I show/hide them according my needs. To pass data between forms I use events and stick the data in the args.
Also data can be shared between forms across the whole application by using Application.Current.Resources dictionary.

I hope you can get something valuable from this long and boring article :)

11.02.2010 г.

Back again...

Hello there,
it's been a while since I last posted on my blog. The reasons of course are many. First of all I didn't knew that somebody's actually reading my posts. So I was quite surprised when I read some comments on my older posts. Also I was glad, yes you got me right, glad when I saw the typical russian spam. That was to tell me that my blog is already indexed by Google. Hooray!

From now on I promise myself to write much more. Not that I'm some kind of software GURU and my post have a tremendous influence to the community, but I find it good to share some of my modest experience with the software technologies I work with and also some of the thoughts that my head gives birth of, before they are irretrievably gone.

So, I thought that now is the time to put some lines of text on my latest work experience. Also I'm now stuck for a week at home, sick, sniveling and quite bored. Sometimes I ask myself whether I prefer to be busy or to relax. And I always hate the answer, cause sadly resting I take now as wasting my precious time.

I'm working lately on a silverlight project and that gave me the opportunity to understand silverlight more deeply. Also I use Blend for a designer tool cause Visual Studio lacks a silverlight designer. I'm planning 2 post on that, one on silverlight and another one on Blend 2 and Blend 3.
Also I'm planning to write a substantial article about my opinion on what is going on in my home country Bulgaria. Of course it will be "hater like" one, cause things are getting worse and worse.