Min första Windows phone 7 app

Igår var jag på appslöjd med Microsoft och gjord min första Windows Phone 7 app. Det gick förvånansvärt bra och enkelt var det. Appen är klar, men tyvärr kan jag inte publicera den på marketplace då jag inte tycker att det är värt att betala 99$ årligen för utvecklar-licensen.

Då min app ska vara en gratisapp som max ett hundratal personer skulle använda så är det inte ekonomiskt motiverat att lägga upp den. Så tyvärr Microsoft, eran prismodell för WP7 passar inte för hobbyutvecklare av småskaliga appar. Det känns nästan som att man motarbetar sådana.

Androids prismodell med en engångsavgift på 25$ dollar känns här betydligt mer rimlig. Det priset är satt för att få bort de värsta HelloWorld-apparna men utan att skrämma bort hobbyutvecklarna. Det finns väl inget syfte med att motverka utvecklare till den egna plattformen kan man tycka som i WP7 fallet. Apple Ios-utvecklare får tydligen också betala samma summa.

Inkomsterna som dessa bolag får av utvecklarna borde vara försumbar i det stora hela. Den enda anledningen till denna barriär, som jag kan se det, är att genom att ha en relativt hög avgift så får man upp kvaliteten på apparna som publiceras. Det genom att de som satsar på att utveckla till en plattform verkligen ser till att jobba med sina appar med motiveringen att om man betalar en relativt hög avgift så vill man utnyttja det till fullo. Något som en hobbyutvecklare kanske inte har råd/tid med på samma sätt.

Så lite besviken är jag ändå på Microsoft att min app inte kan publiceras på marketplace under rådande omständigheter. Om Windows Phone får en större spridning så skulle jag omvärdera mitt beslut att inte publicera, men i dagsläget så är det inte värt det.

Analyzing column sizes in csv files

I had this problem with a rather big csv file. I needed to find the maximum length of each column in the file. This could probably be solved rather easily with M$ Excel, but anyway it is much more fun to write a program. It is rather crude but works.—

Download the CSV-checker (executable)
Download source-code (visual studio 2005)

Command line syntax
CSV-checker.exe filepath delimeter

Program output

----------- FILE ANALYZED -----------
Column nr | Column name | Max length
-------------------------------------
1 | Columname | 2
2 | Columname | 37
3 | Columname | 3
4 | Columname | 44
-------------------------------------
Nr of columns: 4
Nr of rows: 2701
Nr of chars: 2117584

using System;
using System.Collections.Generic;
using System.Text;

namespace CSV_checker
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // check arguments
                if (args.Length < 1)
                {
                    Console.WriteLine("Missing file argument");
                    Environment.Exit(-1);
                }
                else if (!System.IO.File.Exists(args[0]))
                {
                    Console.WriteLine("That file does not exist");
                    Environment.Exit(-1);
                }

                // set delimiter
                char delimiter = ';';
                if (args.Length > 1 && args[1] != "" && args[1].Length == 1)
                {
                    delimiter = char.Parse(args[1]);
                }

                // read file
                string[] lines = System.IO.File.ReadAllLines(@args[0]);
                int nrColumns = lines[0].Split(new char[] { delimiter }).Length;
                int[] maxColumns = new int[nrColumns];
                string[] columnNames = new string[nrColumns];
                long nrChars = 0;

                // analyze file
                for (int i = 0; i < lines.Length; i++)
                {
                    string[] parts = lines[i].Split(new char[] { ';' });
                    for (int j = 0; j < parts.Length; j++)
                    {
                        nrChars += parts.Length;
                        if (i == 0)
                        {
                            columnNames[j] = parts[j];
                        }
                        else if (parts[j].Length > maxColumns[j])
                        {
                            maxColumns[j] = parts[j].Length;
                        }
                    }
                }

                // Print results
                Console.WriteLine("----------- FILE ANALYZED -----------");
                Console.WriteLine("Column nr | Column name | Max length");
                Console.WriteLine("-------------------------------------");
                for (int i = 0; i < nrColumns; i++)
                {
                    Console.WriteLine(i + 1 + " | " + columnNames[i] + " | " + maxColumns[i]);
                }
                Console.WriteLine("-------------------------------------");
                Console.WriteLine("Nr of columns: " + nrColumns.ToString());
                Console.WriteLine("Nr of rows: " + lines.Length);
                Console.WriteLine("Nr of chars: " + nrChars);

                //Console.ReadLine();

            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: " + ex.Message);
            }
        }
    }
}

