SAP .net Connector 2.0 (NCo) RFC Server in “Running” State but not appearing in SAP

Recently I was involved in upgrading an old component from one SAP server to a different one. It uses SAP Connector 2.0 which is still supported but has it’s end of life in 2013. The PROGID, Gateway Server and Host were changed to point to the new server and the application log showed that the RFC server reported “Running”, but it wasn’t showing up as a registered endpoint in SAP. (Testing the RFC Endpoint also delivered “Program ID not registered.”)

After a lot of thinking, searching and trying many approaches we finally managed to get it going, but since I hadn’t seen this particular case anywhere on Google I must share it.

Turns out that the old server was upgraded from a 6.4 SAP kernel to the 7 series. One of the major changes of this was that librfc32.dll (a library the .Net Connector 2.0 depends on) is not copied to c:\windows\system32 anymore. Since the 6.4 had been installed on the old server the dll was present and this issue never turned up (and so wasn’t documented in the installation documents).

The solution was easy enough to copy librfc32.dll (beware there is also a unicode version librfcu32.dll which we copied just in case aswell) from the SAP directory to c:\windows\system32\ and then the application registered without any hesitation.

<rant>Only took 4 hours to find though. I just hope the newer SAP .net Connectors are a bit more debugging friendly and don’t just output “Running” when they are obviously not.</rant>

Great Sites! Great First Impressions? Learning from the best landing pages available.

In the past I never gave too much thought to the design of my web applications. Lived by the motto “if it succeeds I’ll hire a designer”. This time I’m taking a different approach. Mainly because I really believe that we are building something big.

But how do you go around designing a web application. I’m not a designer and have worked with enough to know you don’t just explain the idea, off they go and come back with awesomeness. The best results came after I had put a lot of thought into the problem myself.

In this new venture we have access to a UX expert and I have experience with a handful of UI designers. So the basic idea is to mockup everything, iterate on the UX and once that is done we hand over to designers.

My task today is to mockup the start page. Clearly the most important page of all, so I am trying to be as structured (and therefore comprehendable for my team) as possible. To start off I defined what different kind of users are coming to this page. They have different goals that all need to be catered for. But how do you put that all on one page? So why not look at apps and site I frequently use. Learn from the best, right?

I’ve focussed on services with a download and with a secured content area since this is closest to what we are building. For these kind of apps the start page serves three user types:

  • NewGuy: Wants to know what it is.
  • Adopter: Wants the software or wants to create an account.
  • User: Wants access to the secured area.

Dropbox

First impression: Lot’s of white space.

  • New Guy: One click plays the video, 40 seconds later you know enough.
  • Adopter:
    • One click leads to the right download (determines OS automatically).
    • Account creation link is not directly visible. But I guess most users will create the account in the app after download.
  • User: Two clicks in total, username & password entry.

One thing I noticed is that if you press tab the login window popups automatically and you can only tab to password and the “Sign in” button. Using the keyboard you cannot proceed to “play the video” or “download”. Are they assuming that power users are the ones that use a “tab” and don’t need the other two features? Also what about accessibility?

Evernote

First impression: A lot of elements on the page. The download button almost dissapears in the green.

  • New Guy: Main features are visible immediately.
  • Adopter: One click leads to the right download (determines OS automatically) and one click for account creation.
  • User: Two clicks in total, a page reload and username & password entry.

Interestingly the homepage displays a feature set instead of the problem they solve. As a user myself I would have gone with “Save anything you think you might need in the future” & “find that one thing you know you saved with just a couple of words you remember”.

Twitter

I hadn’t seen the new homepage before, so this is a quite genuine first impression: “This could just as well be a pay wall to a news site”. Would you think that if you had no idea what Twitter is?

  • New Guy: The value description is too broad and applies more prominently with classic media sites. Clicking on the picture doesn’t do anything. There is a small “About” button which leads to a lot of text and somewhere in there is the Twitter video.
  • Adopter: 3 Fields and you’re good to go. Since the desktop experience is the web site you don’t need to download anything. Thankfully*.
  • User: Username, password and you’re in.

The twitter video has no voice-over and centers on the experience. Sure it creates emotions and a feeling of “ooh I want that too”, but does it show how it differentiates itself from Facebook?

