Tuesday, September 16, 2014

Enable autostart in IIS 7.5 (without AppFabric)

You can create your own autostart provider for your WCF services and there is no need to use AppFabric for autostarting WCF services.

You will need/configure 4 things to enable autostart in WCF
            1) Autostartprovider (source code below)
            2) Add the reference of the above library to your WCF service
            3) Modify the svc file to use factory - 

<%@ ServiceHost Language="C#" Debug="true" Service="Service1" CodeBehind="Service1.svc.cs" Factory="Web.Hosting.ServiceBusHostFactory" %>

            4) Modify the applicationHost.config in C:\Windows\System32\Inetsrv\config in the following places

a) At AppPool level
                       <add name="AutoStartSite" managedRuntimeVersion="v4.0" autoStart="true" startMode="AlwaysRunning"  />



b) At Site level -
                      <site name="AutoStartSite" id="2" serverAutoStart="true">


c) At Virtual directory/Application level
                      <application path="/AutoStartVD" applicationPool="AutoStartSite" serviceAutoStartEnabled="true" serviceAutoStartProvider="MyAutoStartProvider">


d) serviceAutoStartProviders itself -
                       
In your applicationHost config file between <webLimits/> and    </system.applicationHost>, add the following section - 

         <serviceAutoStartProviders>
            <add name="MyAutoStartProvider" type="Web.Hosting.AutoStartProvider, Web.Hosting" />
        </serviceAutoStartProviders>



Thats it. Deploy your WCF service. Fire up DbgView.exe for debugging purposes as there are some diagnostics statements in the AutoStartProvider.




================START Autostartprovider source code=======================

File::::AutoStartProvider.cs

using System;
using System.Diagnostics;
using System.IO;
using System.ServiceModel;
using System.Threading;
using System.Web.Hosting;


namespace Web.Hosting
{
    public class AutoStartProvider : IProcessHostPreloadClient
    {
        
        public void Preload(string[] parameters)
        {
            bool isServceActivated = false;
            int attempts = 0;
            while (!isServceActivated && (attempts < 10))
            {
                Thread.Sleep(1 * 1000);
                try
                {
                    if (!System.Web.Hosting.HostingEnvironment.IsHosted) 
                        return;

                    var virtualPath = HostingEnvironment.ApplicationVirtualPath;
                    var physicalPath = HostingEnvironment.ApplicationPhysicalPath;
                    var svcFiles = Directory.GetFiles(physicalPath, "*.svc");

                    foreach (string svcFile in svcFiles)
                    {
                        ServiceHostingEnvironment.EnsureServiceAvailable(virtualPath + "/" + Path.GetFileName(svcFile));
                    }

                    isServceActivated = true;
                    System.Diagnostics.Trace.WriteLine(String.Format("Activated {0}", virtualPath));
                }
                catch (Exception exception)
                {
                    attempts++;
                    //continue on these exceptions, otherwise fail fast
                    if (exception is EndpointNotFoundException
                        || exception is ServiceActivationException
                        || exception is ArgumentException)
                    {
                        System.Diagnostics.Trace.WriteLine(exception.Message);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
    }

}

-------------------------------------------------------------------------------------------------------------

File::::ServiceBusHostFactory.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Text;
using System.Threading.Tasks;

namespace Web.Hosting
{
    public class ServiceBusHostFactory : ServiceHostFactory
    {
    Type incomingServiceType;
    Uri[] incomingBaseAddresses;
    /// <summary>
    /// Reopen Service host on network intermittent error
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnServiceHostFaulted(object sender, EventArgs e)
    {
        ICommunicationObject faultedHost = (ICommunicationObject) sender;
        faultedHost.Abort();
        //Log failure
        bool IsSourceExist = EventLog.SourceExists(CustomEventLogInstaller.EventSourceName);
        if (IsSourceExist)
            EventLog.WriteEntry(CustomEventLogInstaller.EventSourceName,
                String.Format("Host {0} connection failed at address {1}",this.incomingServiceType.ToString(),
                        this.incomingBaseAddresses.FirstOrDefault()), EventLogEntryType.Error);
        ServiceHost host =  base.CreateServiceHost(this.incomingServiceType, this.incomingBaseAddresses);       
        host.Faulted += this.OnServiceHostFaulted;
        System.Threading.Thread.Sleep(TimeSpan.FromSeconds(10)); // Sleeping here just to allow some time for the resource to come back.
        host.Open();
        //log host reopened
        if (IsSourceExist)
            EventLog.WriteEntry(CustomEventLogInstaller.EventSourceName,
                String.Format("Service bus connection reopened for {0}", this.incomingBaseAddresses.FirstOrDefault()), EventLogEntryType.Information);
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
    this.incomingServiceType = serviceType;
    this.incomingBaseAddresses = baseAddresses;
    ServiceHost host = base.CreateServiceHost(this.incomingServiceType, this.incomingBaseAddresses);
    host.Faulted += this.OnServiceHostFaulted;
    return host;
    }
 }

}

================END Autostartprovider source code=======================

Uninstalling and reinstalling IIS 7.5 on Windows 7

If you want remove IIS 7.5 from your Windows 7 machine, make sure to remove IIS Hostable Web Core and Windows Process Activation Service (if already installed).

Uninstalling just IIS features and reinstalling them will not help and you will get - "An error occurred. Not all features are installed".

Here are steps-
1) Uninstall IIS, IIS HWC, WAS.
2) Restart the system
3) Rename Inetpub to Inetpub1
4) Reinstall IIS


