Wednesday, July 30, 2008

First time Windows Vista or Disillusion in 30 minutes

I just got my brand new retail PC sold with Vista Home Premium from Atelco, decent seller for computer related products in Deutschland (Germany). So I expect that Atelco had put some though in their configuration, what is working best with Vista. It even came not just with Vista, it came with Vista SP1 preinstalled.

After hitting the market for over a year and with SP1 I was willing to take the challange.....

It took me 30 minutes until I wrecked my Vista for the first time.

Until the installation I got the installer error: "Error 1628: Failed to complete script based install". Too late I found a promising link so I decided to reinstall.

In total I reinstalled it 2 times this night. The first upgrade install did not fix the problem, so I had to do another complete reinstall.

But this was not the end of disappointments.

The next was named Bluetooth. I had a simple USB Dongle. After I personally found it disappointing that Microsoft had failed to ship XP with proper Bluetooth support, I was absolutely convinced that it would be no problem at all to connect my Microsoft Bluetooth keyboard and mouse as well as my Nokia N95 mobile with Vista.

Well think again. Although keyboard and mouse seemed to work at first, it soon turned out that after a certain time (between 1 hour and 1 minute) the keyboard would delay every key pressed for 10 seconds or more. Not really the ideal solution for playing an ego shooter game.
Even worst was my mobile. I got a lot of installation errors (sync profile) errors, that from now on popped up every time I started my Vista.
When I googled for the problem it soon turned out that the Bluetooth stack that comes with Windows Vista is complete crap. If you want to use Bluetooth you still need to install a 3rd party bluetooth stack.

Apart from that I already had a blue screen during boot (bad_pool header), I have a disc usage of almost 80 gigs without anything installed, the disc is running with intense activity for no obvious reason, the icons use up space like nothing, the program menu looks like crap, the permanent questioning to authorize this and that sucks like hell.

Just today I heard a story from a real good IT guy, who had the following problem. After starting his Vista Laptop in a Windows 2003 Server controlled domain, his Vista would start and connect fine the first time, but when you shutdown or reboot this was the last time your Vista will ever connect to ANY network.
The reason is that the server distributes a group policy (which is aimed at XP Workstations). Once Vista applies the group policy it disables everything that is not explicitily allowed. And this includes various network services. Even worse. Even the administrator won't be able to revive the services ("Access denied") and you won't ever be able to connect to any network!
This means under certain circumstances your Vista will commit suicide.

But apart from the fact that Vista is big, bloated, unstable, confusing and a potential suicide candidate, what are the advantages compared to XP?

...
.....
........
...........

(Still thinking)

Friday, July 25, 2008

Adding FlatWSDL to WCF WebService

WCF WebServices in a UDDI Environment

Download the SourceCode

If it comes to the point where you want to integrate your WCF WebServices into a UDDI environment you will stumble accross a feature introduced in WCF.

By default you will find in the WSDL types section:

<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:3826/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/" />
<xsd:import schemaLocation="http://localhost:3826/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="http://localhost:3826/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/MyFirstWCFService" />
</xsd:schema>
</wsdl:types>


Looks great, but here it is causing a problem. Using a UDDI means you bind your Service at runtime. To do so you need a WSDL that contains only the abstract informations. But "http://localhost:3826/Service1.svc?xsd=xsd0" ist not very abstract, right?

You have 3 choices now.
a.) You have always your service at the given adress up and running.
This would just negate the whole UDDI concept.
b.) Load every data schema by hand, and replace the include statement with real schema. By hand. This is pain in the ass. Especially when you deal a number of datatypes from different namespaces.
c.) You find a way to somehow flatten your WSDL.

As I did not like a.) or b.) I looked for c.) and luckily stumbled across the articles of Tomas Restrepo and Cristian Weyers. Christian even provides the source for download and their FlatWSDL does a nice job. Thanks guys!

But their example was related to self-hosted services. As I mainly try to run IIS based WCF Services I came on day to the point where I had to integrate FlatWSDL with an IIS based WCF Service.

The problem. You do not directly control the ServiceHost object and thus

foreach(ServiceEndpoint endpoint in selfHost.Description.Endpoints)
endpoint.Behaviors.Add(new FlatWsdl());

won't work here.

But Ok then. Everything related to ServiceHost Configuration you can do either in Code or via the ConfigFiles. The WCF Config Editor is really a great help here.

So I just added FlatWSDL.cs to my project, recompiled it and fired up the WCF ConfigEditor.

The first step is to register FlatWSDL as a "behaviour element extension" what can be done under the "Advanced - Extensions" tab.

