The curious pattern of pre-emptively rejecting the solution to your problem


A frustrating pattern that shows up occasionally in customer questions is the case where the customer poses a problem, and pre-emptively rejects the mechanism explicitly designed to solve that problem.

How can we change the widget color without using IWidget::Set­Color?

Um, the whole point of IWidget::Set­Color is to change the color of a widget. Why are you rejecting the mechanism whose sole purpose in life is to solve the very problem you are having?

Usually, if you press hard enough, they will cough up the reason why they think they cannot use the solution specifically designed to do what they want. Various excuses tend to come up over and over.

One excuse is the belief that the proposed solution does not work in a particular scenario. “We cannot use ACLs because they don’t work on network volumes.” Um, yes they do. Check it out.

Or that the proposed solution doesn’t fit their choice of technology. “We are programming in a language that does not support COM objects. We can only p/invoke to C-style APIs.” Well, you can work around that problem by writing a helper DLL that exposes a C-style API, and implements it by calling the COM method.

Or that the proposed solution violates some vague corporate policy. “We have a corporate policy that users cannot change widget colors, so the IWidget::Set­Color method returns E_ACCESS­DENIED. We’re looking for a way around that policy.” Okay, well, now that’s something you need to take up with the people who establish your corporate policies. Don’t come to us looking for ways to circumvent corporate policy.

One time, the reason came from our own technical support staff: “We cannot write a C++ program that calls IWidget::Set­Color and provide it to the customer because we are not a developer support team. We are not allowed to send compiled binaries to the customer for liability reasons, and we generally do not send source code because our customers typically do not have the expertise or desire to install Visual Studio and the Platform SDK just to compile and run a five-line C++ program. (Did I mention that we are not a developer support team?) Can it be done from a batch file?”

Yeah, how about this batch file:

 >changeColor.cs echo using System;
>>changeColor.cs echo class Program {
>>changeColor.cs echo public static void Main(string[] args) {
>>changeColor.cs echo ...
>>changeColor.cs echo }
>>changeColor.cs echo }
%windir%\Microsoft.NET\Framework\v4.0.30319\csc changeColor.cs
changeColor blue

Only half-joking.

The non-joking answer is “The customer can take this information to a developer support team, or at least somebody who will write the program for them, if they don’t know how to write a program themselves.” Microsoft Consulting Services exists for this, but that is likely overkill for a five-line program.

