Archive for the 'Entrepreneur' Category
My Apartment
Want to see some pictures of the apartment I live in? See below. Since I’m no longer at MS and am trying to work for myself, I’m a little low on cash flow. So, I’ve moved into a cheaper place and am rooming with a former colleague of mine. Actually, it was an easy transition since we’re both very low key. I do sorta miss the privacy, but it’s not bad at all, and can be fun at times. Anyway, I had a housing budget at Microsoft. Actually, it was super high, until I brought it down to the reasonable level and negotiated the difference into a cash bonus instead – haha! But anyway, my place was about 8000RMB before, which is almost $1200. That’s pretty high end for Shenzhen (which is already an “expensive” city for China). My place was really big too – 3 bedrooms. Much to much for me, but I picked it because it was the cleanest place I found in a neighborhood that I knew. The landlord turned out to be fantastic too. She even dropped the price way down (to 5500, I think) when I announced that I had to move out (just before coming to the US for the summer).
Anyway, there were a couple of ‘hoods that we thought about moving to. In the end, we ended up finding a place in “Hai An Cheng”, or “Coastal City” which is the name of a big mall near here. It’s a nice area; the mall attracts a lot of high end businesses and restaurants and there is still plenty of local flavor. There are way more local restaurants and stores that I can quickly get to now than before. The only downside is that it’s not close to a subway. But, I’ve found the key busses that can take me where I need to go. Some are quite fast. Who needs a car?
The rent is 3500RMB a month, about $500. Split in two, that’s $250 per month. Not too shabby.
I have a Filippino friend down the street whom I’m jealous of. He’s got the best place for the money I’ve ever seen. A very cozy apartment that matches roughly the same dimensions as mine. But, a sweet kitchen and a well-designed bathroom too. It’s only 3000RMB. If he moves out, I’m jumping on that place without waiting.
3 commentsGoreRange.info
I rehired a girl here in China to help me port over the trip reports from my old Gore Range site to the new one. I used the same effective technique: Create a special page that described the job and (here’s the key) created a screencast that showed how to do the job. A “screencast” is basically a video of your computer screen showing what you’re doing on the computer. I created the one for this job with Windows Media Encoder 9, which has problems (of course), but is at least free. I’ll be upgrading to Camtasia as soon as I get my new laptop (going to pick it up in Hong Kong early next week!) They’re running a $99 promotion now for their new version for the Mac.
The screencast is a powerful tool. My assistant was convinced that this job, using WordPress, etc. was too complex for her. I told her to just give it a try for a couple of them. Now, she’s cranking them out in a matter of minutes.
Total price for the website port: $15
My adventures in the Cascades are next. That’s a much bigger site. Maybe I’ll even create a site for my fourteener trip reports.
No commentsSoftware Release
My first project after leaving Microsoft was to re-release my WebSnatcher products. Except, this time, I wanted to give this old lineup a brand new handsome face. That included: bundling my two products together as a simple “web downloading suite”, update the new graphics with artwork from someone who knew what they were doing, a new name, and a new website. Of course, I included some small enhancements and a few key bug fixes, but there wasn’t really that much new in terms of functionality; it’s just a much better looking package that runs much better on vista and Windows 7 and, as a package, it’s much cheaper (by a third).
The development was a pain. The primary source of that was wanting to move the main product, the product formerly known as “WebSnatcher”, to Unicode. Well, that didn’t work at all (and I believe I covered exactly why in a previous post), so rolling that back was kind of a pain, especially not having source control.
Then, just before I went to the US, I ran out of time and didn’t have all the software that I needed to prepare the installation. My copy of InstallShield was in my storage unit and one of my first jobs was to pull that out and put together the installation while I was in the US. But, upon arriving in the US, I discovered unlucky mistake: Apparently the software that protects my product had corrupted one of my DLLs. After trying numerous workarounds, I realized I was stuck and had to wait until I got back to China in order to rebuild the DLL and protect it again (I had some vague memory that the protection software would corrupt files one in a hundred times or so…actually, I now have no idea if that’s true). So, I gave up on releasing my software and forsaked two months of revenue. But, when I started the project up again in China, I realized that it wasn’t the software at all, it was just some absurd new security feature in Vista. How many times has Vista prevented me from “realizing my potential”? Well, let’s not even bother counting. I immediately got a copy of Windows 7 and installed it on my laptop and reproduced the error. I fixed it by manually registering the stupid COM DLLs on install and not automatically through DllRegisterServer(). Easy fix…once I knew what the problem was.
Well, as big a disappointment as that was, it paled in comparison to setting up the fulfillment operations. I assumed that once the product was actually done, setup created, website running, and everything, that the big problems were behind me. Oh no. And what’s worse, these problems were even more stupid than the Vista problems. In fact, all throughout this release, every problem I ran into was not a problem solved by creativity or innovation, but some dumb barrier placed by some bad design choice or lousy support system.
It started off pretty well. I was set on fully automating order fulfillment. Before, when a user purchased a product, I’d get an email notification. Then, I’d log into my Windows machine, start up the software that protected my product, input their name, generate the key, then save the registration key as a text registry file. I’d then start up my email program, copy the usual mail text from a text file and paste it into the email, then add the registration key as an attachment and send the email. I got pretty good at this, where it would take two to three minutes to fulfill. It wasn’t that big of a deal since I didn’t get that many orders, but the one huge downside was that it was dependent on me. If I didn’t check email, someone wouldn’t get their key for a day or more (if I were a user, that would irritate me). If I went on vacation and couldn’t bring my laptop, they wouldn’t get their key for a week, or maybe more. But, at least I set up an autoresponder to let them know (no matter, that would irritate me too). So, I was committed to 100% automated fulfillment.
The software that I use to protect my application came with a ‘C’ API to implement your own key generating tool. That’s exactly what I needed and it fit the requirement of the regsoft.com, my fulfillment company of many years. They simply needed the registration key to be output to stdout (text in a console application, basically) and to know the arguments that you required to be passed to your application. Easy enough, and I was able to implement it in just a couple of hours (the one party in this whole affair that did do a good job was the protection software). I then, according to regsoft’s instructions, emailed regsoft and asked them to evaluate my application, I attached the application in a zip file (renamed to .ziz), I included a readme.txt file with the arguments I required and sample output. I did everything to the letter. They said they’d review it in two days and get back to me.
Two days came, nothing. So I wrote back. I got an email response saying something like, “Oh sorry, we got your email but the file wasn’t attached. Please send it again.” I sent it again this time from two different addresses. Two days later, I followup and get the same response. This time I send another email and add an FTP link with username and password (which I tested) where they could download the file. Two days later, maybe more, I follow up again. I get the same response, except this time they suggest that I add a link where they can download it. So, I write back nicely saying, “You guys don’t seem to have your act together. I’ve already provided all of this.” to which they replied with profuse apologies.
It was a little too late anyway because I had learned of another fulfillment company, a sister company in fact, called regnow.com. This looked more attractive anyway because they had an extensive affiliate network. So, I was committed to switching. I started the process to get my software selling on their site.
Of course, their system was way more complex than regsoft’s. I actually liked the regsoft system quite a bit; it was well designed, they just lacked the affiliate network and their customer service was lacking at times. Combine the two and you’d have a strong combination. Anyway, just getting through the first two pages took a whole afternoon. They had huge sections to prepare affiliate marketing kits and so on. I had to create graphics from the artwork that my designer created for me in all sorts of dimensions. No matter, I plowed thorugh it.
Then I got to the automated key generation section. I assumed that I’d be able to use my little Windows console app to generate my keys. No such luck. They had much stricter requirements: You had to submit source code, not an executable. And it had to be compiled by the GCC compiler (uh oh) and be able to run on a Solaris machine (or whatever). Well, I looked a bit into this, but I hate these open source compilers; just getting them to work is a monumental effort. I don’t understand why they enjoy making it so hard, well actually, I think I do, I should write a post on the psychology of programmers. Anyway, I realized this was going to be an effort so I first had to ask a key question: “My key generating application is dependent on a Windows DLL (the protection software DLL), there is no way around this. Do you support an app that can run on Windows?” I never really got an answer to that question, but I did submit my source code just to see what would happen. A tech representative wrote me back with a long list of errors and told me to fix them. Most all of them were from Windows identifiers that the GCC system didn’t understand. OK, that settled it for me; this was the wrong battle to engage in. Was there another solution?
Turns out, there was something that looked promising. I had recently purchased an upgrade to my protection software which included many updates in custom key generating options. One was a CGI library. I’d never done that before, but how cool would it be to generate keys over the web? Regnow supported this, that was good. So, I just needed to upload the library to my cgi-bin folder on my website and create a little web page to test it. I uploaded the library, wrote the page (even easier than writing the first application), and tested it. ERROR. So, I opened a ticket with my hosting company to find out if they supported this. I was suspicious of one little line in their CGI documentation: make sure your script ends in .pl or (one of the other popular CGI scripting languages). Mine was a compiled library. Maybe this was impossible to work. Regardless, my ticket was there. In the mean time, I posted the “do you supported compiled CGI libraries on your server?” question to another hosting company. They wrote back right away with “Yes”. Would I end up switching hosting companies too?
In the mean time, the other company took forever to answer. The first response they gave me was, “Can you set up a test page?” to which I replied, “Look at my original request; I’ve pasted in text you need to test it. Just save that text to a ‘test.htm’ file and open it.” I won’t go into the details of all the back and forth, but finally they confirmed that it was indeed true – they only supported scripts, not binary CGI solutions. Time to switch hosting companies.
I started trying to switch hosting companies. I figured out the plan I wanted and the duration (I wanted the max length so the monthly rate would be very low). But, my credit card was denied. Oh no, not now. I tried jumping over to some software that bypassed the China filters and disguised my IP address. Still failed. I called up the company and told them what was going on. They suggested that I either go to Hong Kong or call someone in the US to make the purchase for me. So, I called my mom and we walked through it at least two times, maybe three. DENIED! Remember, this is all balancing times between the US and China so much of these conversations took place late at night or early in the morning for me. I called the bank and told them that I was running into these problems. They suggested that I call the hosting company back and explain to them that I had contacted the bank and so on. She also gave me a phone number that they could call in order to verify that I was telling the truth. Back on the phone with the hosting company, the customer service agent was great; he seemed to understand the pain that I was going through. As he was communicating with some of the people looking into the credit card, he would quietly pop back on the phone with me and tell me, “They’re asking me if you sound like a real American” to which I could only reply in my best Apu voice, “Yes, thank you, hot dog, Britney Spears…” We finally got it all straightened out, but I had to email over a scanned copy of my passport and explain again the situation, the people I talked to, the bank phone number, etc. etc. I was relieved when I woke up the next morning and I saw an email message, “Welcome to Host Gator!” YES!!!
It took me only five minutes to upload the CGI key generating library and test it. It worked! Score another one for the protection software! Now, it was just a matter of getting it plugged in to the Regnow system. But, remember what I said about it being complex? Well, it was basically impossible for me to figure out without plowing through reams of web page help which was badly indexed and had no search (what?!?). So, I spent the next several days on email with support back and forth. I asked for a phone number twice; never got one. While these guys were helpful, they were constrained by this complex system, and their time zone. It was basically an email per day unless I was lucky enough to catch one of them early in the morning (my time) in which case I’d get two emails in one day. In between all that, technicians were changing parts of my submission, deleting sections, etc. etc. This prompted more emails like, “Hey, I just added this, what happened!?” It was a big mess, and they have a lot of improvement to make here.
I realize this post is already long so I’d better stop. If I went into all the additional little problems of getting this product out the door, I could go on for another few paragraphs. Let’s just say that it’s finally done and I’ve very happy with it. An order came in almost right away and it was so sweet to not have to do a thing. I’m looking forward to turning more of my attention to another project and spending a few hours a week working on marketing this software, something I never did the first time around (I think I could have done really well if I had any business sense back then).
I never would have thought that this little project would have been such a pain. As they say in Chinese: “Hao3 Shi4 Duo1 Mo2″, “????”, or “The road to success is paved with hardship”. Neat how you can say all that in just four words, huh?
Well, here t’is, finally!
4 commentsAmplifier Headaches
I am starting to work on some recording projects and need a working amplifier. I had MS ship over my studio guitar amplifier, a very nice one, from the US, but, silly me who didn’t even think about the power requirements, the amp has no internal transformer like a laptop and can only work with 110 volts. But, I had a brilliant idea: I can go to Hua Qiang Bei, the electronics capital of Shenzhen, and China, and I guess the world.
I got a tip from Davide to visit some stores in the area that sold mixing boards and microphones and ask there. I was successful at step one: locating these stores. The salespeople though weren’t selling what I was looking for, but they directed me to “Electronics World” across the street, which is yet another of these 4-5 story enclosures which comprise hundreds of independent shops. I asked one of the guards where they sold transformers (bian4 ya1 qi1). I couldn’t understand his response, but he gestured off in a certain direction, so I pretended to understand and thanked him. After walking down one corridor of mini stores and eyeing the wares, I began to notice a lot of power supplies and plugs. Perhaps this was the place.
And it was. The nice woman showed me two heavy transformers, about the size of a shoebox. After explaining what I was looking for and showing her a picture of the back of my amp, we settled on the 600 watt transformer. I walked back outside and to the bus-stop, quite pleased with myself. But, as I should have known, when I got home and plugged it in. It turned on briefly, made a horrible noise, and shut off. Dead. Reality set back in and I cursed at the idea of having to go back to Hua Qiang Bei.
I went the next day and the nice lady switched out the fuse. Oh, it was that simple? Just an old fuse or something? She gave me a couple of extras and we tested it. It seemed to work fine.
Back at home, I plugged it in and turned it on again. This time, it made a horrible loud buzzing, but didn’t shut off. Now, why didn’t I hear this loud buzzing when I was in the store. Oh wait, it was Hua Qiang Bei which is perpetually full of multitudes of screaming people. Makes sense. Well, back to reality again, I though, “How in the heck am I supposed to record with this awful buzzing in the background?” There was no reasonable answer, but I decided to at least try the amp. I plugged it in, turned on the power…BOOM! Fuse blown again.
OK, I give up. I could always have someone replace the transformer, I guess, but I do plan to go back to the US someday and don’t want to have to change it back again. Besides, there is zero guarantee that the electrician will do a good job. I could end up burning the whole apartment complex down. Forget it; I’ll just buy a new amp, a little cheapo studio one. That’ll be fine, I’ve got a nice effect rack. It’ll work. The next day, I learned about “Music Heaven” in Shenzhen and checked it out. Not bad! It’s another collection of stores, about 3 stories worth. The owner of the place that I tried out is a big fan of Paul Gilbert and had his picture playing guitar with him proudly displayed, so I thought that was fitting.
I’ve got an extremely heavy paperweight now, my shoebox-sized transformer, unless someone wants to take this thing off my hands. Return it to the store? Forget it. Welcome to Hua Qiang Bei.
No commentsWhere’s php.ini?
I had a heck of a time hunting down the location of php.ini on my Mac. I needed to set the PHP error reporting setting to ‘true’ for my local installation. Though I much prefer the file system organization of the Mac to Windows, I don’t know it nearly as well. After some digging, I finally found the file. On top of locating it, I had to set the permissions so that I could make the necessary change to the file. Here are the steps:
1) Find PHP5. It’s a pain in the axe. It’s located at /usr/local/php5/lib.
2) Access the parent folder in the finder by typing “/usr/local/php5″ in the dialog at “Go->Go to folder…” menu item.
3) Right click on “lib” and choose “Get Info”.
4) Under “Ownership and Permission”, click on the lock icon.
5) Change the permission so that you now have permission to write to the file. You’ll have to put in your admin password a cupla times.
6) Navigate to the “lib” menu now and find the “php.ini” file. Double click on it and choose “TextEdit” as the application of choice (make it the default app too).
7) Make the necessary changes and…done.
PHP and MySQL on the Mac
I now am needing to learn more about PHP, MySQL, WordPress, and so on. As you may know, this site you’re now reading runs on WordPress software, which, for the most part, I’ve been happy with. But, if I want to add my own customizations or just play around with different ideas to try out on WordPress, running a test site online is not so practical (especially with the pitiful speed of my internet here in China). So, I looked into running WordPress locally on my Mac. I had to hunt down four things to install and configure: Apache, PHP, MySQL, and WordPress. I spent four to five hours downloading, installing, and troubleshooting. In the end, it wasn’t so hard, but pulling all the info together from various websites was quite time consuming. So, I spent 20 minutes this morning culling the important information and distilled how I did it into a five-page document.
You can download the pdf file here.
It sure is nice having this set up locally. It’s incredibly fast (obviously) and as easy as editing and saving files in a basic text editor.
1 commentPersonal Code Review
In my “The First Three Weeks” post, I mentioned how one of my first projects is to re-release my shareware. I have two closely related shareware applications. Both are “Download Managers”, which make archiving websites, and downloading in mass easy. My applications are written in MFC and ATL, ancient technologies by today’s standards. This project has been occupying most of my working time; my other projects are mostly being outsourced right now. For example, logo work and graphic design is something that must be done but I personally have no talent to do it myself. Witness the lousy graphics that I created myself or borrowed from freeware in my last shareware release. So, even though collecting bids and reviewing work can be time-consuming, that option sure is better than pretending I can do it myself and wasting time and effort.
But, how easy it is to digress. So, back to the main point. This is the first time I’ve been back in my shareware code in nearly six years. Also, this code was written about nine years ago. My how the time does fly. It’s interesting to see how my coding style has transformed over the years. So what have I noticed? Well, why not give myself a code review for everyone interested to see? Here it goes:
Strengths:
- Organization – The code and projects are organized well. It’s easy to find things and there is very little duplicated code. The code is organized well for reuse.
- Loosely-Coupled Code – Code is easy to move around or remove entirely without too many side effects.
- Well-commented – The code is easy to read and commented well. There are some fairly obscure sections that would have taken me a long time to figure out, but the comments gave me a great starting point.
- Easy to localize – Dialog and string resources are managed well and it’s a piece of cake to localize the applications into multiple languages.
Weaknesses:
- Error Handling – The error handling is generally good, but sometimes very lax. There are a few egregious violations like a string buffer being passed to a function with no indication of length. The function assumes the buffer is at least 64 bytes. Yes, I have fixed that. Microsoft educated me well on defensive programming.
- Unicode support – In most places, you could tell that I was paying attention to Unicode, but I had to spend at least a full day updating the rest of the code to be cleanly build both Unicode and MBCS builds. However, I discovered one big problem: I realized my home-grown HTML parser simply did not work in Unicode. And, it’s not a simple matter of using TCHARs or something like that…
- HTML Parser – For the sake of speed, my parser assembles DWORD tags from HTML and matches them to predefined HTML DWORD tabs like “<ahr”, “<ima”, “<bas”, etc. When I started writing this app, the web was still quite young and HTML parsers weren’t so common. The MS DOM probably existed, but since it’s shipped with IE, I, like most normal people, probably assumed that IE could easily be uninstalled in favor of another browser. Regardless of how engrained IE is into Windows or Anti-Trust rulings, I didn’t want to rely too much on third party libraries.
I do have my full Unicode builds working now, but my parser doesn’t work. It’s quite the understatement to say that’s a big problem. The jury is still deliberating about what to do. The easy answer is to just stick with a multi-byte character set build, which still works great. I may do that for the first re-release and then upgrade the parser to use the DOM for the next release.
The parser really does need an upgrade because it’s also quite complex. There is a lot of code in this “pointer” style (and this is one of the easier sections):
TCHAR* pBM = buffer; while ( _T('#') != *pBM && *pBM ) pBM++; ...if ( _T('#') == *pBM ) { *pBM = NULL; token = ST_HTML_FILE; }So, with a lot of code like this, maintenance is a bit of a problem. Time for something more reliable and easier to manage. My IE plug-in application uses the DOM for parsing and it’s much simpler, however, that application does not need to update the links in the HTML to match the users hard drive.
- Feature happy – Well, this one isn’t so serious because my applications already aren’t very feature heavy, but I do have a few silly features and additions that don’t provide any value. I gained a new appreciate of this problem at Microsoft. It was something that I fought against constantly. Maybe I’ll write more on this later, but I was shocked at how much effort and time we put into useless features. But, hey we did, and I sometimes felt like an outsider for opposing them. Anyway, because of my appreciation for a feature done well vs. a mad mass of confusing features, I’ve cut my non-essential features and frills.
- Graphics – That’s why I’m outsourcing this next release.
In summary, I’m happy with the code. Though I’ve expanded more on the negatives here, I’d rather have this strength/weakness profile than have it flipped! That would be a much tougher problem to deal with. That would basically mean rewrite. That would tempt me to abandon.
No comments