*To download an app from the website: guess and find the link called “Mobile”, send e-mail to myself, then click on link in e-mail to get to the right app store. Four clicks at least.

Spotify

First impression: This is an app store. I can’t believe there biggest element conveys this message. Even the second image which appears a few seconds only talks about trying the premium for 30 days. The premium of what exactly?

  • New Guy: If you do click on “What is spotify” then the message is clearer: “search for music, play anywhere”.
  • Adopter: With “Get Spotify” you’re there in two clicks.
  • User: 2-3 clicks depending on how you log-in.

I love Spotify and hate to see this as their start page. Sadly it’s the same experience in all countries that I tried. They just translate the “app store” announcement.

Google Chrome Browser

First impression: Sure it’s minimalistic, but is the empty browser window that covers a large part of the page necessary? Older versions even had content in that screenshot. My focus is certainly directed towards “fast, free” and the blue download button.

  • New Guy: It’s a fast, free web browser. Says it right there.
  • Adopter: One click to download.
  • User: not applicable.

That blue button just jumps at you. If this was there only product they could have gotten rid of a lot more elements on the page, but it doesn’t look cluttered at all.

Other examples

Nozbe

First impression is the site’s pages are little too dense with information. Targeted at GTD users the start page slogan “simply get everything done” is recognized immediately. On the sign-up page you are led to think you need to choose a plan even though you don’t.

Trello

The video is Joel demo-ing the app, with lot’s of aehms and uhms, but it’s very natural and great to watch. I actually immediately made myself a task to create another board for our project.

The one think I thought I liked was the search box. I didn’t know if they already had a mobile app for Trello but searching for mobile app leads me to strange looking search results. It’s actually a search across the public trello boards and not a search on the Trello site itself.

Take-aways for us

1. A basic value proposition on the first page

Three illustrations on what we offer that leave no confusion. This will take a lot of time to get right, but it’s essential for grabbing the attention of visitors. Focus on the problem you solve and not the features.

Follow-up with a natural video taking you through a basic case and 1-2 more complex use cases.

2. Immediate log-in

Most of the apps show you the secured area immediately (if you have the appropriate cookie). If that can’t be done I prefer username and password fields to be at most one click away, but certainly not require a new page to load.

3. Don’t make the user choose

If possible figure out what the user needs to download. If you can use the referrer to determine what the incoming user is most probably looking for adapt the experience to that.

4. Demo account / screenshots

Hardly any of the sites I looked at had any kind of demo account. When I download tools or utilities I always search for the screenshots of the application first. For online apps I would expect to see a demo account that I can look at immediately (which to be fair many business web application do have).

5. Make sure every action has a reason and is clear

Last but certainly not least. Anything on that first page needs to be there for a reason. It has to be clear to everyone what it means. Test, ask and observer what people do. Reason enough to keep the elements on the first page to a minimum so that testing does not get out of hand.

How do I run dotLess on embedded resources? or How to embed .less files in assemblies?

I’m in the process of creating one central library for future ASP.NET libraries that will do all the setup and wiring of the infrastructure and also deliver core files (e.g. Twitter Bootstrap CSS + JS). In .NET Assemblies non-code (i.e. content files, such as .less files) can be embedded by changing the build action on the file to “Embedded Resource”.

Accessing file contents is easy once you remember that the filename is prefixed with the Namespace. So if you embed the file foo.txt in a Directory “bar” of a project configured with the default namespace “companydll” then the embedded resource will have the filename “companydll.bar.foo.txt”.

Simply pass that to the GetManifestResourceStream method and read the contents as follows:

public string GetFileContents(string file)
{
  using (Stream stream = this.GetType().Assembly
                             .GetManifestResourceStream(file))
  using (StreamReader reader = new StreamReader(stream))
  {
    return reader.ReadToEnd();
  }
}

So far so good. You can create MVC controller methods that load files from the manifest resource stream – just remember to always check the request file against a whitelist of allowed files.

In my case I embedded some .less files and wanted to deliver those to the browser. Working with less in ASP.NET projects couldn’t be easier. The dotlesscss project provides the engine for transforming less to css (and it can even be added using nuget). You simply add an HttpHandler and all .less requests are automatically parsed. But in my case I needed to run the less parser on files from the manifest. So basically I have a string in memory and not a real file path. The problem is the less parser provided by dotlesscss needs a file path to the .less file in order to import referenced files.