Comments (28)
  1. Damien says:

    The one's I like are when someone says "I can't use X", and then refuses to elaborate on WHY. So then, you come back with "Well, if you don't want to use SetColor(blue), you could use SetAttribute("Color",blue)", and they again reject it (and again refuse to say why).

    It then becomes a fun guessing game as you proposes solutions and see each one shot down, and try to divine the pattern yourself on what is or is not prohibited.

  2. Jack B Nimble says:

    IWidget::SetColor is for the commoners. I want the secret Microsoft method for setting the color of a widget.

  3. @Jack B Nimble: that secret method would be using the Force so that a cosmic ray flips the right bits in the computer's memory, Of course, all the rest of us, poor non-Jedis, have to use the more mundane method of generating binary code through a compiler and then running it :-P .

  4. Rick C says:

    @Damien somewhere around the second rejection I'd ask why, instead of continuing to provide solutions they're going to reject.

  5. Rick C says:

    "that is likely overkill for a five-line program."

    Raymond, your sample looks like it was written by underpants gnomes.

  6. jim says:

    Obviously the correct solution is to distribute tinted spectacles along with your software.

    (I wonder if Microsoft could distribute kernel-tinted spectacles to developers? That might help cut down on confusion.)

  7. Joshua says:

    ["We have a corporate policy that users cannot change widget colors, so the IWidget::Set­Color method returns E_ACCESS­DENIED. We're looking for a way around that policy." Okay, well, now that's something you need to take up with the people who establish your corporate policies.]

    The engineering response to a brain-dead corporate policy is to bypass whatever is enforcing it. Sometimes the policy cannot be changed for political reasons but must not be enforced. This is also what leads to the various patches circulating that disable group policy altogether.

    [Yeah, how about this batch file: ]

    No joke. I've threatened to take advantage of the near-guaranteed compiler before.

  8. JM says:

    "The problems of the real world are primarily those you are left with when you refuse to apply their effective solutions." –E. W. Dijkstra

  9. configurator says:

    Off-topic, but I like your batch style of putting the redirection before the command. I knew it was possible but never ever considered actually writing code that way. I might adopt this.

    [It's essential if you want to avoid trailing spaces and don't want to run into trouble with lines that end in a digit. -Raymond]
  10. Yuri says:

    LMAO @ the batch file.

    Theres a batch file solution to every problem XD

  11. Mc says:

    That reminds of batch files I used to write a loooonnnnggg time ago that scripted the old DOS debug.com utility to enter some bytes and run it.  I also seem to remember this was a safe way for virus binaries to be distributed to interested persons.

  12. Matt says:

    You can always just poke the screen with your finger. That'll change the color of the widget without calling any APIs at all.

  13. @Matt: You make the assumption that the display device is an lcd panel. That's a bad assumption if your widget needs to be blue for all users. (In fact the touchscreen on my phone doesn't change with finger pressure either!)

  14. wsl says:

    @Brian_EE: You're not pressing hard enough ;)

  15. Steve says:

    For some particularly unfathomable reason my take away from all of that is: PowerShell would have been far simpler.

    c:powershell.exe Namespace::IWidget.SetColor($color)

    My appologies for the pedantry.

  16. Henning Makholm says:

    How about: "For various reasons we're considering technology Y for an upcoming project, and I'm trying to get a handle on which kind of problems that choice may lead to. One problem is changing widget colors, where it looks like it would be quite complex and painful to call the ordinary IWidget::SetColor from Y code. Is there a different way to achieve the same effect in a more Y-friendly manner? An email interface would be ideal, because email meshes particularly well with the Y concurrency model."

  17. Andrew says:

    '"We are programming in a language that does not support COM objects. We can only p/invoke to C-style APIs." Well, you can work around that problem by writing a helper DLL that exposes a C-style API, and implements it by calling the COM method.'

    This doesn't seem quite as reasonable to me as your other retorts. There are languages that don't do COM, and there are compilers that don't emit DLLs. C-style API calls constitute a lingua franca; COM doesn't, no matter how much Microsoft might promote it as such.

    [My point is that there is an obvious workaround: Write a shim DLL to translate between the two models. You can argue about which model is better, but that doesn't change the fact that there are two models, so you have to deal with it. -Raymond]
  18. Joshua says:

    @Andrew: I'm well aware of that.

    An amusing case was calling some COM entity from NSIS installer. NSIS can't do COM lookup, and DLL plugins for it have to be specially compiled as the C libraries aren't set up. If the vendor's compiler can't it's quite a puzzle. It turns out that NSIS can in fact be used by treating the COM interface as an ordinary structure and walking the vtable, but it's very painful.

    Thankfully this comes up rarely in cases early enough in the install that the C++ runtime install can't run first.

    This gets from amusing to painful when calling via a strange language that doesn't know about COM and can't coerce types. Having to write all those wrapper modules (same DLL or many DLLs doesn't matter) gets painful.

  19. MItaly says:

    @Joshua: I don't see the problem, why can't you just statically link the CRT? It's routinely done for small utilities and other situations when you don't want to have the CRT package as a dependency.

  20. Joshua says:

    @Matteo: Because the static CRT isn't redistributable (as in the .LIB file, not the resulting binary).

  21. Chris Chiesa says:

    I might want the SetColor equivalent that works on all controls, not just those the Microsoft API designers decided to permit.  What's the big damn deal about letting me make e.g. a "STOP!" button that's red with white lettering even though the system Button Face Color is part of the systemwide theme / colorscheme?  I frequently have reasons to want to get around ARTIFICIAL LIMITATIONS in the abstract APIs that have been wrapped around the fundamentals that do what I want.

  22. TightA*** says:

    "%windir%Microsoft.NETFrameworkv4.0.30319csc changeColor.cs"?

    Is this suggesting that the C# command line compiler comes with the .NET framework? Can we therefore use it without Visual Studio? Not that it probably matters since VS Express is free anyway but this would be a way to use it without installation of the VS product.

  23. @Chris Chiesa: So we have you to thank for all those horrible GUIs that ignore all conventions and user defined properties? Believe me you may think that having 50 applications on your desktop that all look and behave completely different from each other is great, but users disagree.

  24. Drak says:

    @TightA***: seeing as .NET websites that aren't precompiled use this compiler to compile on the fly as a page is served for the first time, I'd say that you have a good chance to find this compiler in the .NET framework folder :)

  25. If the calling language doesn't "support" COM, what's so hard about using the vtable directly?  After all, COM was explicitly designed to be usable from C and not require C++.

    Writing a wrapper DLL and creating a whole new project might be a bit overkill…

  26. configurator says:

    [It's essential if you want to avoid trailing spaces and don't want to run into trouble with lines that end in a digit. -Raymond]

    Good point. I usually use bash where the trailing spaces are omitted unless quoted, so I wasn't aware of this problem.

  27. Damien says:

    @Rick C – I was trying to highlight the users who *refuse* to tell you why. I admit, I've usually given up after only a single round or two.

  28. Douglas says:

    @TightA***: Yes, the C# command-line compiler is installed with every version of the .NET framework. You do not need Visual Studio to build .NET applications.

Comments are closed.