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.

Tuesday, July 29, 2014

Android - Making Facebook login works in HTML5 app hosted inside WebView

Context - Develop one app for all machines / platforms.

The software stake holders always want to target a large audience regardless of what machine / plat form their clients uses. That is one of the reason why software are often written as web application. If we write as web application, at least in theory it can run in any machine whether it is laptop,tablet or mobile also regardless of the OS Windows / Linux / Mac used in those machines. Another advantage going with web is the less development cost as we are developing one application. Its the trend among the developers / organizations.

There are so many arguments going on whether we should go with this HTML5 web apps to address this problem in case we are targeting mobile platforms only. Some people argue that we should go with Xamarin kind of converging platforms. But that won't help to run the app in laptops.

Another requirement from the stakeholder will be to have native web app even if we have working web application. That is to make sure the application is present in the app stores in the way standard mobile applications are present and users don't need to worry about the web application url. They just need to install the mobile app from the store.

So only one way to meet the above requirement of running in desktops, laptops and as native mobile app is to develop application using HTML5 and create native wrapper applications which uses WebBrowerControl / WebView to show the HTML5 web site inside the native mobile app.

But will that make our the development life easier? If the application is very simple, it is easy. But when the application gets more features, problems will starting popping up. Below is one of the problem we faced in such a scenario.

Problem

The application needs to have Facebook login. It is easy to setup that using the Facebook javascript sdk. It worked well when we try this from laptop and the mobile browser. But when the same is tried from native Android wrapper we got an issue. After Facebook login, it ends up in a blank white page. 

The analysis leads to Android WebView limitations. The Facebook login SDK normally creates browser window child window and after login it will close that window and control will be passed to parent window. But when we show the same page using Android WebView control. That javascript popup window closing is not working.

Solution

The solution is as follows 
  1. Show the FB login popup in a different WebView control
  2. After the login success, close that window. 
How do we achieve that? Below are the tasks to be done.

Task 1 - Show login popup in different WebView

There is already a WebView in the application. We need to catch the javascript popup show event happened inside the web page and show that popup in a different WebView control. To do that we need to follow steps below
  1. Subclass WebChromeClient and override it's onCreateWindow method. Name it as UriWebChromeClient
  2. From the onCreateWindow method create object of new WebView control and add to the view.
    1. When we create the second WebView control, associate that to our custom WebViewClient which we are going to create in Task 2. That is required to close this second WebView.
  3. The new UriWebChromeClient class object needs to be connected to the existing WebView by calling webViewObj.setWebChromeClient() Method

Task 2 - How to know FB authentication is success to hide WebView