There is a button "New". Enter a Name, pick your Service.DLL and select.....

nothing.... which is about the whole choice you have.

When I googled for "wcf add custom endpoint behaviour config" I again stumbled accross an article from James Bender where he also implements an IEndPointBehaviour but here he derives his behaviour class from the abstract class BehaviorExtensionElement as well.

Related to BehaviorExtensionElement the help says:
"Represents a configuration element that contains sub-elements that specify behavior extensions, which enable the user to customize service or endpoint behaviors."
"Sounds great" I thought and derived the FlatWSDL class from BehaviorExtensionElement. So your class definition now looks like
using System.Collections;
using System.Collections.Generic;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Xml.Schema;
using ServiceDescription = System.Web.Services.Description.ServiceDescription;

namespace SCDServices.ServiceImplementation
{
/// <summary>
///
/// </summary>
public class FlatWsdl : BehaviorExtensionElement, IWsdlExportExtension, IEndpointBehavior
{
    public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
    {
    }

    public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
    {
        XmlSchemaSet schemaSet = exporter.GeneratedXmlSchemas;

        foreach (ServiceDescription wsdl in exporter.GeneratedWsdlDocuments)
        {
            List<XmlSchema> importsList = new List<XmlSchema>();

            foreach (XmlSchema schema in wsdl.Types.Schemas)
            {
                AddImportedSchemas(schema, schemaSet, importsList);
            }

            wsdl.Types.Schemas.Clear();

            foreach (XmlSchema schema in importsList)
            {
                RemoveXsdImports(schema);
                wsdl.Types.Schemas.Add(schema);
            }
        }
    }

    private void AddImportedSchemas(XmlSchema schema, XmlSchemaSet schemaSet, List<XmlSchema> importsList)
    {
        foreach (XmlSchemaImport import in schema.Includes)
        {
            ICollection realSchemas =
            schemaSet.Schemas(import.Namespace);

            foreach (XmlSchema ixsd in realSchemas)
            {
                if (!importsList.Contains(ixsd))
                {
                    importsList.Add(ixsd);
                    AddImportedSchemas(ixsd, schemaSet, importsList);
                }
            }
        }
    }

    private static void RemoveXsdImports(XmlSchema schema)
    {
        for (int i = 0; i < schema.Includes.Count; i++)
        {
            if (schema.Includes[i] is XmlSchemaImport)
                schema.Includes.RemoveAt(i--);
        }
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    public override System.Type BehaviorType
    {
    get { return typeof(FlatWsdl); }
    }

    protected override object CreateBehavior()
    {
    return new FlatWsdl();
    }

    #region Ctor

    /// <summary>
    /// Default constructor.
    /// </summary>
    public FlatWsdl()
    {
    }
    #endregion
    }
} 


1.) We compile and fire up the config editor again.
We go to "Advanced - Extension - behaviour element Extension" and press new.
Now we browse to our Service.DLL in the bin directory and Bingo!



We select Thinktecture.ServiceModel.Extensions.Description.FlatWsdl from the List.

2.) We now browse to "Advanced - Endpoint Behaviours" und press "New Endpoint Configuration"
We enter a name (here MexFlatWSDLBehaviour), press "Add" and select FlatWSDL from the List.



In case there is no FlatWSDL in the List, save, close and reopen the ConfigEditor. It now complains that it can't find the DLL file. Press "Yes" browse to our Service.DLL in bin directory and click "Yes" when the editor warns you it is going to execute some code.
Now at latest there should be FlatWSDL in the list.

3.) Now add the newly created Endpointbehaviour to our ServiceEndPoint (not the mex endpoint).
You can recognize your ServiceEndpoint as the "Contract" attribute points to your ServiceInterface.
For "BehaviourConfiguration" select our "MexFlatWSDLBehaviour" from the list.


Done

When you now check the WSDL emitted from our WCF WebService you will find nice inline type schemas.

<wsdl:types>
<xsd:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<xsd:element name="HelloWorld">
<xsd:complexType>
<xsd:sequence />
</xsd:complexType>
</xsd:element>
<xsd:element name="HelloWorldResponse">
<xsd:complexType>
 <xsd:sequence>
    <xsd:element minOccurs="0" name="HelloWorldResult" nillable="true" type="xsd:string" />
 </xsd:sequence>
</xsd:complexType>
</xsd:element>



Christian had found another approach through a custom ServiceHost and custom ServiceHostFactory. Look at the bottom of the article.

I recommend taking a look at WCFExtra. They just released Version 2. Among others it brings single WSDL support out of the box.

Download the SourceCode

Thursday, July 24, 2008

Must have Development Tools