Saturday, January 19, 2013

Various ways to access registry by VBScript


Various ways to access registry

Program 1

If RegKeyExists("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL11.MSSQLSERVER\") Then
WScript.StdOut.Write("2012")
Else
WScript.StdOut.Write("2008R2")
End If


Function RegKeyExists(Key)
  Dim oShell, entry
  On Error Resume Next

  Set oShell = CreateObject("WScript.Shell")
  entry = oShell.RegRead(Key)
  If Err.Number <> 0 Then
    Err.Clear
    RegKeyExists = False
  Else
    Err.Clear
    RegKeyExists = True
  End If
End Function


Program 2 (using WMI)

Dim WMI, Col, Prod, Q
Set WMI = GetObject("WinMgmts:")
Q = "Select * FROM Win32_Product WHERE Vendor = " & _
    "'Microsoft Corporation' AND Name LIKE 'SQL Server%Database Engine Services'"
Set Col = WMI.ExecQuery(Q)
For Each Prod in Col
  if left(Prod.version, 3) = "11." then
    msgbox "SQL Server 2012 was found!" & vbCrLf & prod.version
  elseif left(Prod.version, 4) = "10.5" then
    msgbox "SQL Server 2008 R2 was found!" & vbCrLf & prod.version
  end if
Next
Set Col = Nothing
Set WMI = Nothing


Program 3 (using WMI)

' Supporting only SQL Server 2012 and SQL Server 2008 R2
Const HKEY_LOCAL_MACHINE = &H80000002
Set shell = CreateObject("WScript.Shell")


strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

If Err.Number <> 0 Then
            shell.LogEvent 4, "Get Object error"
            shell.LogEvent 4, Err.Description     
  Else   
 End If

strKeyPath = "SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL11.MSSQLSERVER\Setup"
strValueName = "Version"
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

If Err.Number <> 0 Then
            shell.LogEvent 4, "Get Stringvalue error"
            shell.LogEvent 4, Err.Description    
  Else   
 End If


If IsNull(strValue) Then
           WScript.StdOut.Write ("SQLNCLI10")
Else
           WScript.StdOut.Write ("SQLNCLI11")
End If


Program 4 (using Reg.exe)


strkey="HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL11.MSSQLSERVER\Setup" & Chr(34) &  " /v Version /reg:64"

Set objShell = CreateObject("WScript.Shell")
Set objScriptExec = objShell.Exec("REG QUERY " & Chr(34) & strkey )

strText = objScriptExec.StdOut.ReadAll()
if (strText <> "") then
WScript.echo "2012"
else
WScript.echo "2008R2"
end if

 /reg:64 option is very important if you need to run the script via a 32 bit application (example installer).


Use program 4 if you are using vbscript via some other medium (like installer).

Sunday, January 8, 2012

Creating first PHP program (in Windows platform)

Creating a PHP client and consuming WCF service
1) Download PHP for windows and install it.
2) Run” PHP.exe –i “ to see the initialization settings.
3) You ll find PHP expects PHP.ini file to be present in C:\Windows. So first rename PHP.ini development to PHP.ini and copy it to C:\Windows
4) Modify C:\Windows\PHP.ini to include some settings for PHP runtime. Most of the settings are present there but commented with semi-colon (;) prefix. Just uncomment to include that setting.
a) uncomment include_path
b)uncomment extension=php_soap.dll (as we ll be needing to making SOAP calls)
c)uncomment extension_dir = "c:\php\ext" (set your extension dir. Mine is C:\PHP\ext
       5) Create the PHP program as follows and save it in LMSClient.php (Read the program. It ll make sense):

<?php

// Create a new soap client based on the service's metadata (WSDL)
$client = new SoapClient("http://localhost:24802/LMSService.svc?wsdl");

   //echo("<br />Dumping client object:<br />");
   //var_dump($client);
   //echo("<br /><br />");
  
   //echo("Dumping client functions:<br />");
   //var_dump($client->__getFunctions());
   //echo("<br /><br />");

