Tuesday, September 16, 2014

Overriding without virtual and override keywords in .Net

This is about a particular scenario where we can achieve overriding without virtual or override keywords in C#. Below is the scenario of an inheritance hierarchy.
Here we can see that both the base and derived class implemented the IDisposable interface. In this case we don't need to mention the keyword overrides but the Dispose() of DerivedDisposable class will be called when we invoke the Dispose() method on the IDisposable type variable, if it contains the DerivedDisposable class object.

            IDisposable id = new DerivedDisposable();
            id.Dispose();

This will invoke the method written inside the DerivedDisposable class.

Calling base class Dispose method

Normally in overriding scenarios, we may call the base class implementation by using base.OverriddenMethodName(). But in this case, base object will not have the Dispose method, if the IDisposable is implemented explicitly. Means the code below won't compile.


    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            base.Dispose();//This wont compile if the base class / class Derived in this example implements the IDisposable explicitly
        }
    }


Next idea what we can do is to cast the base to IDisposable and call the Dispose method. But that too won't compile.


    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            //DoWork();
            (base as IDisposable).Dispose();//Won't compile
        }
    }

Implicit interface implementation

Only way to call the base class Dispose method is to make sure the base implements the interface implicitly.Then we can call base.Dispose method().


    class Disposable : IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("Disposable.Dispose");
        }
    }
    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            //DoWork();
            base.Dispose();
        }
    }


If we are concerned about having additional public function, another workaround is to have separate protected function in base class (eg:DisposeWorker) which is called from the Dispose() of base class to carry out the task. So from the derived class.Dispose() method we can call that protected function.


    class Disposable : IDisposable
    {
        void IDisposable.Dispose()
        {
            DisposeWorker();
        }
        protected void DisposeWorker()
        {
            Console.WriteLine("Disposable.Dispose");
        }
    }
    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            //DoWork();
            base.DisposeWorker();
        }
    }

Real scenario - Overriding the ClientBase<TChannel>.Dispose

This is useful when overriding the Dispose method of ClientBase<TChannel> class related to WCF to have our own behavior when disposing. In our project as I mentioned in earlier posts, we are not adding service reference to call WCF service. Instead we create our own proxy class by implementing ClientBase<TChannel>. We have proxy pooling technique built into the system and it needs "return  of proxy to the pool" when Dispose is called on proxy object.


    class Client : ClientBase<IService1>, IService1IDisposable
    {
        void IDisposable.Dispose()
        {
            Console.WriteLine("Disposable.Dispose");
        }
 
        string IService1.GetData(int value)
        {
            throw new NotImplementedException();
        }
    }


I am really not sure whether its overriding or 'feels like' overriding. Anyway I am open to discussions. This is one of the scenario I could see which can only be solved by using implicit interface implementation.We will face this same issue if we implement interfaces explicitly in VB.Net.

Happy coding

Tuesday, September 9, 2014

Why WCF Service cannot be activated when calling from client side?

Last week I came to see one interesting issue related to WPF calling WCF services. One of my colleague asked me to look into his machine as he is not able to call WCF service from WPF application. When I looked into the issue, I could see that the error message at client side is 

The requested service, 'http://<host>/<Service>.svc' could not be activated. See the server's diagnostic trace logs for more information

Diagnose step 1

When ever we see this exception we could understand that the service instance creation got error. If we browse the service url, it internally creates the service object and fail with more error details. So the next step was to browse the WCF service in browser by right click on IIS and browse or give the URL directly, if its known.

That turned out to be more informative

Could not load file or assembly '<assembly name>' or one of its dependencies. An attempt was made to load a program with an incorrect format

If we are not seeing the details we can enable the exception flag.

<serviceDebug includeExceptionDetailInFaults="true"/>

Diagnose step 2

Reset IIS and clear the temporary Asp.Net files. Sometime the temporary Asp.net files will be holding a wring dll.

Location of temporary ASP.Net files for 64 bit .Net 4.0 applications is - %Windir%\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files

Location of temporary ASP.Net files for 32 bit .Net 4.0 applications is - %Windir%\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files

Tried this step but no luck.

Diagnose step 3