How to install a shared network printer with VB.NET and WMI

Today I show you an example of how to install a network printer with VB.NET and WMI by using the AddPrinterConnection method of the wmi Win32_Printer class. Just replace hostname with the name of the printserver/workstation and queuename with the shared printer queuename.

        Try

            Dim scope As ManagementScope = New ManagementScope("root\CIMV2")
            scope.Options.Impersonation = ImpersonationLevel.Impersonate
            scope.Connect()

            Dim path As New ManagementPath("Win32_Printer")
            Dim mgtClass As New ManagementClass(scope, path, Nothing)

            Dim inputParameters As ManagementBaseObject = mgtClass.GetMethodParameters("AddPrinterConnection")
            inputParameters("Name") = "\\hostname\queuename"

            Dim outputParameters As ManagementBaseObject = mgtClass.InvokeMethod("AddPrinterConnection", inputParameters, Nothing)
            Dim returnValue As UInteger = UInteger.Parse(outputParameters("ReturnValue"))

            If (returnValue = 0) Then
                Console.WriteLine("Success")
            ElseIf (returnValue = 5) Then
                Console.WriteLine("Access Denied")
            ElseIf (returnValue = 1801) Then
                Console.WriteLine("Invalid Printer Name")
            ElseIf (returnValue = 1930) Then
                Console.WriteLine("Incompatible Printer Driver")
            End If

        Catch ex As Exception

        End Try

How to create a printerqueu with .NET and WMI

This is an example of how you create a printerqueue with .NET and WMI (Windows Management Instrumentation).

A list of properties can be found at MSDN Win32_Printer

Other topics:
How to install printerdrivers with wmi and VB.NET
How to create TCP/IP printerports with .NET

Imports System.Management

Dim shared as Boolean = true

Try
 Dim mp As ManagementPath = New ManagementPath("Win32_Printer")
 Dim co As ConnectionOptions = New ConnectionOptions()
 co.EnablePrivileges = True
 co.Impersonation = ImpersonationLevel.Impersonate
 
 Dim ms As ManagementScope = New ManagementScope("\\" + Environment.MachineName + "\root\cimv2", co)

 Dim printerObject As ManagementObject = New ManagementClass(ms, mp, Nothing).CreateInstance()
 printerObject("PortName") = "IP_192.168.0.2"
 printerObject("DriverName") = "DriverName"
 printerObject("DeviceID") = "queuename"
 printerObject("Location") = "Placement of printer"
 printerObject("Comment") = "Some comments"

 If (shared) Then
  printerObject("Shared") = True
  printerObject("ShareName") = "Sharename"
  'printerObject("Published") = False ' Publish printer
 End If

 Dim options As PutOptions = New PutOptions()
 options.Type = PutType.UpdateOrCreate
 printerObject.Put(options)

Catch ex As Exception
 ' Do something
End Try

Install printerports with WMI and VB.NET

This is an example of how you install TCP/IP printerports with .NET and WMI (Windows Management Instrumentation).

A list of properties can be found at MSDN Win32_TCPIPPrinterPort

Other topics:
How to install printerdrivers with wmi and VB.NET
How to create a printerqueu with .NET and WMI

Imports System.Management

