Wednesday, July 30, 2008

70-504 passed

Lets hope MS get that ADO .NET 3.5 done soon otherwise i'll have to do WPF!

Friday, July 18, 2008

Grab that icon with .NET

Many people just dont know there's a very easy way to get any program icon you need.
Here's the code
Icon icon = Icon.ExtractAssociatedIcon(@"C:\Program Files\Internet Explorer\iexplore.exe");
using (FileStream fs = new FileStream(@"c:\explorer.ico", FileMode.Create))
{
icon.Save(fs);
}

Sunday, July 13, 2008

Embedded resources and clean folder structure - yes you can.

If you have a bunch of embedded resources in a folder, the single most efficient way to get a stream to them is to create a dummy class in that folder. Aside from it being internal or public, it doesn't have to do a thing.
You then use the type of this object in calls to get this resource, eg Assembly.GetManifestResourceStream. With this type, the namespace is looked up for the folder, and the embedded items in it are effortlessly resolved.
eg:
Assembly.GetExecutingAssembly().GetManifestResourceStream(typeof(ImageResourceResolver), "myicon.ico");

Saturday, July 12, 2008

//You do not need to understand this

Maintenance programming... hated by most, yet essential.

Good things to do for the poor sod who has to maintain your code after you left:
  • Comment clearly and not too much
  • Put in a clear roundup what the function is supposed to do
  • ... add some explanation for your parameters
  • Keep speaking variablenames, but go easy on the length :)
  • Be consistent in these names.. p preceeds a pointer, s a string, i an integer and so on
  • Avoid pressing complicated statements into one line
Bad things to do:
  • Ignore all of the above
  • i is good, use often like nested for{} statements with i for the outer loop and ii for the next :)
  • Take extremely good care of your pointers and never set them to NULL when you free()
  • Place comments like //Taking care of X... when you do nothing the like

heheeh.... maintenance programming has its ups and downs. But you can make it hell if you like. If you happen to hop into a job where you get thrown at code that looks like the latter... I do not envy you :)

Saturday, July 5, 2008

Electronic flyswatter: The Art of Debugging

Among the less popular things about programming in general is debugging. It is a hassle to most people I know, yet an essential skill to master.

The first step to find a bug is to think while coding. Hacking away without reason and just grinding code without exercising your brainmuscles is futile. Believe me when I say that a well thought through codeflow is saving you quite some headaches in debugging.

Before you start coding make yourself a clear picture of what you want, how it should look and how it should flow. Expect that to be hard :)
Do whatever helps you, don't rely on what others tell you too much, as there is no perfect way. Use what works for you.. diagrams, UML or Post-It notes. It saves you time and gives you an overview of the program-to-be.

Step two is translating that into code. Here I mostly choose to have my own collection of ironcode. WTF? 'Ironcode' is code I use all the time, well tested and throught through (...ehhehe... in most cases well though through). It minimizes the possibility of errors... most of the time :)
KISS. Keep It Simple Stupid. Don't optimize too much. It is easier to get a working program to run fast than a fast program to run.

Avoid one-liners in the first iteration. I love oneliners like:
string ASCII = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(srLogFile.ReadLine()));
While it surely is not the most complicated thingy to do, it is surely stupid to do that untested. Try, for debugging, to split that into three or more lines. It is easier to debug (yes, and to read, I hear you, but maintenance programming is another topic).
When your code is ready to be shooed out of the sandbox, you can always tighten up things.

Step three is 'Know your tools'. Know your tools. Know how the debugger works, when to hit which key and watch your locals. Locals is your friend, the callstack tells you quite a lot about what happened before you crash.. or did not crash.. also a possibility in a multithreaded environment.
Speaking of which.. create a decent logger that is alive in your debug build. In most of the cases you cannot just 'stop, drop and roll' your program, e.g. Games. There a good logger is making your live a lot easier.

Step four is 'know the 'usual suspects''. I, when programming, have a list in my mind of those things that can go wrong. I build and test every function I create for obvious errors then stuff in a few lines of loggingcode to be prepared.