I started out by looking at IsolatedFileStorage as a temporary store for the .less files which I could pass to the engine, but there is only a private reflection hack to get to the real path of a file in IsolatedFileStorage, so I kept looking for something better. After a git clone of the dotlesscss source I produced this neat (and in retrospect very simple) solution to this problem. You can simply override the file provider for the less engine and read the files from the manifest stream.

public class DotLessEmbedded : IFileReader
{
 private LessEngine m_lessEngine;
 private string m_filesNamespace;

 public DotLessEmbedded(string filesNamespace)
 {
    m_filesNamespace = filesNamespace;
    if (!m_filesNamespace.EndsWith("."))
      m_filesNamespace += ".";
    m_lessEngine = new LessEngine();

    // Changed for dotless v1.2.4 - IImporter was introduced
    // but lacks the FileReader property, so cast required.
    (m_lessEngine.Parser.Importer as Importer).FileReader = this;
  }

  public string TransformToCss(string file)
  {
    return m_lessEngine.TransformToCss(GetFileContents(file), file);
  }

  public string GetFileContents(string fileName)
  {
    using (Stream stream = this.GetType().Assembly
          .GetManifestResourceStream(m_filesNamespace + fileName))
    using (StreamReader reader = new StreamReader(stream))
    {
      return reader.ReadToEnd();
    }
  }
}

(Remember to reference and import dotless.Core.Input and dotless.Core.)

With this class you can simply transform any embedded less file by using:

var dotLess = new DotLessEmbedded("Web.Core.Assets.Bootstrap");
var out = dotLess.TransformToCss("bootstrap.less");

Office 365: “Your data will be deleted in 1 day(s)” – Or how to scare the **** out of customers

Everyone knows a good psycho thriller always involves some kind of countdown. It really increases the suspense. Microsoft seem to have adopted a similar tactic, which is great at first glance. After all they are warning you that your DATA WILL BE DELETED. Definitely something I want to know about and constantly be reminded of if I don’t take action (no sarcasm here actually!).

Trial users of Office 365 will have received numerous emails from the time the trial ends until 30 days (+15 days grace period as far as I can see) after that telling them to buy a license. Ok, sounds reasonable. People may have signed up for the trial and forgotten about purchasing real licenses and nobody wants to lose their data. In my case I signed up for the trial, got hooked and bought the licenses probably a couple of days after that. So my license panel reads:

It was my understanding that as long as “Assigned” licenses <= “Valid” licenses then everything is fine. I could let those expired licenses simply expire.

Now I’m not easily irritated and assume that the Office 365 Portal simply forgot to do the math and just sends those warning whenever trial licenses are in your account. But an assumption won’t be enough for customers asking the same question, so let me reassure myself and them.

First of all I really appreciate that the warning email is not sent from a “noreply@microsoft.com” – it actually goes to msonlineservicesteam@microsoftonline.com. Awesome, that’s a +1 over Google Services (where asking questions per email is apparently a no-no).

Quickly fired off a reply asking what the warning will do in my scenario. This was back at the beginning of September. A couple of days ago I got the “7 day warning”. I again sent an email reminding them they had left my email unanswered and asking what to do. Still no reply. WTF? I did pay my subscription didn’t I?

I know there is a great forum (and I have received helpful information there before about technical issues) but this is a financial/licensing (and usually confidential - especially for customers) issue which I’m not going to post on a public forum – that’s why I am a paying customer and expect answers to questions like these via email. Sadly I don’t even know if my email was ignored, deleted or is still in progress, because I didn’t get any answer at all. Not even one of those kind automated emails thanking you for your email.

Dear Microsoft. Don’t be a faceless monster in the cloud and try to:

  • Answer emails (especially if I am paying and especially if “DATA WILL BE DELETED”)
  • Implement some form of ticketing so that I at least know my issue arrived and is being looked at by someone.
  • Or simply don’t send out warning emails if my data is not really in jeopardy.
All I can do at the moment is wait for tomorrow and hope our data is safe (and of course run a backup tonight).
UPDATE 2011-10-18
For anybody who finds this and is worried what really happens. The deadline went by and as I had suspected it was just an overanxious e-mailer and in reality as long as “purchased licenses” >= “assigned licenses” then you are fine. No data was lost, no customers were upset. Just a case of bad communication.