Now we need to think how the Android web view knows whether the FB login is successful. It can only be determined by looking at a particular URL(https://m.facebook.com/v2.0/dialog/oauth) where the FB will be redirecting after login success. How do the Android web view knows that the web redirection happens? It can be done by sub classing WebViewClient class. Steps below
  1. Subclass the WebViewClient class.Name it as UriWebViewClient
  2. Override the onPageFinished() method of WebViewClient in the new inherited UriWebViewClient class and check for the url. If the URL is "https://m.facebook.com/v2.0/dialog/oauth", we can decide that the FB authentication is completed and its time to hide the second WebView.
  3. Override the shouldOverrideUrlLoading() method too and do the similar.
The code is mentioned in this SO link .Only difference from this link is the onPageFinished method overriding.

Reference links

Tuesday, July 22, 2014

Not able to uninstall .net assembly from GAC

Occasionally when we try to uninstall .net dll from GAC by pressing delete button, it will show the below error message.
Unable to uninstall: assembly is required by one or more applications

Solution 1 - Run in admin mode

The major reason could be the user don't have permission to delete the dll from GAC. If we run the windows folder explorer in administrator mode it might be uninstalled. How to run the windows explorer as in administer mode? We cannot right click and "Run as administrator" on any item to get an explorer window in admin mode. So we need to run the cmd in admin mode. and use the GACUtil.exe to remove the dll. 

Most of the cases it will get uninstalled. Else try the below link to and uninstall as admin .

Solution 2 - Installer problem. Edit registry

There is one more reason why we cannot uninstall from GAC. Sometimes the the assembly might have installed into GAC by installers and they will hold the reference so that we cannot uninstall from GAC. If this is the case we need to remove some registry entries present inside the below registry path.

[HKCU\Software\Microsoft\Installer\Assemblies\Global]
[HKLM\SOFTWARE\Classes\Installer\Assemblies\Global]

This is already reported to MSFT and more details can be found in below links.
http://support.microsoft.com/kb/873195
http://blogs.msdn.com/b/alanshi/archive/2003/12/10/42690.aspx

Last week when I was trying to run a sample which I got from internet, it was loading wrong Microsoft.Practices.Unity.dll. I could see that there is one Microsoft.Practices.Unity.dll of different version in the GAC. So thought of deleting it from GAC and it ended up in the above mentioned error.

Monday, July 14, 2014

Hosting ASP.Net MVC app in Windows 8 IIS 8 - HTTP Error 403.14 - Forbidden

Recently I was trying to run an ASP.Net MVC application in my new Windows 8 environment. When I run the application from visual studio, I got the below error.

HTTP Error 403.14 - Forbidden

The Web server is configured to not list the contents of this directory.


It was silly as the Windows 8 by default don't support pre .Net 4.0 versions also we need enable programming support explicitly.

First We need to enable it in
Control panel -> Turn windows features -> .Net framework 3.5(includes .Net 2.0 and 3.0) in case the project is targeting older version.

Also we need to enable ASP.Net development support too. Go to  Control panel -> Turn windows features -> Internet Information Services-> World wide web services -> Application development features and enable ASP.Net 3.5 and 4.5 based on the project target.

http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-using-aspnet-35-and-aspnet-45

Tuesday, July 8, 2014

Why my Roslyn extension is not getting loaded?

Below is my experience when I started working with a Roslyn project which I got from my colleague. First thing

Is the Roslyn compiler enabled for the Visual Studio test instance?

Yes there is something called enabling Roslyn. As we know Roslyn is the new compiler. The Visual Studio can now support 2 compilers. Traditional and Roslyn. So how the Visual Studio knows, it needs to use Roslyn? 
The answer is the below command line argument which needs to be passed to Visual Studio process devenv.exe when its started.

/rootsuffix Roslyn

If we are building VSIX extension project, we can mention this command line argument in the project properties->debug tab. This will make sure the test Visual Studio instance will be using the Roslyn compiler.

If the visual studio test instance itself not starting when we run the extension project, make sure the below path is there in the Project properties->Debug -> Start external program text box.

<Drive>:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe

Is the VSIX extension actually loaded or there is any bug in my code?

First of all check whether the Visual studio test instance can start with Roslyn enabled. If yes, load a project in the test instance of Visual Studio. If so go back to parent Visual Studio where we write our extension code and look at Modules window.

Debug->Windows-Modules

If our assembly is listed there in indicate that the extension is loaded. Now we can go to next debugging step.

Why the VSIXManifest is copied to wrong Roslyn extensions folder

If we are not able to find our extension assembly in the modules window, it indicate that the Visual Studio is not able to locate our extension assembly. To understand this better we should understand how the Roslyn extension is working under the hood. When we press the run button on the Roslyn extension project from VS,

  • It is compiling the project and copying the dlls including the extension.VSIXManifest file to the below mentioned location
    • <Drive>:\Users\<name>\AppData\Local\Microsoft\VisualStudio\12.0Roslyn\Extensions
  • The above underlined folder name "12.0Roslyn" is controlled by a project property given below
    • <VSSDKTargetPlatformRegRootSuffix>Roslyn</VSSDKTargetPlatformRegRootSuffix>
If the property hold a wrong value, it may copy the compiled vsix extension to wrong folder and the Roslyn extension will not take effect when we load Visual Studio test instance.

Why my VSIX extension files are not getting copied to Roslyn extension folder

Sometimes we will be having proper value in the <VSSDKTargetPlatformRegRootSuffix> tag. But still the files may not be copied. That will be due to improper values in the below project properties.

<IncludeAssemblyInVSIXContainer> true </IncludeAssemblyInVSIXContainer>  
<IncludeDebugSymbolsInVSIXContainer> false </IncludeDebugSymbolsInVSIXContainer>
<IncludeDebugSymbolsInLocalVSIXDeployment>  false</IncludeDebugSymbolsInLocalVSIXDeployment>
<CopyBuildOutputToOutputDirectory>    true</CopyBuildOutputToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>    true </CopyOutputSymbolsToOutputDirectory>

Best solution is to remove all these properties so that it will take the default behavior and default will copy required dlls to extensions folder.

Can I change these VSIX project properties using the properties tab?

The answer is NO as the project properties tab don't have the UI to support these properties. There is already a bug raised to Microsoft.

Is there a real issue in my code?

If all these things are set properly and still our Roslyn VSIX extension is not working, there is something wrong in the code. Inspect the code for below scenarios.
  • Class level attributes.
  • The interfaces implemented 
  • Whether the SymbolKindsOfInterest property returns proper list?

More links


Happy debugging...