//$result = $client->Test();
$result = $client->GetUserById(1);


//echo $result->TestResult;
echo $result->GetUserByIdResult->Firstname;
echo $result->GetUserByIdResult->Lastname;

?>

6) Run the program by php -f c:\php\MyPHPFiles\LMSClient.php

WCF Metadata publishing and use of DATACONTRACTS

No Datacontracts are not used so they can consumed outside .NET like JAVA / PHP


1)      If enabled, WCF service metadata could be found by opening the http://...svc?wsdl
2)      In there, there is a section types, which refers to an xsd for example http://localhost/LMSService/LMSService.svc?xsd=xsd2
3)      That xsd has all the data types/structures for input and output.
4)      The funny part is, it has all the public properties used in the input/output even if you don’t have DataContract attributes.

So the question is What’s the point of DataContract/DataMember attributes. The above xsd has the datatypes/structures and a PHP/Java client could consume that. The answer is for more control on which properties to be published. So without DataContract/DataMember attribute, its ALL or NONE for all public properties publishing. (Note: You can all together switch off WCF Metadata publishing). With DataContract/DataMember, we have some properties public to be used in our own projects/solution yet not expose it the outside world by not adorning it with DataMember attribute.

Question- ) How to switch off/on WCF metadata publishing

<system.serviceModel>   
    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior">
          <!—The answer is in the comment line below à
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="SRO.LMS.Services.LMSService" behaviorConfiguration="metadataBehavior">
        <host>
          <baseAddresses>
            <add baseAddress=
                 "http://localhost/LMSService" />
          </baseAddresses>         
        </host>
        <endpoint address="" binding="basicHttpBinding" contract="SRO.LMS.Services.ILMSService"/>
        <endpoint address="mex"  binding = "mexHttpBinding" contract = "IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>
 

Monday, November 7, 2011

Image Editing Printing

Selecting part of a large pic in MS Paint
--------------------------------------------

1) zoom out 50% or 25% (as required)
2) Select required area
3) Cut
4) Zoom in back to 100%
5) Paste. You are done.



Printing a large doc (pic) in A4 paper
-------------------------------------------
1) Open the large pic in Adobe Photoshop
2) Click on 'Image' menu -> Image Size. Change the Pixel settings to 1280 * 800
3) Save it
4) Open Word (Insert -> Pic -> aaaa.jpg). Always use this procedure rather than copy-pasting
through clip-board to avoid large size document
5) To print a full page change the margin setting to 0,0,0,0 first and then check if there is any space
on top,right,bottom,left and again change the margin accordingly
6) Remember to change the margin settings for that particular page only Insert 'Next Page' Section break before and after that page. (V.Imp) otherwise all pages get the same margin settings.

Silverlight RIA services (without using entity framework) - The most basic example

1) Create a Silverlight (and its host ASP.NET Web App.) Project. While creating the same check on “Enable RIA Services”
2) Add a model Employee.cs in Web Project. Mark [KeyAttribute] to EmployeeId Property. This is necessary as all Entities in DomainServies should have this attribute.

3) Add a DomainService class to the Web Project and and make a method GetEmployees() returning IQueryable<Employee>. You can hard-code an IList and return list.AsQueryable<Employee>().

4) When you build the entire solution, do a “Show All Files” in Silverlight project. You will get an folder Generated_Code which has a class containing the DomainContext (with public methods converted to queries) and entities (generated from models).

5) Add the namespace for RiaControls and web Project using the following.
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
             xmlns:my="clr-namespace:BasicRIAService.Web"
6) Add the RiaDataSource using the following.

<riaControls:DomainDataSource AutoLoad="True"                                                                           
                                      Name="employeeDomainDataSource"
                                      QueryName="GetEmployeesQuery"
                                      >
            <riaControls:DomainDataSource.DomainContext>
                <my:EmployeeDomainContext />
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>


OR (Pick it from Static Resources)




<riaControls:DomainDataSource AutoLoad="True"                                                                           
                                      Name="employeeDomainDataSource"
                                      QueryName="GetEmployeesQuery" DomainContext="{StaticResource myContext}">
        </riaControls:DomainDataSource>

For picking it from Static Resources, you have first define it in Static Resource

<UserControl.Resources>
        <my:EmployeeDomainContext x:Key="myContext"/>
</UserControl.Resources>



7) Add a Listbox and bind to RiaDataSource using the following.
<ListBox x:Name="listEmployee" ItemsSource="{Binding ElementName=employeeDomainDataSource,Path=Data}" Width="200" Height="100">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding EmployeeId}" Margin="5,0,0,0"/>
                        <TextBlock Text="{Binding EmployeeName}" Margin="5,0,0,0"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>