And the last, most important, step: 'Don't give up'!
See it this way: At least you have the sourcecode, you know the one who committed the cirme and you know all the things that sourround your program. The worst thing that can happen to you is reverseengineering buggy code with not the slightest idea what that program needs... believe me.. been there, done that, got the T-Shirt.

All in all this is not the yellow brick road to follow in debugging. Never thought of it that way, but it should take away the highest hurdles. Of course it is easy to say such things while having quite a bit of experience in that field. As always. But then... I also started sometime... heheeh... most people forget that...

Thursday, July 3, 2008

Division by Cucumber?

Today I let loose my latest thingy, which reads some logs and parses them into a FoxPro table. See my post on it here.

It was working fine while in the sandbox but screamed hell when I set it loose in the wild. It threw a 'DivideByZeroException' all the time. After a while of debugging and crawling through my code I ended up here:
  1. System.Data.OleDb.OleDbCommand Com = new System.Data.OleDb.OleDbCommand(Instrucions[i]);
  2. Com.Connection = conn;
  3. Com.ExecuteNonQuery();
Line 3 threw the exception... but why? The instruction looked like 'insert into tablename (Col1, Col2, Col3) values ('One','Two','Three other things added here')'.
Thing was that the first round with another table went fine and that SQLstatement was a lot more complicated! So... what gives?

Took me about 2 hours of fiddling, cursing and sniffing through my code I found out the cause:
'Col3' is a FoxPro Memofield... sheesh.. which creates the need for the corresponding 'tablename.FPT' in the directory where the free tables reside. After that it worked like a charm.

So... all the crap in the web about some complicated parameteradding and such is safely discarded. The only thing is that you should chop your strings that should go into the memofield into 255 charater pieces as FoxPro works with stringlaterals that hold 255 chars max :)

Hope I could push you a step further to enlightenment :)

Wednesday, July 2, 2008

Beauty is only GUIdeep

Softwareguy: 'So did you decide on the purchase of our NiftySoftware v2.01?'
Customer2b: 'Yes. And no, we won't buy. We'll buy Competitor v1.1.'
Softwareguy: 'Oh... well.. ok. May I ask what influenced your decision?'
Customer2b: 'Sure, because it looks a lot better and it feels better.'
Softwareguy: 'But we are faster, more refined and our databasehandling is top-of-the-line'
Customer2b: 'Well, but it looks ugly and I do not find anything I need.'

Now what is that all about? And what should we learn from this conversation?

Well... as much as your code may roxxor, your GUI is the face that sells the Application. A lot of books have been written about GUI designe, do's and don't's and quite a few by Pschologists who explain how it reflects in various ways on the workflow of ones brain.

So how to design the perfect GUI? Easy: You don't!
There is nothing like a 'perfect' [insert whatever here]. The thing I learned over all of these years is that you should, in the best possible case, be proficient in the trade. And I do not mean GUI design or programming. I am aiming at the profession you write the programm for. Let me elaborate on that:
You can write a CRS software, an accounting software or a Qualityassurance software without special training. You just get book (well... not 'just', but you get the hang of it) and read up on the procedures and algorythms involved and hack away. There is always a logic pattern you can beat out of things and translate to code.
But (<- the catch) you do not know what the user looks for. In everyday usage of a program some things need to be visible to the trained eye. And some things need to be accessible even for the... uh... how to say... not-so-techy-people-who-barely-know-how-to-logon.
Everybody has their own workpace and -path. But somethings are universal to the trade. Get to know those. Have a feel for the work, the job and the people.

Hm... not sure if I made my point.... to put it short: The customer does not give the slightest bit of a poo if your code beats 100,000 SQL instructions into a database in 10 seconds. He also is not too impressed if your code is 100 lines less than your competitors.
He sees: 'Clean design, nice grouping of the [important things]'

Realworld example:
We designed a program to manage the workload in a carrepairshop. By looking how they work we designed the GUI to display the free workers on almost 70% of the screen. The customer loved that 'I can see who has the most time on their hands!'. After he doubleclicked a worker, assigned a task and got the option to priorize the work the thingy was sold.


For the finale:
I am not sure this helps you. We work that way and we really get a bang out of it. And... well... for all it is worth we have a 99% customersatisfaction rating for the 5th year in a row (that is how long I am with this company now). And I am proud about that :)