Try
  Dim mp As ManagementPath = New ManagementPath("Win32_TCPIPPrinterPort")
  Dim co As ConnectionOptions = New ConnectionOptions()
  co.EnablePrivileges = True

  Dim ms As ManagementScope = New ManagementScope("\\" + Environment.MachineName + "\root\cimv2", co)

  Dim port As ManagementObject = New ManagementClass(ms, mp, Nothing).CreateInstance()
  port.SetPropertyValue("Name", "portname")
  port.SetPropertyValue("Protocol", 1)
  port.SetPropertyValue("HostAddress", "10.15.12.12")
  port.SetPropertyValue("PortNumber", "9100")

  Dim po As PutOptions = New PutOptions()
  po.UseAmendedQualifiers = True
  po.Type = PutType.UpdateOrCreate
  port.Put(po)
Catch ex As Exception
  ' do something
End Try

Install printerdrivers with WMI and VB.NET

This is an example of how you install printerdrivers with .NET and WMI (Windows Management Instrumentation). Most examples on the Internet shows how this can be done with vbscript, printui.dll and such…

A list of properties can be found at MSDN Win32_PrinterDriver

Other topics:
How to install printerports with WMI and VB.NET
How to create a printerqueu with .NET and WMI

Imports System.Management

Dim infPath  as String = "c:\driver\printerdriver.inf"
Dim mp As ManagementPath = New ManagementPath("Win32_PrinterDriver")

Dim co As ConnectionOptions = New ConnectionOptions()
co.EnablePrivileges = True

Dim ms As ManagementScope = New ManagementScope("\\" + Environment.MachineName + "\root\cimv2", co)

Dim mcPrinterDriver As New ManagementClass(ms, mp, Nothing)
mcPrinterDriver.SetPropertyValue("Name", "drivername")
mcPrinterDriver.SetPropertyValue("SupportedPlatform", "Windows NT x86") ' x86-architecture
'mcPrinterDriver.SetPropertyValue("SupportedPlatform", "Windows x64") ' x64-architecture
mcPrinterDriver.SetPropertyValue("Version", 3)
mcPrinterDriver.SetPropertyValue("FilePath", System.IO.Path.GetDirectoryName(infPath))
mcPrinterDriver.SetPropertyValue("InfName", infPath)

Dim inParams As System.Management.ManagementBaseObject = Nothing
inParams = mcPrinterDriver.GetMethodParameters("AddPrinterDriver")
inParams("DriverInfo") = CType(mcPrinterDriver, System.Management.ManagementBaseObject)
Dim outParams As System.Management.ManagementBaseObject = mcPrinterDriver.InvokeMethod("AddPrinterDriver", inParams, Nothing)

Dim uiReturnValue As UInteger = System.Convert.ToUInt32(outParams.Properties("ReturnValue").Value)

I have tested this in Windows XP, Windows 7 and Windows 2008R2. Make sure your account has privileges to install drivers.

On Windows XP the drivers are installed physically to:
C:\WINNT\system32\spool\drivers

And in the registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments

Mid Sweden Technology Conference i Sundsvall

Den 9 september så var jag på Mid Sweden Technology Conference på Folkets Hus här i stan. Det var en trevlig tillställning som arrangerades av Åkroken Science Park AB. Man förklarade att det skulle bli en återkommande konferens med fokus med utveckling och teknik inom Microsoft-området och denna gång så låg fokuset på ”Windows 7”.

Programmet var följande:

08.00-08.30 Registrering

08.30-09.30 Arbeta smart (Nils Morén, XLENT)

09.45-10.45 Nytt försäkringssystem i .NET (Thomas Hellström, SPV)
Thomas Hellström är ansvarig arkitekt i ett pågående projekt på Statens Pensionsverk som syftar till att utveckla ett nytt försäkringssytem med den största delen på .NET plattformen. Thomas kommer berätta om de utmaningar som ställs på ett sådant system och de tekniska lösningar som valts.

11.00-12.15 Azure (Johan Lindfors, Microsoft)
Windows Azure består också av tjänster som SQL Azure och .NET Services. Dessa kan användas både i molnet och från lokalt installerade applikationer. Här visar vi på exempel och demonstrerar teknikerna som redan idag finns tillgängliga för utvecklare!

12.15-13.15 Lunch