This leads to the situation where one assembly file present in the bin folder is not getting loaded due to some exception. There are chances that it depends on another dll and that is causing issue. Also chances are that it might be loading the dll from some other location such as GAC. 

So better idea is to see the assembly binding fusion log using the fuslogvw tool .Tried that and got more detail. Basically enabled the registry key, then we can see the fusion log in the browser itself. It says

===
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:\TFS\TestDotNet\WcfService1\web.config
LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/wcfservice1/63540997/f07fffe5/ClassLibrary20.DLL.
LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/wcfservice1/63540997/f07fffe5/ClassLibrary20/ClassLibrary20.DLL.
LOG: Attempting download of new URL file:///D:/TFS/TestDotNet/WcfService1/bin/ClassLibrary20.DLL.
ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated

This means the dll is loaded from proper location. So need to go next step.

Diagnose step 4

Need to have closer look at the exceptions and their call stack to understand how far its reaching and where its failing. The exception call stack is given below which was present in the browser when service is browsed.


[BadImageFormatException: Could not load file or assembly '<assembly name>' or one of its dependencies. An attempt was made to load a program with an incorrect format.]
   System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
   System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +210
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection) +242
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +17
   System.Reflection.Assembly.Load(String assemblyString) +35
   System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +122

[ConfigurationErrorsException: Could not load file or assembly '<assembly name>' or one of its dependencies. An attempt was made to load a program with an incorrect format.]
   System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +12761078
   System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +503
   System.Web.Configuration.AssemblyInfo.get_AssemblyInternal() +142
   System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +334
   System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath) +203
   System.Web.Compilation.BuildManager.ExecutePreAppStart() +152
   System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +1151