ProcessExplorer

Gives you many details on running processes. Including IP Connections etc. Although these functions are really nice, the "Find Handle or DLL" functionality is a real life saver.

Every Developer gets the error message "can not access file because it is used by another process" once in a while.

But which programm/process is it? This is where the "Find Handle or DLL" functionality enters the stage. Simply enter the filename, and Process Explorer will tell you who is sitting on your file.





Web(Service)-Development

Fiddler

Fiddler is a HTTP Debugging Proxy which logs all HTTP traffic between your computer and the Internet.



.NET

Lutz Roeder's Reflector

Excellent Tool for .NET Assembly reverse-engineering. Many plug-Ins available

Subversion & TortoiseSVN & Ankhsvn

Subversion is a versioning system and TortoiseSVN is the fitting Subversion explorer client, implemented as a windows shell extension.
Ankhsvn makes these 2 a dream team as in brings a Visual Studio 2005 & 2008 plugin, that allows you to handle most tasks directly from within Visual Studio.

Once you understood the concept of versioning and Subversion you never want to live without it. Even for standalone developers it makes perfectly sense to use it. You need no server component, simply create your repository on your disc or filesystem, import in your stuff, checkout and never worry again about versions or unlucky modifications.

Thursday, July 17, 2008

Walktrough for mediawiki on Windows IIS - The gory details

I have the following setup:

Windows Server 2003 with Inernet Information Server 6 (IIS 6) running. So installing Apache is not an option.

First of all.

It works with no limitation. Even with complete Email-Support.


For running mediawiki you need:

mySQL (I used 5.0.51)
the MySQL GUI Tools
Php (I used 5.2.6)
mediawiki of course 1.12)
FastCGI for IIS 6
DiffUtils for Windows (Optional but useful)
ImageMagick (Optional)


A. Install ImageMagick

Just run the installer and remeber the path.

B. Install DiffUtils


Just run the installer.

1. Install FastCGI

Simply run the installer

2a. Install mySQL


Simply run the installer. Not much to do here. Remember the Password of the "root" user. You will need it later to autocreate the mediawiki Database.

2b. Install the MySQL GUI Tools
Simply run the installer.

3. Install PHP

Installation

This is more tricky.

When asked for the Web Server Setup choose :

IIS FastCGI

I chose the following Extension (do not select all):

MySQL

MySQLi
OpenSSL

Enable the following Extra

Pear Install

After setup completed

Configuration

Modify php.ini

Under Start - Programms - PHP 5 you find php.ini

Edit the following parameter:

fastcgi.impersonate = 1;

Modify fastcgi configuration fcgiext.ini file for php support

Click Start - Run and slap in

%WINDIR%\system32\inetsrv

Open fcgiext.ini in Notepad and add at the bottom

[Types]
php=PHP

[PHP]
ExePath=D:\Program Files\PHP\php-cgi.exe
InstanceMaxRequests=10000
EnvironmentVars=PHP_FCGI_MAX_REQUESTS:10000


Make sure the Exepath reflects the path to your PHP installation!

If you get the error:

FastCGI Error
The FastCGI Handler was unable to process the request.

Error Details:

* Could not find entry for "php" on site 1 in [Types] section.
* Error Number: 1413 (0x80070585).

* Error Description: Invalid index.


HTTP Error 500 - Server Error.
Internet Information Services (IIS)

you did not edit fcigext.ini properly

See also the full description here

Install MediaWiki to IIS

Installation

Create a directory for you wiki under the wwwRoot Dir of IIS ( I used "wiki" in this case)

Extract the mediawiki-1.12.0.tar.gz to the "wiki" IIS directory.

Modification of config/index.php installer script

If you installed the DiffUtils:

Go to the wiki/config/ directory and edit the file index.php

Find the line:

$diff3versioninfo = array( '$1 --version 2>&1', 'diff3 (GNU diffutils)' );

and replace with:

$diff3versioninfo = null ;

If you get the Message:

PHP Warning: shell_exec() [function.shell-exec]: Unable to execute 'D:\Program Files\GnuWin32\bin\diff3.exe --version 2>&1' in F:\secureinet\wwwroot\wiki\config\index.php on line 1824

you did not edit this line.

If you installed the ImageMagick:

Go to the wiki/config/ directory and edit the file index.php

find the line:

$imcheck = array( "/usr/bin", "/opt/csw/bin", "/usr/local/bin", "/sw/bin", "/opt/local/bin" );

and replace it with

$imcheck = array( "", "D:/MYPATH/ImageMagick-6.4.2-Q16", "/usr/local/bin", "/sw/bin", "/opt/local/bin" );