13.15-14.00 Windows 7 (Magnus Jungåker, Microsoft)
Windows 7 är ett modernt operativsystem som alla kan använda och företag sparar mycket på att rulla ut som standartklient. Vi har fokuserat på att utveckla de fundamentala egenskaperna som prestanda, kompatibilitet, säkerhet och stabilitet. Vi lägger också till funktionerna DirectAccess och BranchCache. Vi har förbättrat sök och hårddiskkrypteringsfunktionerna. Men vi har framförallt gjort ett operativsystem som gör användaren mer produktiv och företaget effektivare.

14.15-15.15 Virtualization (Magnus Jungåker, Microsoft)
Med Live Migration i Windows Server 2008 R2 och Server Management Suite Datacenter har Hyper-V blivit en mogen och fullfjädrad servervirtualiseringslösning. På klientsidan har Microsoft i Desktop Optimization Pack (MDOP) och Virtual Enterprise Centralized Desktop(VECD) alla teknologier på plats för att även virtualisera klientsidan.

15.30-16.45 Rika klienter (Robert Folkesson, Microsoft)
I den här sessionen visas hur rika klienter kan dra nytta av ny funktionalitet i Windows 7 som Taskbar notifications, Jump Lists och federerad sökning. Vi visar också de nya möjligheterna som Multi-touch ger och undersöker hur stödet för detta kommer att se ut i .NET Framework 4 och Windows Presentation Foundation.

17.00-18.00 RIA Arkitektur (Fredrik Normén, Cornerstone)
Fler och fler affärs applikationer flyttas till målnet , fler och fler användare vill a bättre användarupplevelse. Enligt Gartner Research, så är 60% av all nya applikationer skapade som RIA under 2010. I denna session så får du lära dig hur arktietkturen för en RIA kan se ut, vad man bör tänka på etc när man utvecklar RIA.

windows7

Mina Synpunkter
Jag tycker att det var intressant att lyssna på Thomas Hellström från SPV och hans tankar om deras .NET utvecklingsprojekt. Han undertryckte bla. vikten av att testa sina ideer med proof-of-concept lösningar, och det är något som jag själv gillar väldigt mycket. Det är viktigt att testa sin design med en enkel modell innan man börjar bygga något stort.

Sedan så var det intressant att höra föreläsarna från Microsoft tala om nyheter i Windows 7. Eftersom jag själv nyligen börjat köra sjuan efter att ha hoppat över Vista så fick jag lära mig en hel del nyheter inom såväl operativsystem som sådant samt om utvecklingsbitarna, virtualisering, paketering och licenser.

Här kan du läsa om Robert Folkessons Presentation från Mid Tech-konferensen i Sundsvall . Där hittar man även material för nedladdning.

I det stora hela så var det en bra dag, även om vissa delar inte passade mig. Det blev lite väl stor spridning på de ämnen som diskuterades. För att passa mig bättre så skulle jag år vilja se att man delar upp konferensen på två dagar. Ena dagen med utvecklingsrelaterade ämnen och den efterföljande dagen med mer driftrelaterade ämnen. Samt att man får välja om man vill gå en eller två dagar.

MSDN Live Sundsvall 28 maj 2009

I slutet av maj så var jag på årets MDSN Live på Åkroken i Sundsvall. Talare var ”Microsoft-evangelisterna” Dag König och Robert Folkesson. Man informerade bland annat om att man kan hitta många filmer (på svenska) om den senaste MS-tekniken på Channel9 MSDN Sweden. Även att man då och då kör MSDN Radio som är radio-sessioner där man snackar om allt mellan himmel och .NET.

msdnlive

Dagen fortsatte sedan med en kort genomgång av historiken bakom .NET Framework 1-2-3 där man visade generiska typer och metoder, delegater, WCF, WF och WPF. Med grunden lagd så fortsatte dagen med en titt på det framtida .NET Framework 4.0 och Visual Studio 2010 som fortfarande är i beta-stadiet.

I .NET Framework så kommer ”Parallel Extensions” att ingå och det hjälper oss att programmera flertrådat. Introduktion till Parallel Extensions

Dynamic Language Runtime” (DLR) är ett stöd för dynamiska språk så att dessa går att köras på CLR’en.