[HttpException (0x80004005): Could not load file or assembly '<assembly name>' or one of its dependencies. An attempt was made to load a program with an incorrect format.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +12881540
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +159
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +12722601


There were 3 exception one after another. Configuration exception and HttpExceptions are the outer ones and the real problem is stated in the very inner exception which is nothing but BadImageException.

BadImageException usually happens when we try to load 32 bit assembly in 64-bit applications or when the assembly is corrupted

Diagnose step 5

We can check whether the assembly is corrupted by opening it in reflector or any other decompilation software. If reflector is able to load the dll, there is no issue. In this case, I was able to open the file in reflector.

Diagnose step 6

Next we need to make sure all the assemblies are marked as 64 bit / AnyCPU when compiled. The ASP.Net hosting mechanism loads all the dlls when its started. Based on the application pool setting "Enable 32-Bit Applications" flag, it decide the processor architecture of web application. If there is any dll which is not matching with bit size, it will throw this bad image exception. We could see that the assembly which was causing, is built using x86 mode where the app pool is exclusive for 64bit applications.

Recompiled using 'AnyCPU' setting. Reset IIS and cleared the Temporary ASP.Net Files. Everything worked.

Tuesday, September 2, 2014

Hosting WCF service in IIS and System.Web.WebPages.Deployment

As per MSDN the System.Web.WebPages,Deployment namespace contains "the classes that are used to confirm the deployment of web applications". It make sense for web applications which contains web pages created using .aspx or Razor. But what is the relation between this System.Web.WebPages.Deployment.dll and WCF service application which hosted inside IIS which is exposed via netNamedPipes ?

As we have seem in my previous post about SSMS and System.Transactions.dll, I got a machine crash and the machine started behaving in its's own way which resulted in problems. Now when I host WCF services inside IIS there are problems. The services, I was able to browse before the crash stopped working with below error message.

Could not load file or assembly 'System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The module was expected to contain an assembly manifest

The call stack looks as follows

[BadImageFormatException: Could not load file or assembly 'System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The module was expected to contain an assembly manifest.]
   System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
   System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +34
   System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +152
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection) +77
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +16
   System.Reflection.Assembly.Load(String assemblyString) +28
   System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +38

[ConfigurationErrorsException: Could not load file or assembly 'System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The module was expected to contain an assembly manifest.]
   System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +752
   System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +57
   System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +170
   System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() +91
   System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath) +258
   System.Web.Compilation.BuildManager.ExecutePreAppStart() +135
   System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +516

[HttpException (0x80004005): Could not load file or assembly 'System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The module was expected to contain an assembly manifest.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +9873912
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +101
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +254


One possibility for BadImageFormatException is the mismatch of runtime. ie if we try to load x86 assembly in x64 application or other way we may get this exception. I tried enabling 32 bit support in the application pool by setting the "Enable 32-Bit Applications" flag in IIS. 

It did't help.

Then looked at all the config files possible such as aspnet.config and machine.config. Nowhere I was able to find any entry to the problematic dll. Then I decided to find out the assembly binding information which is as follows

=== Pre-bind state information ===
LOG: User = NT AUTHORITY\NETWORK SERVICE
LOG: DisplayName = System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///<drive>:/TFS/TestDotNet/WcfService1/
LOG: Initial PrivatePath = <drive>:\TFS\TestDotNet\WcfService1\bin
Calling assembly : (Unknown).
===


Here its clear that the calling assembly is unknown which I assume any framework dll. May be it was earlier getting loaded from GAC and after the crash GAC registration might be broken. So I figured out the location of he dll and registered into GAC.

Location of System.Web.WebPages.Deployment.dll - <Install drive>:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies

But the GACUtil failed with a message as follows.

The module 'System.Web.WebPages.Deployment.dll' was expected to contain an assembly manifest.

Then I tried open the dll in reflector and could see that, it was not able to open as its no more a .net dll and it displayed more detailed error message


File is not a portable executable. DOS header does not contain 'MZ' signature.


This leads to a conclusion that the System.Web.Webpages.Deployment.dll is corrupt. So next option is repair or re-install. So went to appwiz.cpl and re-installed "Microsoft ASP,Net Webpages 2".

It worked!!!

But why WCF hosted in IIS needs System.Web.WebPages.Deployment.dll which is for web page related :-(

Tuesday, August 26, 2014

SSMS 2008 and System.Transactions.dll 2.0.0.0

Recently my machine got some hang and I had to restart my machine by "pressing down power button for long time and start again". As usual the chkdsk popup came and run complete disk scan. After the check disk scan, I was able to login and reached till desktop. But from that time onwards I started facing some strange issues. One of issue is mentioned below.

I opened SSMS 2008 R2 (SQL Server Management Studio) and tried connecting to an SQL Server instance.It resulted in the below error message

"Could not load file or assembly 'System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The module was expected to contain an assembly manifest. (System.Data)"

What is the relation between SSMS and this dll. I know this dll is used for .Net to achieve transactions in our applications. May be this is used by SSMS to execute our queries. But why its needed when we are connecting to database? No idea. 

Attempt 1 - Re-register System.Transactions.dll into GAC

Googled and found couple of links and everywhere it is telling that the dll is not registered in the GAC. Normally this dll will be registered in to the GAC but some operations like installation of other software might have unregistered it. Below are the main paths we can see this particular dll. But unfortunately in my case I don't have that dll in place or the dll size is 0 KB.
  • C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Transactions.dll - File size 0 KB
  • C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin - I dont have VS 2005 Installed
  • C:\Windows\Microsoft.NET\Framework64\v2.0.50727 - The file is present. But SSMS.exe is a 32bit process.
  • C:\Program Files (x86)\Microsoft Visual Studio 9.0\SDK\v3.5\Bin - This folder is empty
  • C:\Program Files (x86)\Microsoft Visual Studio 10.0\SDK\v3.5\Bin - Folder empty
  • C:\Program Files (x86)\Microsoft Visual Studio 11.0\SDK\v3.5\Bin - Folder empty

Attempt 2 - Reinstall .Net framework from control panel

This turns out that my .Net 2.0 installation is corrupted. What is the easiest way? Go to control panel -> Programs and features -> Turn windows features turn on or off and uninstall and install the .Net framework. But in my machine I was not even able to get the "windows features on off" grid. Even I don't think, I can do it as .Net 2.0 is part of Windows 7 OS.

Attempt 3 - Repair .Net using tool

Downloaded the Microsoft.Net Framework Repair Tool and run it. I tried the same and no chance. Still the file size is 0KB.

Attempt 4 - Install .Net framework using msi

Then downloaded the.Net 2.0 installer and tried installing it. But it says "The product is already installed as part of the operating system"

Attempt 5 - Uninstall from installer cache

One link from Microsoft KB says we need to goto the installer folder located at <OS Drive>:\Windows\Installer and find the msi package by its comment "Microsoft .NET Framework 2.0 RTL x86 enu" and right click to repair. But I was not able to see the entry with the .Net 2.0 comment.

Attempt 6 - Reinstall using command

Anther link says we can directly run the installer using the msiexe command as follows

msiexec /fpecmsu {C09FB3CD-3D0C-3F2D-899A-6A1D67F2073F} REINSTALL=ALL /l*v %temp%\netfx20sp2_repair_log.txt /qn

After waiting for some time I could see the netfx20sp2_repair_log.txt in the temp folder with and entry as below

MSI (s) (7C:30) [01:16:50:534]: Running installation inside multi-package transaction {C09FB3CD-3D0C-3F2D-899A-6A1D67F2073F}

But still the issue is not resolved.

Attempt 7 - using sfc.exe

Since the .Net 2.0 is part of Windows OS, there is another way to verify the installation. Its using sfc command. Full command is as follows which we can give in command window which is running in admin mode.

sfc.exe /scannow

Result

"Windows Resource Protection found corrupt files but was unable to fix some of th
em.
Details are included in the CBS.Log windir\Logs\CBS\CBS.log. ...."

There are issues which were not resolved and simply pointing to a log file which is around 3 MB text.

What is there in the log

Just searched through the CBS.log for System.Transaction.dll and found the entry very easily.

2014-08-26 01:33:57, Info                  CSI    00000389 Hashes for file member \SystemRoot\WinSxS\x86_system.transactions_b77a5c561934e089_6.1.7601.18410_none_e7e76cdf2530f04d\System.Transactions.dll do not match actual file [l:46{23}]"System.Transactions.dll" :
  Found: {l:20 b:2jmj7l5rSw0yVb/vlWAYkK/YBwk=} Expected: {l:20 b:hs4esk9VeIeBIBB9tDCOqo2DioA=}
  Found: {l:32 b:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=} Expected: {l:32 b:hZSyvIr53ZRpAoP4vZD8O+tE48T6dPGXmr6Eo8MKkWU=}
2014-08-26 01:33:57, Info                  CSI    0000038a [SR] Cannot repair member file [l:46{23}]"System.Transactions.dll" of System.Transactions, Version = 6.1.7601.18410, pA = PROCESSOR_ARCHITECTURE_INTEL (0), Culture neutral, VersionScope neutral, PublicKeyToken = {l:8 b:b77a5c561934e089}, Type neutral, TypeName neutral, PublicKey neutral in the store, hash mismatch
2014-08-26 01:33:58, Info                  CSI    0000038b Hashes for file member \SystemRoot\WinSxS\x86_system.transactions_b77a5c561934e089_6.1.7601.18410_none_e7e76cdf2530f04d\System.Transactions.dll do not match actual file [l:46{23}]"System.Transactions.dll" :
  Found: {l:20 b:2jmj7l5rSw0yVb/vlWAYkK/YBwk=} Expected: {l:20 b:hs4esk9VeIeBIBB9tDCOqo2DioA=}
  Found: {l:32 b:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=} Expected: {l:32 b:hZSyvIr53ZRpAoP4vZD8O+tE48T6dPGXmr6Eo8MKkWU=}
2014-08-26 01:33:58, Info                  CSI    0000038c [SR] Cannot repair member file [l:46{23}]"System.Transactions.dll" of System.Transactions, Version = 6.1.7601.18410, pA = PROCESSOR_ARCHITECTURE_INTEL (0), Culture neutral, VersionScope neutral, PublicKeyToken = {l:8 b:b77a5c561934e089}, Type neutral, TypeName neutral, PublicKey neutral in the store, hash mismatch
2014-08-26 01:33:58, Info                  CSI    0000038d [SR] This component was referenced by [l:156{78}]"Package_3_for_KB2931356~31bf3856ad364e35~amd64~~6.1.1.0.2931356-78_neutral_GDR"
2014-08-26 01:33:58, Info                  CSI    0000038e Hashes for file member \??\C:\windows\Microsoft.NET\Framework\v2.0.50727\System.Transactions.dll do not match actual file [l:46{23}]"System.Transactions.dll" :
  Found: {l:20 b:2jmj7l5rSw0yVb/vlWAYkK/YBwk=} Expected: {l:20 b:hs4esk9VeIeBIBB9tDCOqo2DioA=}
  Found: {l:32 b:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=} Expected: {l:32 b:hZSyvIr53ZRpAoP4vZD8O+tE48T6dPGXmr6Eo8MKkWU=}
2014-08-26 01:33:58, Info                  CSI    0000038f Hashes for file member \SystemRoot\WinSxS\x86_system.transactions_b77a5c561934e089_6.1.7601.18410_none_e7e76cdf2530f04d\System.Transactions.dll do not match actual file [l:46{23}]"System.Transactions.dll" :
  Found: {l:20 b:2jmj7l5rSw0yVb/vlWAYkK/YBwk=} Expected: {l:20 b:hs4esk9VeIeBIBB9tDCOqo2DioA=}
  Found: {l:32 b:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=} Expected: {l:32 b:hZSyvIr53ZRpAoP4vZD8O+tE48T6dPGXmr6Eo8MKkWU=}
2014-08-26 01:33:58, Info                  CSI    00000390 [SR] Could not reproject corrupted file [ml:520{260},l:98{49}]"\??\C:\windows\Microsoft.NET\Framework\v2.0.50727"\[l:46{23}]"System.Transactions.dll"; source file in store is also corrupted
2014-08-26 01:33:59, Info                  CSI    00000391 Repair results created:

It says source file store is also corrupted. Even I checked sfc.exe documentation .It says the same cannot be repaired.

Attempt 8 - Remove .Net 2.0 using third party tool

There is something called .Net framework cleanup tool which can be used to remove .Net framework version. But in the documentation it says, it cannot remove .Net 2.0 from Windows 7.

Attempt 9 - Use SQL Server 2012 and connect to SQL 2008 R2 instance

Now its time to step back and think. My actual problem is to connect to SQL Server instance. Why don't I try using SQL 2012 SSMS. Installed SQL Server 2012 and tried to connect to SQL 2008 instance. The connection succeeded. I was able to expand the databases node. But when I try to do any operation such as  opening the query window or restore database backup I gets new error as follows.

Could not load file or assembly 'Microsoft.NetEnterpriseServers.ExceptionMessageBox, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The module was expected to contain an assembly manifest. (Microsoft.SqlServer.Management.RelationalEngineTasks)

Entering into more issues

What's left

  1. Copy the dll from another machine which is having same .Net version and paste into my folder and register into GAC
  2. Reinstall .Net framework 2.0 manually by following the below link
  3. Format and re-install everything / re-image my machine as everyone in my company uses same OS image.
Planning to go with option 3 is option 1 doesn't work.

Update 1

I tried option 1 and it started working. Followed the steps mentioned in a link to replace the System.Transactions.dll as its protected by Trusted Installer

Tuesday, August 19, 2014

Why Visual Studio 2010 closes itself without loading the UI when we launch devenv.exe

On a fine day, I could see that my Visual Studio stopped loading up, when I try to start VS IDE. It shows the splash screen for some seconds and then popup an alert dialog as below and exit itself.

The 'Microsoft.VisualStudio.TeamFoundation.PowerTools.TfptPackage, Microsoft.VisualStudio.TeamFoundation.PowerTools, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' package did not load correctly.


The problem may have been caused by a configuration change or by the installation of another extension. You can get more information by running the application together with the /log parameter on the command line, and then examining the file 'C:\Users\<user>\AppData\Roaming\Microsoft\VisualStudio\10.0\ActivityLog.xml'.

I could see that the devenv.exe process is not present after the alert box. As usual first option I tried was restarting the machine. But that didn't help me.

Then I uninstalled the VS 2010 team foundation power tools as its mentioned in the message. Restarted machine. Still no improvement. Then I tried running VS in safemode to make sure none of the plug-ins are getting loaded which might caused error while loading. No luck.

After the above step I understood that its something complicated and I need to run the Visual Studio with logging enabled so that I can examine the log. After running with log enabled, I was able to see the below suspicious entry in the log file.

<entry>
    <record>39</record>
    <time>2014/08/08 18:11:33.997</time>
    <type>Warning</type>
    <source>VisualStudio</source>
    <description>The CTM file is out of date and should be deleted and rebuilt, but the file &apos;C:\ProgramData\Microsoft\VisualStudio\10.0\1033\devenv.CTM&apos; could not be deleted.</description>
  </entry>

What is this CTM file? I did some google and got some links to fix it. But unfortunately nothing worked out.

I had to spent half day to reach this point. There was no benefit researching on this as its taking my productive time. So decided to re-install Visual Studio. Then the next issue started. I am using VS 2010 Ultimate and the infrastructure team in my office don't have the DVD as the license is with client. So finally settled in installing VS 2012 Pro in my machine. I had to agree on that as VS is my tool. That day went smooth with VS 2012.

On next day out of curiosity, I tried to launch VS 2010 and surprisingly it worked. Still this time, its a wonder for me.

Tuesday, August 12, 2014

Javascript window.external.notify to communicate to WebBrowser control

How to communicate from web page loaded inside browser control to the hosting application

There are so many scenarios, where we may need to show web page inside our native applications such as Windows forms, WPF, Windows Phone, Android, iPhone etc... One of the scenario is to integrate with external authentication providers.

If we look at any third party authentication providers such as Google, Facebook, Azure ACS they don't let us take the user authentication details via our forms and get it authenticated using their web services. Instead the are strict in accepting the user name and password only through their web pages. The reason is security. If each and every application starts accepting user's Facebook or Google user name and password, there are chances that some of those apps will store the credentials locally and it might be miss used. That is the issue which is addressed by only allowing web page login even if we are in native applications.

The solution is, if we are developing even WPF or native mobile application and want to get external authentication we need to show their web page in our application. And once the authentication happens inside the browser, the native application can receive the security token and use it for subsequent operations.

For showing identity provider login page, we need to rely on the browser control available in the corresponding platform. If its WPF the browser control name is WebBrowser, in Android its named as WebView and in iOS its UIWebView. It is simple. First part is over, now our native application need to know when the authentication is completed, so that it can remove the browser control and obtain the token. This is the main topic of this post. In other words, the authentication happened inside the browser and browser need to to notify that event to the host application via some techniques.

The same technique, we can reuse the same technique if we want to notify any event happens inside the web page loaded inside the browser control.

Communication from HTML5 web page to WPF

WPF Browser control class has a property called ObjectForScripting. Assign any object to this property and it will be available as the window.external object in Javascript. So whatever methods are available in the class of the object assigned, those can be invoked from Javascript. For example, we created a class called HTMLInteropClass and that class has a method named MyMethod(). If we assign an object of that class to the WebBrowser.ObjectForScirpting property, we can invoke the MyMethod() written in C# from javascript using window.external.MyMethod() statement. Obviously the javascript should be downloaded from server or injected during run time to be running inside the browser control. Steps are as follows.

  1. Develop the interop class. Have the method inside it, which we are intended to call from javascript.
  2. Create object of that class and assign to the ObjectForScripting property of the WPF WebBrowser control.
  3. Point web browser control to the web page which is having invocation code. ie window.external.<methodname>()
  4. Develop the web page which is having the invocation code
More details here.

Communication from HTML5 web page to Android

In Android the web browser control name changes. But the handling is kind of same as of WPF browser control. Steps given below
  1. Develop a class in Java for Android application with method which will be called from javascript.
  2. In the onCreate() method of activity capture the webView reference and relate the object of above class with javascript using addJavascrtiptInterface() method.
  3. Make sure the Javascript is changed to call the method, present in the class created in step 1.
  4. Point the WebView to the page which contains the code to invoke our Android method.
More details here.

Communication from HTML5 web page to Windows phone

Windows phone uses a different way than WPF. It uses event based method invocation. ie We need to listen to the ScriptNotify event of WebBrowser. Steps below
  1. Subscribe to the ScriptNotify event.
  2. In the event handler e.Value gives the value sent from javascript
  3. The javascript code can invoke this method using window.external.notify("value");
This can be used in Silverlight as is. More details here.

Communication from HTML5 web page to iPhone

Here again the way is different. We cannot handle the window.external object directly. Need to follow a workaround. Whenever we want to communicate to the iOS UIWebView, we need to navigate to a dummy url and catch the navigation event in objective C code. We can use the webViewDidFinishLoad handler of UIWebView to capture the event. Steps below.

  1. Write code in JS to redirect the window.external invocations to a dummy url with data in its query string.
  2. Handle the webViewDidFinishLoad of UIWebView control and write the code in it.

More details here.

Tuesday, August 5, 2014

XAML as DSL - Load and saving Windows workflow foundation workflows

Context

Windows Workflow Foundation has got better after MSFT introduced the WWF 4.0. I don't think, it was stable earlier. We are now using WWF, in one of our project. The main reasons are as follows
  • There is a complex business scenario (similar to recommendation algorithm) which business experts itself, is not clear how to do it. They want to try/test the algorithm in production data using a different tool. During that test they may need to alter the algorithm and change configurations to try various possibilities. Since the production data is spread across different countries and some don't allow the data to be carried out of the country, its not feasible to have a developer going with the business testing team and alter the algorithm.
  • During the above testing conducted by business experts, they want to try different algorithms (copy and modify original) on same data and compare the results.

Why XAML as DSL

This clearly points to the need of a Domain Specific Language to code the algorithm. As mentioned in one of my previous posts about DSL, either we can develop a DSL with its own parser and all or leverage existing languages to manipulate the entities. Creating own domain specific language with its own parser is not feasible as it takes more time.We could easily use PowerShell or Javascript as DSL, but the problem is the tooling. So we took XAML as DSL to code the algorithm. Decision factors below.
  • The business want to change the algorithm on the fly.
  • Business people are not good coders and its difficult for them to understand by looking at program as text. So they need a UI to edit algorithm (Implemented using DSL)
  • There is not much time to create tooling for existing languages such as PowerShell or Javascript

Advantages

XAML as DSL is being executed by the WWF engine. If we see the WWF as technology, it has many inbuilt features we can leverage to have it as DSL. Some items listed below.
  • It stores the workflow in clear XAML format
  • It comes with out of the box workflow designer control based on WPF. This workflow editor control can be easily hosted in our WPF application.

How to load and save WWF workflow

Lets come to the topic of saving and loading windows workflow foundation .xaml workflow files. As we saw earlier, the business want to edit the algorithm on the fly. We are keeping the xaml file in file system itself , even though the application has database.Below are the code snippets

Load the WWF workflow.xaml from file

Mainly we need to create the instance of WorkflowDesigner class and invoke it's Load() method with string argument. We can pass the file name as string.

Important thing here is, we don't need to read the file ourselves and pass the workflow XAML. For doing that there is another method.

            _workflowDesigner = new WorkflowDesigner();
            _workflowDesigner.Load(_fileName);
            //Code to Load _workflowDesigner related controls such as _workflowDesigner.View,_workflowDesigner.PropertyInspectorView 
            //into the WPF container

Save modified workflow to file.

Saving the workflow into file too simple. Just invoke the method. Main thing to make sure the permissions on the file. The user who is running the process should have write permission on the file.

            _workflowDesigner.Save(_fileName);

Load and save the workflow from database or any other source

There is Text property in WorkflowDesigner class. Assign the workflow xaml content in string form to the Text property and call Load() method to load the XAML string directly. Read the XAML string from database using traditional techniques and assign to Text property. We may get the modified XAML via the same property to save back to database.

            _workflowDesigner = new WorkflowDesigner();
            _workflowDesigner.Text = GetWorkflowFromDatabaseAsString();
            _workflowDesigner.Load();

References

Loading workflow in WorkflowDesigner

Happy coding.