Remember to replace MYPATH with the correct path and to turn Backslash \ into Slash /

find the line

$im = "$dir/convert";

and replace with:

$im = "$dir/convert.exe"

Configure the wiki directory settings in IIS

Start - Settings - Administrative Tools - Internet Information Services

Configure the "wiki" directory appropriatly. To be honest I just enabled everything:

Script source access, Read, Write,Directory Browsing and Execute Permissions on Script and Executables.

For me it is fine as I use the wiki in the intranet. For Internet usage this could be potentially insecure. Post a comment if you know what the best settings are.

Edit the permissions on the config Directory.

In explorer go the wiki directory

Configure file permissions by rightclicking the "config" directory, go to the security tab and add "Everyone" with Permission "Full Control". The directory should be deleted anyway after the installation so it does not matter.

If you get the error message:

PHP Warning: fopen(LocalSettings.php) [function.fopen]: failed to open stream: Permission denied

you do not have permissions to write the file.

Create the mediaWiki

Now start the Browser and slap in the URL

http://MyServer/wiki/config/index.php

If you have installed diff and ImageMagick it should come up with the message that they have been found.

  • Choose a name for your wiki
  • Enter a wiki admin Password (and remember it)
  • Disable all Email Options including email authentication (they won't work out off the box. All options can be enabled later)

Choose
  • a Database Name
  • a Wiki Database Username and Password.

If the user and database do not exist, you must check the "Use superuser account" option. In this case the database and the user will be created for you. Put in the password of your MySQL root user.

All the rest leave unchanged.

Now hit the install Button and you should get a lovely success message.

Now go to wiki/config directory and copy the LocalSettings.php file into the wiki directoy. If you use mediaWiki in the internet you should delete the config directory now.

Now slap in http://MYSERVER/wiki/index.php and you should get a warm welcome on your newly created media wiki.

Nice!


Email Support for mediawiki on Windows IIS

Remember I recommended to install the PEAR Extra during PHP Setup? (If you forgot, you can simply rerun the installer and modify the installation)

Go to your PHP programm directory and run the pear.bat.

This will ask you a bunch of questions. I simply confirmed each recommendation by return.

After the installation you find a PEAR_ENV.reg . Double click it to add the configuration to the registry.

Create an Includes Directory in your PHP programm directory.

Modify php.ini

Under Start - Programms - PHP 5 you find php.ini

After installing PEAR your should have something like this. Edit the following parameter:

include_path=".;D:\Program Files\PHP\pear"

to

include_path = ".;D:/INSTALLATIONPATH/PHP/includes;D:\Program Files\PHP\pear"

Remember to adapt the path to reflect the correct path to your PHP directory.

On Windows make sure you do use ; and not : as seperator!

I had some strage issues, where the change of my include path was not reflected in the running php scripts. To avoid unnecessary stress it is advisable to reboot the server now.


Now Download Pear Mail Package (I used 1.2.0b1)

Extract the folders to your newly created include folder.

Now Create a folder "Net" in your "includes" folder

Download Pear Net SMTP Package (I used 1.3.1)
Download Pear Net Socket Package (I used 1.0.9)

Extract the folders to your newly created includes/Net folder.

your INSTALLATIONPATH/PHP/includes folders should now look like this:

[Mail]
[tests]
Mail.php
[Net]/SMTP.php
[Net]/Socket.php
[Net]/[Docs]

and some other subdirectories.


Now go to your wiki directory and edit the file LocalSettings.php

Configure the Mail-Server by adding the following to your LocalSettings.php

$wgSMTP = array (
"host" => 'mymailserver.somewhere.com',
"IDHost" => 'myDomain.com',
"port" => "25",
"auth" => false
);

if you need authentication use

$wgSMTP = array(
'host' => "mymailserver.somewhere.com",
'IDHost' => "myDomain.com",
'port' => 25,
'auth' => true,
'username' => "my_user_name",
'password' => "my_password"
);

To Enable User Emails

find the lines:

$wgEnableEmail = false;
$wgEnableUserEmail = false;

and set to

$wgEnableEmail = true;
$wgEnableUserEmail = true;

To Enable WatchList Notification

find

$wgEnotifWatchlist = false; # UPO

and set to

$wgEnotifWatchlist = true; # UPO

Remember you have to enable Email Notification for your Watchlist in your user profile as well.

Done.

Have fun with a fully operational wiki on Windows and IIS.

Btw.

If you are looking for WYSIWYG Editor have a look at fckeditor. A bit tricky to set up, but awesome. I am using version 2.6.2.

For source code syntax highlighting have a look at the Geshi extension