Utöver detta så gick grabbarna genom nyheterna i C# version 4 med nyheter som dynamiska typer (dynamic).

I sista sessionen före lunch så gick de igenom hur man använder Visual Studio i kombination med Team Foundation Server och Visual Studio Team System. Detta var innehållet i förmiddagspasset som jag tyckte var väldigt intressant. Jag hade hört det mesta sedan tidigare då Johan Lindfors var på plats för Swenug, men det var ändå många nya bitar som gjorde det ”spännande”.

Eftermiddagen började med en grundgenomgång av XAML och varför Microsoft satsar stort på ett deklarativt språk. Detta används inte bara för gränssnitt i rika klienter, utan även i tekniker som Windows Workflow och WCF. Ett flertal exempel på detta gjordes i VS och Expression Blend.

Efter, det för mig ganska tråkiga, avsnittet om XAML (svammel *smile* ) så var det en genomgång av ASP.NET MVC som är ett alternativ till webforms. Webforms är som ni vet en utveckling eller en följd av winforms där man på något sätt ska ha samma arbetssätt då man skapar applikationer vare sig det är på desktopen eller på webben.

I MVC ramverket så har du full kontroll på allt som händer och kan utveckla dina webbsidor mer ”rent”. För mig som har php-bakgrund där du måste skapa allt för hand (ja nästan allt) så känns detta helt rätt. Personligen så tycker jag att detta är det bästa som MS kommit ut med då det gäller webbutveckling. Jag har aldrig riktigt gillat tråcklandet med webforms,
att man inte har någon kontroll på den html som skapas och viewstate och annat ”störande”.

Dagens sista presentation var om Silverlight 3 och .NET RIA Services. Om jag ska vara ärlig så var inte detta så intressant så jag har inte så mkt att säga om det…

Sammanfattningsvis så var det en intressant dag. Det är alltid intressant att höra om de senaste nyheterna från Microsoft.

Läsa från och skriva till nätverksmappar i .NET

Dagens lilla problem var hur man kan skriva och läsa filer från en utdelad mapp på nätverket från ett .NET program. För att komplicera det hela så har användaren som kör programmet inga rättigheter på nätverksmappen. Dessutom så är inte nätverks-sharen ”uppmappad” på datorn (av någon användare).

Som vanligt så fanns det ett antal sätt att göra det på där vissa var krångligare än andra. Förhandskravet på detta är att man har en användare som har rättigheter att skriva/läsa på nätverksmappen.

Alternativen var följande:

1) Exekvera ett bat-script där man använder ”net use” och copy för att flytta över filen.

2) Impersonera (vad blir detta på svenska?) en användare som har rättigheter på nätverksmappen. Läs mer om detta här.

3) Använda sig av Windows Networking functions (WIN32 API)

För mig så passade alternativ 3 bäst eftersom jag tyckte att de andra verkade mer eller mindre krångliga. För ändamålet så ”hittade” jag en färdig klass som fungerade på första försöket. Klassen hittar ni på Accessing Shared Folders in ASP.NET

Annan intressant läsning på samma tema:
Hur man skapar en utdelad mapp med .NET

Tappar focus för en webbkontroll i en ASP.NET Ajax updatepanel

Ett problem då man gör dynamiska formulär i ASP.NET Ajax är att man tappar ”focus” för den kontroll (textbox, dropdown etc.) som genererar postbacken. Med det menar jag att formulärets tabbningen resettas och den som fyller i formuläret får börja tabba från början.

Om man då har ett gränssnitt där tabbning mellan fälten är viktigt för helhetsupplevelsen såm måste man ”sätta tillbaka focus” på den kontroll som orsakat postbacken. Detta gör man enklast med följande oneliner i den metod där du hanterar postbacken:

ScriptManager.GetCurrent(this.Page).SetFocus(controlName);

controlName är det ID som du använder för din textbox, dropdown eller vad det kan vara….

Efter att ha mixtrat med diverse javascript som använder metoderna focus(), och select() i några timmar så var ovan nämnda lösning den enklaste.