Office 365 does not allow more than 16 character passwords or “Why, why, why???”

Since my first article about a financial institution’s policy on password length I’ve encountered a couple of examples. All of which were not really worse than the one I had mentioned before but today I was happily signing up for Microsoft’s new online services offering and was prompted to change my password (n.b. I was in the trial). I whip out my Keypass, make an entry and get presented with the following:

 

Why oh why would you ever put a maximum length on the password field? Even if the database size is a concern (really?) would it make sense to bump the limit to something much longer like 100 or 200 characters. Even the default security setting for KeyPass (which I’m sure many people use) is longer than 16 characters.

I may be Microsoft-friendly and it won’t keep me from using the service, but come on Microsoft. Ask the guys who wrote the (ludicrously long) method: HashPasswordForStoringInConfigFile

 

 

Lessons learned from using the Facebook Like button

I recently launched a side project with some friends and wanted to use Facebook “Likes” as a simple voting mechanism (and viral marketing tool of course). The page (plug: http://threelikes.com) gives you a link every day in one of three categories. Basically a simplistic cure for information overload from all those social aggregator/news sites. I wanted to include a Facebook Like button beneath each link in each category so people could vote on it. Simple enough you would think. Facebook provides a little wizard for creating the buttons and it didn’t take long to figure out how to customize the url that was being liked.

Each link has the format threelikes.com/date/category so people go to the sites via us (for statistics purposes and so people can share the link – we bought 3lik.es for that purpose). Being a good internet citizen (and in order not to comply with Google “law”) I decided to implement a permanent redirect (HTTP 301) for redirecting to the actual destination site.

Next up I started testing the “liking”. At first everything looked great, the site was appearing on my wall. But wait, no reference to our site. Turns out Facebook respects 301 redirects. This makes sense (why would you store or show the “old” link that is redirecting) but is not optimal for us. Apart from not contributing to our viral marketing it actually defies the purpose of including it: the voting. My first test suddenly displayed “400 people like this” which was great but only on the surface. Because my short link was redirecting to the much bigger destination site it was displaying the likes from the destination site on my page. This distorts the voting results.

So my solution was to return a client site (META refresh) redirect from an intermediate page. This is not perfect (and if anyone has a different idea please ping me) but it achieves what I wanted. People click like and the information (title and a short description) we provide appears alongside our own url. When people click they briefly see the intermediate page (unstyled in order to reduce page load) and are then redirected to the main page. Worked great, except for the times when it didn’t.

I’ll spare you all the dirty details of debugging the like button, but the most important parts are:

  • Check you have all the required open graph meta tags in your page and choose the right og:type (in my case the redirect page is article not website – read about the difference here).
  • Check the url you are liking in Facebooks lint: https://developers.facebook.com/tools/lint/
  • If and only if there are no errors, click once with your real account (do it too often and your urls start to get blocked and the error message is hard to find!)
  • You can test a bit more by using Facebook test users (available via developers.facebook.com).

Some things I will think about in the future is: (1) using a iframe or standard frame (2) finding a way to use server side redirect but customize the Facebook Like url to point to us

SharePoint: Why won’t you let me delete a column? A case of “Cannot complete this action.”

Today I deployed a custom SharePoint column and list definition to our productive systems and added some extra columns to test some functionality. I then wanted to delete them again. Boom: ASP.net Error page. ULS told me: “Cannot complete this action. Please try again.“. Suffice to say: Trying again did not help.

Fired up the all-might Powershell and tried deleting the column from there:

PS C:\swFiles\DualConsult.SharePoint.SecretsList\Scripts> $field.Delete()
Exception calling "Delete" with "0" argument(s): "Cannot complete this action.
Please try again."
At line:1 char:14
+ $field.Delete <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

Nothing obvious turned up in ye grande search engine so I had a look what was different about this list and other lists. Turns out I had created a custom content type for the list and it was the only content type on the list (the standard “item” content type wasn’t part of the definition). Since I had used this pattern before I didn’t suspect anything wrong, but since I was stuck I went ahead and added the “item” content type.

SharePoint 2010 - List Content Types

SharePoint 2010 - List Content Types

Tried deleting the columns again and voila it worked. Interesting side note: Once I removed the “item” content type again, I could delete the second column I had created without any problems as well. SharePoint, you are strange.