XmlUrlResolver: a free stream to almost anything

Well, I'm not sure if its a good practise, or if there are any better classes to achieve this goal.
But I often use an XmlResolver (wich is the abstract type, or the concrete version is the XmlUrlResolver) to get a stream to any file or uri alike without the fuss of handling http requests etc.

Just use the XmlResolver function like this:
XmlUrlResolver resolver = new XmlUrlResolver();
using (Stream stream = resolver.GetEntity(new Uri(filename), string.Empty, typeof(Stream)))
{
//do stuff with the file
}

This saves gives you a lot of extra flexibility in terms of where you can put your files. Eg some files can now come over FTP or HTTP.

On a lighter note, I scheduled my Workflow Foundation MCTS exam. Wish me luck.

Tuesday, July 1, 2008

Declarative workflows: Could not deserialize object. The type '' could not be resolved.

This is mainly a reminder for myself.
When you get this error
a) check that you've added a reference to the needed assembly using a type provider for your workflow
b) check the xml itself of your workflow: the namespace of the item that couldnt be deserialized is possibly incomplete. It needs to be a fully qualified namespace. And this is where the editor screws up a little if it's not in the GAC.

For example, the editor has a tendency to create only:
xmlns:ns0="clr-namespace:Company.Lib.Activities
but it should create
xmlns:ns0="clr-namespace:Company.Lib.Activities;Assembly=Company.Lib.Activities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

(it's missing the assembly qualifier in the namespace declaration, wich you need to resolve the activity). Not specifying version, culture and publickeytoken works just the same.

With these two tips you can generally resolve the 'Could not deserialize object'-errors.

Dinner's ready, I already filled the FoxPro table!

Fighting my way through C# and its various... uh... specialities I ran head on into the problem of filling a FoxPro table. Being the smart guy I ventured to the Internet and looked for a solution.

Problem:
A directory of free tables to which I want to connect via C#.

Internet solution:
  1. Download the Visual FoxPro 9.0 OLEDB driver
  2. Install (duh :) )
  3. 'using System.Data;'
  4. Jump around to Connectionstrings.com and get the correct connectionstring
  5. Start filling that table!
Well so far so good, this is what I got (edited so it fits this layout):

  1. string vfpConnectionString="Provider=vfpoledb.1;Data Source=C:\\temp\\fptest\\;Collating Sequence=general;";

  2. conn = new System.Data.OleDb.OleDbConnection(vfpConnectionString);
  3. conn.Open();
  4. System.Data.OleDb.OleDbCommand Com = new System.Data.OleDb.OleDbCommand("[SQL goes here]);

  5. Com.Connection = conn
  6. Com.ExecuteNonQuery();
  7. conn.Close();
Now then... away with testing and... behold... nothing. WTF? The driver is not registered? Okies... go intall again... poo... no luck... what gives? After another round of doing the same... the same.. hehehe... not registered [instert heavy cursing on MS, SQL, FoxPro and Windows].
'Oh crap on FoxPro... I go to bed'

[Birds chirping] Next day at work:
Installed the same sequence again... WOW! Works! What gives?

Now then... education starting, sit down, be quiet and read up:

If you have, like me, a Vista64 Ultimate at home and a Vista32 Business at work... you get the drift? Yes! No 64bit with the FoxPro drivers! [claps] Very good! Get a Snickersbar and be proud.

Solution? Easy:
  1. Create your FoxPro-Accessing-Application-to-be
  2. Go to 'Build' -> 'Configuration Manager...'
  3. Find your Project (should be easy if you only have one in there)
  4. Click on the 'Platform' DropDown and choose ''
  5. 'New Platform' and choose 'x86' and '>'
  6. 'Ok' everything, make sure 'x86' is set as target CPU
  7. Build and frolic
Now you can use the FoxProtables as if they were 'normal' tables in a database. Meaning:
'Select * from ste_q3 where current=3.35'

Oh and by the way I recommend DBFManager which is quite a powerful (and inexpensive) way to sniff around in those tables without having FoxPro installed.

I hope I saved at least a bit of someone's troubles with this :)

Oh.. and I just read up on static variables in functions and C#... I go on with that in the next post, because it is a separate thing to rant about :)