Monday, August 3, 2026
Your Bluetooth is bad, August 2026 (Battery and Name)
Wednesday, July 8, 2026
API Rules for designers: use one encoding, not two
API Rules for designers: use one encoding, not two
"If you haven't tested your code, it's probably wrong"
Today's bad API example is from the Bluetooth Heart Rate system. Most of the protocol is fine: you get a notification every so often with updated heart rate information (e.g., heart rate in beats per minutes (BPM) plus optional stuff for overall energy and the "RR Interval" for fine-grained heart data).
Testing this protocol is extra expensive because the heart rate (BPM) can be sent in two ways. It might be a single byte, and it might be two bytes. There's a single bit in a flags structure to say which way it is. If the person's heart is 255 BPM or less, it's one byte. If it's 256 or more, it's two bytes. The app code (and device code) has to handle this.
For an app, the code is hard to test for two reasons. Most importantly, a human doesn't ever have a heart rate that high (according to Copilot, "255+ BPM is possible, but it’s always pathological"). The second is that even if I could find a person with a heart rate that high, I have no confidence that any specific consumer-grade device will ever produce this data. As just a person coding in their spare time, I can buy a couple of heart monitors. But imagine I still worked at Microsoft: what are the changes that a VP (that's the clearance it takes for approving purchases) would sign off on an unknown number of devices on the chance that one of them would produce this data?
In the end, I've got code in my new Bluetooth app (not on the Microsoft app store yet) to handle the special flag. But my confidence that it works isn't great.
The right API choice was to always send 2 bytes of data and not try to make something in the name of spurious efficiency.
For the nay-sayers: the awkward protocol doesn't support any interesting new scenarios, and doesn't have any appreciable amount of energy.
If they had kept the protocol as-is, developers would have the same abilities. The RR Interval data size would shrink from 9 entries to 8 -- but in typical use, there's only 3 or 4 entries. And if there's a case for needing more than 8 entries, the Bluetooth device could simply transmit more often.
Takeaway: Protocol designers should always include "how will a developer test their code" when considering complicated APIs.
Friday, April 3, 2026
IL2104 IL2026 TRIM and JSON with WinUI3 and newer C#
JSON: why is C# TRIM so horrible for no reason
Trim analysis warning IL2026: SerializeExtra.Demonstrate_Bug_Program.Demonstrate_Bug_Main(): Using member 'System.Text.Json.JsonSerializer.Serialize(!!0, JsonSerializerOptions)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.
- When you make your SourceGenerationContext from JsonSerializerContext, always add a TypeInfoPropertyName option
- When you call Serialize of Deserialize, you must use the non-templated versions. Pass in your object (or string, for deserialize), the typeof(yourclass) and your SourceGenerationContext.Default object.
- Never new up a SourceGenerationContext object. When you do, it won't have the JsonSourceGenerationOptions that the Microsoft docs tell you to use
- Always specify a [JsonSourceGenerationOptions(WriteIndented = true)]. If you wanted a compressed serialization format, you'd have used Protocol Buffers, not JSON. When you use JSON, it's because your users want a human readable result, not some one-line nonsense.
Saturday, January 31, 2026
Weird EPUB bug: empty image files in the IRS i1040gi.epub file
This EPUB bug brought to you by the IRS and their i1040gi.epub file
Tuesday, December 9, 2025
Developing on ARM64: DEP0700 failures in Debug mode
Can you solve this error message?
DEP0700: Registration of the app failed. [0x80073CF3] Windows cannot install package NAME because this package depends on a framework that could not be found. Provide the framework "Microsoft.VCLibs.140.00.Debug.UWPDesktop" published by "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US", with neutral or ARM64 processor architecture and minimum version 14.0.33728.0, along with this package to install.
Background: building an existing UWP app on ARM machine
I have one of the ARM64 machines that Microsoft is big on, and of course I have a bunch of existing app (Store link). So what better thing to do than to enjoy a nice coffee in a fancy lodge here in the pacific northwest while updating the Bluetooth app to support a new device?
Except you can't deploy your debug-mode ARM64 app! It fails with the above error!
What's do the might search engines say?
Search engines recommend the following three things:
<Dependencies>
<PackageDependency Name="Microsoft.VCLibs.140.00.UWPDesktop" MinVersion="14.0.24217.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" /></Dependencies>
Or this:
<RequiredBundles>$(RequiredBundles);Microsoft.VisualStudio.Component.UWP.VC.ARM64</RequiredBundles>
Or updating the user's .VSCODE profile. None of these work
Crappy solution found! Just run in x86 mode!
The crappy solution I eventually tried: just run in x86 mode instead of ARM64 mode. Sure, it's a waste of processor time and effort, and sure, it's a stunning indictment of Microsoft's absolute failure to actually support their own freaking devices, but it got me moving forward.
Tuesday, July 16, 2024
EPUB format thoughts
How hard can EPUB files be?
"EPUB is just HTML"! Hah!
I've got a fun EPUB ebook reader in the store; it's got two nifty features that, IMHO, all ebook readers should have (it can do an offline search of Project Gutenberg, and it's got a two-screen mode, so you can see both a critical image and the text that talks about the image in one spot).
Over the years, I've had to work around a lot of EPUB failures. Today's failure is thanks to the newer EPUB books that Project Gutenberg publishes.
Notably, each book seems to include a (pointless) <pre/> tag. The problem with that tag is that HTML does not support self-closing (void) elements. The Mozilla pages are super clear about that.
So my HTML renderer (which is just a WebView element) takes the <pre/> tag and reads it HTML style, like a <pre> tag that isn't closed. The entire rest of the book, which is most of it, is then displayed with pre-formatted lines. Because pre-formatted lines don't wrap (that's the point of the <pre> tag, the rest of the reading experience is mostly ruined.
SIGH.
Friday, March 31, 2023
WTF is “Exact time 256” : diving into Bluetooth SIG documents
WTF is “Exact time 256”
The Bluetooth Special Interest Group (SIG) has a metric ton of Bluetooth LE device specs in a massively confusing pile. In this walkthrough I’ll show how I figured out the details of a fairly simple LE protocol. In particular, I’ll be creating something that needs to match the “Current Time Service”, services # 0x1805.
TL/DR: the good document is the “Gatt Specification Supplement”.
On the Bluetooth.com
site, you want “Specifications” and under specification you’ll need a tab open
for both the “Assigned numbers” and the “Specifications” directory.
In “Assigned numbers”, there’s two important documents. The
first is “Assigned
Numbers Document”. It’s a giant list of all of the GATT services by name
and all of the characteristics. The second is “Gatt
Specification Supplement”.
In the “Specifications” directory, find the listing for the
"Current Time Service” and click the link
to get the service page. It's got a bunch of the lest useful programming documents ever. The only document that’s interesting for most
developers is the Current Time Service 1.1 PDF file. Click the link
to read the long, complicated document.
Page 9 starts to be interesting: the Current Time Service
supports three characteristics: the “Current Time” (page 10), “Local Time”, and
“reference Time”. On page 10 it’s mentioned that we’ll be reading the Exact
Time 256 field. This is the first bit of useful (and critical) information
in the spec.
BTW, when they say “Unknown”, it’s not clear to me which
“Unknown” value they mean. But in the Assigned Numbers document there are 8 time that
“Unknown” is mentioned; all of the numeric values (6 of them) are zero. The
others are weird strings for something having to do with telegrams. Or not,
it’s a Bluetooth SIG spec, so nothing is clear.
At this point you might wonder what the actual bytes are.
The Bluetooth SIG doesn’t care that you’re wondering. You might even try typing
“Exact Time 256” into the main page search box on the main page, but you won’t get any hits.
However, you can find it in the Assigned numbers where it has number 0x2A0C in
the “Characteristics by name” and “Characteristics by UUID” section.
Note that in the “Specifications” it lists “Current Time” as
the characteristic; that’s characteristic 0x2A2B.
And then finally, take a look at the GATT Specification Supplement,
page 78, section 3.62, “Current Time”. It lists the bytes: there’s an Exact
Time 256 and then a U8 “Adjust Reason” which says why the time changed. Even better, there's a decent overview of the Exact Time 256 fields!
And here the path through the forest of all Bluetooth knowledge ends. If only there was some way to know that the "supplement" is in fact the useful document, and not the pile of other docs.
Thursday, January 5, 2023
History: writing fancy code on a plain compiler (Irix version)
Writing fancy code on a plain compiler
This is a story of porting C++ code using all the latest features to a machine whose compiler was (ahem) definitely not supportive of advanced features :-/
Back
in about 1997 and 1998 I was a software consultant and got hired by an old
coworker at Avid to help them port their shiny new high-performance
file-copying software to the Irix. IIRC, they had written it in “portable” C++
which I discovered was anything but ☹
Writing code with no strings attached
What's in a namespace? Nothing.
Exceptionally fine threading
TL/DR
Monday, January 2, 2023
Your Bluetooth is bad, January 2023 edition
Your Bluetooth protocol is bad, January 2023
I've finally gotten over a big hump in my Bluetooth Device Controller program -- I've been poking around with adding and fiddling with devices, and that means that the code has been getting much more "experimental". That's not a good thing for an app that I ship, and which has over 35 thousand downloads! I've been working hard to convert the experimental code into an app that people can use without too much frustration.
With that, it's on to the next installment of this series on crappy Bluetooth protocols, focused on the Govee line of air sensors. The version 1.10 app supports the Govee 5074; the next version (presumably 1.11) will support the 5075 and 5106. All of them suffer from the same three flaws, and the 5106 has a unique and fun new flaw.
Don't shut off communications too early. All of the Govee devices like to shut down their Bluetooth connections really fast -- after about 4 seconds, they shut down the connection even if you've been talking on it. Other devices will wait until the connection has no traffic before shutting down.
Just transmit your freaking data. If you provide data, just provide it: make a characteristic, and make it readable and notifiable.
Don't fold multiple values into decimal values. This is harder to explain. The Govee Air Sensor, as an example, sends out temperature, humidity, and air quality data in a single advertisement. But instead of just filling in 3 two-byte integer values, they instead take the temperature and multiple by 1_000_000. Then then take the humidity and multiple by 1_000. Then they add the air quality. This is all written as a single 4-byte integer.
To decode this monstrosity, you have to read in the 4-byte unsigned integer (in big-endian mode, even though Bluetooth is mostly little-endian). Then do a weird combination of MOD and integer divide operations to split out the three numbers.
Use the right Manufacturer code. The Govee devices mostly use a made-up EC88 manufacturer code; this is an unassigned value that nobody should be using. But the 5106 Air Quality monitor, for no apparent reason, uses the Nokia Phone code (they are manufacturer #1).
FYI: Common Timeout connection parameters
- 100 ms used by the SensorBug
- 175 ms used by the Sphero
- 4 sec used by the microbit, the govee, the kano coding wand, the viatom, the vion, and skoobot, smartibot and espruino
- 5 sec used by the gems activity tracker
- 6 sec used by the Mipow and the sense peanut
- 10 sec used by the inkbird, lionel, the pyle, the powerup, the various sensor tags, and the dotti
Sunday, March 20, 2022
Review: God and Golem, Inc (Norbert Weiner) -- 1964, MIT
TL/DR: I'm glad to have read the book but can't recommend it. The interesting ideas are now widely accepted (computers can learn, and we can't rely on computers to make decisions).
Best Quotes
"A goal-seeking mechanism will not necessarily seek our goals" (page 63)
"This is only one of the many places where human impotence has hitherto shielded us from the full destructive impact of human folly" (page 64)
"A digital computer can accomplish in a day a body of work that would have the full efforts of a team of [human] computers for a year, ..." (page 71). A modern 2022 computer can do the work of 40,000 people for a year in about a second (a Core I5 can do 34969 million FLOPS).
"Written for the intellectually alert public"
Theme: Computers will be like humans
Can computers learn (spoiler: yes)
Can computers make a new computer? (spoiler: eventually, yes)
What's the right place of computers? (helper, not decider)
So, he says that computers will be like humans? (answer: no)
If it's not physics, it's crap
Wait -- what's all this religious stuff?
Where's the golem?
What's with the ", Inc"?
Tuesday, November 9, 2021
IBM 610 Auto-point: weird 1950's computer
IBM 610 Auto-Point computer (annotated)
Have you ever gone into your pantry, closed your eyes, randomly picked out the first dozen ingredients, and challenged yourself to make a dinner from whatever you grabbed? Well, it sure seems like that's how IBM designed the 610 computer.
The keyboards
Programming the machine
Lights, more light, other more lights.
The keyboard includes a set of lights that help you figure out what the computer is doing, and a set of "check" lights.
The actual little numbers 0..9 aren't displayed; you just have to kind of squint and carefully measure where the little dots are. It's not (seemingly) calibrated, and each column can only display one dot. No, you can't display DOOM on this.
The main body of the computer also has lights, this time to tell you what the current program step and current registers are, plus whether the machine is off, on, or really on.
SEQ (Sequence)
You might also want to program with fancy "if" statements. Those are available when you use the paper tape. The paper tape uses an 8-channel (8-bit) code. The top two bits say what "class" any particular instruction is in -- classes 0, 1, 2 and 3. You can specify which classes of instructions you want to run at any time. Yes, this means you a main body, a "if-else" statement, and a remaining "if" statement, and that's it. But good news: you can interleave the different statements together.
But wait -- which class gets used? Answer, of course, as with everything about this machine, is that it depends, There's four switches on the manual keyboard, one for each class, and they can be set to "always", "never" and "depends on the programming panel".
That auto-point isn't really floating point
IBM was really happy with their "auto-point" concept. If you've never used the previous technology -- which would be a "slide rule" -- those devices don't include the magnitude of the number at all. That is, you multiply "1.23" x "6.78" in the exact same way that you multiply "123" x "678" -- you just have to remember where the decimal point is.
With the "auto-point" concept, you get a bunch of registers, each of which can hold some numbers like "1.23" or "6,780". As you enter each number in, when you get to the decimal place, the number will automatically adjust in the machine so that the integer "left side" of the decimal point uses half of your register, and the fractional remainder goes into the right side of the register.
On the one hand, this is convenient: you don't have to remember where the decimal point goes in your result of 83394. On the other hand, very large and very small numbers are absolutely impossible, and your precision will vary all over the place.
In summary:
Wednesday, October 13, 2021
Learning Typescript, and why I'm not a fan
A work project I'm helping out with uses Typescript, I tried to use it for my extension, and now I just use JavaScript. It's all because TypeScript documentation is bad, the module system is silly, their conversion times are slow, and their target user is 100% not me.
I'm a little bit of a computer language enthusiast, and have been for years. My first intern project was to make a YACC grammar for a Fortran "wirelist" program for Teradyne (hi, Chuck!); I designed and built a technically-oriented terminal-based hypertext system for electric engineering; I created an incredibly simple search language for a game company (technical requirement: must be functional in less than one day, because otherwise we'd have to use my boss's approach, and he was wrong).
I was enthused by having a reason to jump into Typescript for this project. I 100% love the concept of typescript: it's like JavaScript, but adds in types, so you make fewer mistakes. Who wouldn't like that? I'm not a fan of being all loosey-goosey with naming, and appreciate the little boost that Typescript add. The generated JavaScript code matches well with the original, making debugging easier.
And then in all went wrong. After a successful start, within a day I stopped working on the Typescript source and instead just edited the JavaScript file.
The compile speeds take me out of the flow. My file is just a few hundred lines long; in JavaScript I can just reload. With TypeScript, you have an awkward pause. The pause is for no technical reason; my files are small, a reasonable program would be able to read it, parse it, and convert it in under a second. (my own current language project is a language converter; my own goal is <1second for a 1K line file)
The module documentation is much to terse. Specifically, if you already know how modules work, and know what you want, then you can understand the module documentation. Otherwise, it fails to provide basic information about what the settings do, and when to use them.
Modules simply emit errors. The goal of Typescript is that it generates working JavaScript. There are two settings for modules: ones that generate non-working JavaScript (the browser sees an import statement and complains that it doesn't know what requires means), and ones that spit out long lists of compiler errors about not finding some package that I'm not asking for (some configuration language).
If your customers are highly motived people then you can get away with badly documented features that generate errors. I'm not that highly motivated, and have an alternative.
Why do I even need modules? Typescript requires modules for two reasons:
The -watch command that's needed to make compile times acceptable only work with the -build switch and that in turn only works with modules. It would have been nice if I would have just typed tsc file.ts --watch and be done with it.
As soon as you have two files, you have to have modules. Otherwise, nothing works.
The language documentation is a barrier to understanding. The documentation for Typescript hardly presents an easy onboarding experience. There's pretty much nothing that I found that presents a high-level work flow, or explains their design choices.
Mathematicians are the bane of computer documentation. I firmly believe that there's a mathematicians brain that some people have, such that they read in equations and very short, very succinct descriptions, and from that generate an entire field. It's actually an awesome ability, and it makes them write completely useless documentation for the rest of us. (Note: I have a degree in mathematics).
Typescript is full of the mathematicians approach: provide a tiny number of words, with no worked-out example, and starting from first principles (which no beginner know) instead of from what starting people need to read.
I wanted typescript to be a powerful new tool in my toolbox for designing programs. Instead, after multiple fruitless hours of trying to make Typescript work within my work-flow, I simply gave up and embraced JavaScript. And it makes me sad.
Wednesday, February 24, 2021
Everything wrong with the FINGER protocol
Everything wrong with the FINGER protocol
For those of you who have never heard of it, Finger is one of the old "litle"¹ TCP services. As a user of a big multi-user machine, you can edit the ".plan" file in your directory; people can then run a command like finger person@example.com and it will retrieve your .plan file along with other information like where and when you last logged in. It was a super useful way to coordinate with teammates back in the days before cell phones had been created.
The protocol itself is pretty simple: the finger command sends a single line of data with the user name, and the server replies with a bunch of text and then closes the connection. So what could go wrong? In this minor screed, I list both things that should have been known at the time, and also things that we know about protocols today that weren’t known then.
TL/DR: the spec is wrong, confusing, incorrectly implemented and potentially dangerous. But other than that, it works pretty well :-)
The protocol spec is incorrect (/W).
Firstly, the finger spec, RFC 1288, is wrong. The "BNF" query notation, section 2.3, with query type #1, attempts to allow an optional /W before the user. The /W is the verbose switch (W stands for "whois") and servers can reply with more information when it's provided. (This is accessed by the finger -l person@example.com switch; -l stands for long). But that's not what the BNF actually says. What the BNF says is that the /W switch is required whenever a username is provided. What should be an optional switch into a mandatory one.
Good news! Every actual finger client implements what the spec tried to say and not what it failed to say. Which is good, because a number of existing (as of February 2021) Finger servers implement the earlier RFC 742, which doesn’t allow the /W switch.
The protocol BNF is clumsy.
The protocol “BNF” in general is more formalistic than useful. There’s an old saying that every level of indirection makes code harder to follow; the corresponding saying for BNF is that simple and common definitions like CRLF should be spelled out each time they are used, not hidden behind a layer of naming indirection. The BNF also loves using short name; {C} is the name of the rule that eventually expands to CRLF, and {U} the rule for user names.
Additionally, the BNF is split into two rules: one for direct user lookup, and one for an indirect network lookup (these are Q1 and Q2 in the BNF). But this makes the Q1 clumsy, as it has to handle both user lookups with no user, and user lookups with a user. A better split would be three query types: a NULL query (with or without a /W), a user query (also with or without a /W) and a network query.
On-behalf-of is not good networking
We can totes forgive the original spec from adding in the slightly weird “Q2” format. This format is used when we're asking server “A” to ask server “B” for information. It’s like the user can’t get the information they want directly; they have to go through a gatekeeper server. The other servers are called Remote User Information Program (RUIP). Back in the 1970s when the RFC was created, the internet was often provided to a single computer at a site; the site then used other protocols and network to connect to other computers at the site (hence the internet used to be described as a “network of networks” which were expected to use non-Internet protocols).
But in modern times, the Q2 “on behalf of” experience isn’t needed. Indeed, none of the servers I found would handle it.
Massive security issues
Finger servers often return the time and location of user logins. For example, FINGER might say that a particular user is currently logged in at a particular terminal in a particular room. This is handy when dealing with friendly teammates, but is totes wrong when dealing with stalkers and worse. Lots of people really don’t want other people to know where they are.
Giant compat issues with modern servers
You might be confused by this one – what could I possibly mean about modern Finger servers? Have there even been any modern Finger servers at all? Why would anyone build a new Finger server given that the Finger protocol is often blocked by firewalls and provides very few features needed by people.
It turns out that just looking on GitHub shows a bunch of different Finger servers. These servers are mostly derived from the original RFC 742 Finger protocol. It’s almost the same as the RFC 1288 Finger, but doesn’t allow for the /W switch. Other servers attempt to handle the /W switch, but don’t do it correctly (finger.farm, for example, failed until recently).
One more thing about the /W switch spec: case-insensitive
[Later edit]: the RFC set of specs has long declared that just strings in the BNF descriptions should always be assumed to be case-insensitive: "monday" is the same as "Monday" and "MONDAY" and "MoNDAy". The FINGER spec takes the opposite approach: the /W switch, AFAICT, is actually case-sensitive and should always be upper-case.
As a fun aside: the RFC editors are, in the instance, wrong. While I understand why they decided that BNF should be case-insensitive (it's part of our text-based heritage), it's also the case that the workaround they use (specify case-sensitive strings as hex characters) is demonstrably error-prone. I've personally filed about a half-dozen different bugs against Internet protocols for getting the HEX representation of strings wrong.
The best solution is to require each BNF description to say if they are case-sensitive or not.
Use these learning for your own protocols!
Finger is part of the old tradition of text-based services that are almost designed for direct command-line manipulation. As such, it’s now mostly out of favor (when was the last time you read your email by directly talking to a POP server?). That said, there are still lessons from FINGER for today.
- Simple, direct protocol descriptions are easier to debug than complex ones.
- Be aware of bad actors. Don't let your APIs enable stalkers and thieves.
- Make sure that the easy path for handling your protocol also allows servers an upgrade path.
Note¹: Finger is one of the litte TCP services noted in RFC 848 along with echo, discard, systat, netstat, quotd chargen, finger and a couple of time-related services.
Sunday, May 24, 2020
Your bluetooth is bad (continued)
More example of how to make bad Bluetooth devices
What format is my number?
Bluetooth developers continue to create a bewildering variety of undocumented data formats. Indeed, it's a race between them and the bizarrely incompetent "Distributed Ledger" teams for the worse numerical formats.- Nordic Thingy -- you can't just describe a value as a "uint_16"! Specifically, you can't do it because I don't know if you mean a big-endian or little-endian value (as it turns out, the Nordic Thingy is little-endian)
- Also Nordic Thingy -- describing a temperature as a signed value and an unsigned fraction only works if you tell me the denominator of the fraction. Some devices might reasonably make the "fraction" part be out-of-10 to get a degrees in a tenth of a degree (which is just fine for a weather station), or it might be out-of-100 or even out-of-256.
Your Bluetooth is Bad, continued
Very silly Bluetooth protocols, continued
Sunday, September 23, 2018
Another grumpy post, this time about Application Insights
What is Application Insights, and why is it awful?
- When I made my Windows App, Microsoft not very helpfully added a reference to it in the project. I spent time to understand what it was (it is supposed to send up "telemetry" to some dashboard somewhere). I decided to keep it because I didn't want to offend the Awful Scary Microsoft Monsters.
- When I got scary email saying that I'm about to spend hundreds of dollars a month to get some alleged insights because Microsoft decided that hosting a ton of data was expensive, and they didn't want to foot the bill forever. Luckily my actual usage is almost nothing (I think).
- When my updated projects simply refused to compile. Except when they did compile. But they never compile when I'm making an app store
- And just now, when I finally ripped off the bandage, and remove the Application Insights packages from my app.
- Oh, and while I'm at it, I figured that I might as well look and see what awesome insights the Application Insights is giving me. I turns out that whatever data has been sent up is gone; when I go to my Azure Portal, there's a grand total of no data at all, or even a hint that any data has ever been sent up
Friday, June 1, 2018
Ethereum uses what base encoding?
Base 58 is about the dumbest thing ever
Friday, May 15, 2015
Stupid Idea #692: The installed client has fewer features than the web client
Keep in mind that I use Trello for my hobby projects; it's awesome in its simplicity. I can make new little card, and move them from column to column, and track what's going on.
So why is the expensive, heavy, full-featured Visual Studio so far behind the curve? Why doesn't it have a nice graphical interface? Where is the help for simple planning?
Answer: those are on the web, not in the full client. In order to use them, I have to leave my nice productive environment, and go to a totally different web page. And sign in. with some credentials. Which have to match the credentials I signed into Visual Studio with. But there isn't a "go to the web" button.
Never force your customers to leave your product! As soon as I have to type in a web address to go somewhere else, and sign in again, why wouldn't I just use Trello and skip the Microsoft solution entirely?
Monday, December 29, 2008
Issues with LIB files (a riff on Raymond Chen)
- On failure, the linker should try a fuzzy match ("I didn't find 'xyz' but I did see 'xyxz@4')
- The linker should keep track of how all of the files are being compiled ('the library was linked with /FOO but you are compiling with /NOTFOO)
- A library should be "stuffable" with all of the different versions of a file -- I should be able to pop in the unicode and ansi, debug and release, statically linked and dynamically linked versions of all of my files.
Sunday, March 2, 2008
Shell Blog -- interesting blog ruined
It's very interesting, it might solve some of my integration questions, and it's another couple hours out of my life that I would like back. What the entire (deleted) article didn't seem fit to mention is that when they say Microsoft Windows provides a default implementation of IShellView that what they really mean is most existing copies of Microsoft Windows do not provided any of these facilities
Because their code is (deleted) Vista only. Now, I don't object to Vista only code. But the Windows Explorer has only been around since what? Windows 95? Any code that talks about Shell Integration had better have a pretty good reason for not supporting their existing code base. And any code that does talk about integrating should mention any huge honking holes in the usability.
Microsoft: I want those hours back!
(Link to the Shell Revealed blog post: http://shellrevealed.com/blogs/shellblog/archive/2007/09/05/Shell-Namespace-Extension_3A00_-Adding-Custom-Command-Module-Items.aspx)



