Install Windows in BootCamp from a USB Drive on an “Unsupported” Mac

Turns out Apple knows what’s best for you, and won’t let you use a USB thumb drive if your Mac has an optical drive. Unnecessary restriction at its finest.

A co-worker has an Early-2011 MacBook Pro that he used primarily as a Windows machine. (I know, I know… Don’t ask me…) His hard drive died and he needed to reinstall OS X and Windows. But… He only had a Windows 7 ISO disc image, and didn’t have a blank DVD, but had a couple USB thumb drives that we should be able to use to create a bootable install volume – after all, how do Macs with no optical drive install Windows (which, as of this writing, is all but one of them – the lowly non-Retina 13″ MacBook Pro)?

Luckily I was able to piece together some hacks from various sources across the Internet, and I decided to document them here, for anyone else that finds themselves in this same situation…

I’ve successfully done this with Windows 7 on OS X 10.9 Mavericks, but it should also work with 10.8 (minus the need to re-sign the Boot Camp Assistant app), 10.10, and 10.11, and the flavors of Windows that those versions of OS X support.

Here are the steps I followed – DO AT YOUR OWN RISK. Don’t come crying to me if you destroy all the data on your OS X partition ’cause you clicked the wrong thing somewhere… PAY ATTENTION.

Let’s go:

  1. Procure Windows install ISO file
  2. Acquire USB thumb drive (8 GB or larger)
  3. Download TextWrangler (optional, but makes editing the .plist file easier)
  4. Note your Mac’s Model Identifier as indicated in the Hardware Overview in OS X’s System Information app. (Choose About This Mac in the Apple Menu, then click More Info… then click System Report…)
    Screen Shot 2015-10-19 at 4.10.54 PM
  5. Navigate to the Boot Camp Assistant app’s “Contents” folder (put the path name in quotes since it contains spaces):
    cd "/Applications/Utilities/Boot Camp Assistant.app/Contents"
  6. Edit the Info.plist file in that folder using your editor of choice. If you have TextWrangler installed, you can run the following command to open in the TextWrangler GUI:
    sudo edit Info.plist

    You can also use the bare-bones text editor Nano that is part of OS X’s core software

    sudo nano Info.plist
  7. Add the string for the Model Identifier base (before the comma) as noted in step 4 to the top of the PreESDRequiredModels and PreUEFIModels arrays. If your Mac is an iMac12,2, then should look like this (in OS X 10.9):
    <key>PreESDRequiredModels</key>
    <array>
        <string>iMac12</string>
        <string>MacBook7</string>
        <string>etc...</string>
    </array>
    <key>PreUEFIModels</key>
    <array>
        <string>iMac12</string>
        <string>MacBook7</string>
        <string>etc...</string>
    </array>
  8. Remove or comment-out the line where your model is listed under the PreUSBBootSupportedModels array. I just commented mine, and it worked fine – it looked like this:
    <!-- <string>iMac12,2</string> -->
  9. Save the file.
  10. If you’re running 10.9 or later, you’ll need to re-sign the Boot Camp Assistant app by running this command from the terminal:
    sudo codesign -fs - /Applications/Utilities/Boot\ Camp\ Assistant.app
  11. Launch your newly patched Boot Camp Assistant app and choose the newly available option to “Create a Windows 7 or later version install disk” o create your boot drive.
    Screen Shot 2015-10-19 at 4.07.59 PM
  12. After that finishes (it could take a while – you’re copying many many GB of files and adding Apple-specific bits so it can boot your Mac), go back to Boot Camp Assistant and download the Boot Camp software (unless you’ve already done this), then “Install Windows 7 or later version” onto your Mac.
    Screen Shot 2015-10-19 at 4.08.05 PM
  13. Do the Windows installation cha-cha. Go out to dinner, go see a movie, then come back and HOPEFULLY your Windows installation will be finished by then.

I think that’s it. There are some other steps to actually doing the Windows install through Boot Camp, and Apple has that documentation, so go look it up. But this should get you a bootable thumb drive for your computer that you can use instead of an optical disc.

Cheers!

Advertisements

jQuery Object or Bust

We use jQuery in our web app. I’m starting to use more native JavaScript now that browsers are getting better at creating a consistent API for the native DOM and JavaScript features. But there’s still a lot of usefulness in jQuery, and sometimes when a function requires an input be a jQuery (DOM) object, we’ll need to check it and wrap it pass it to jQuery if it’s not already a jQuery object. (Alright kids, let’s see how many times can we say jQuery in a single paragraph!)

I’ve already written about this a couple times, and it keeps coming up because I keep trying to make it more efficient. Of course, the native document.getElementById(‘id’) and document.querySelectorAll(‘sel’) are usually the fastest way to get a DOM element, but if you still need that as a jQuery object, you gotta call jQuery anyway, so… Let’s try to speed that up, even if just a little bit.

Here’s the latest iteration of this (handy?) function:

function $$(el){
    var $el = el,
        id_prefix = /##|#:|id:/;
    // we only need to run this if el is not already a jQuery object
    if (!$el.jquery) {
        // special case for (faster?) handling of id
        // using a "special" id-only selector:
        //  "##", "#:", or "id:"
        // (this will tolerate crazy non-standard ids)
        // document.getElementyById("foo.bar/baz") ==
        // $$("##foo.bar/baz") == $$("#:foo.bar/baz") == $$("id:foo.bar/baz")
        if (el.search(id_prefix) === 0) {
            el = el.replace(id_prefix, "");
            $el = $(document.getElementById(el));
        }
        // NOW try the standard jQuery selector
        else {
            $el = $(el);
        }
    }
    return $el;
}

// here's how we use it:
// attaching cached object on $$ for fun
$$.emailInput = $$("input[type='email']");
// now we can use jQuery's methods on it
$$.emailInput.on("focus", function(){
    this.value = "";
});

That’s it. This should be faster if we pass a selector that is an id (with special syntax), and will tolerate silly non-standard id values that could contain other strings that would mean something else in the context of a CSS-type selector (like dots for class, colons for pseudo-selectors, etc.).

Object [Deep] Merge/Extend in POJS (Plain Ol’ JavaScript)

I know there are a lot of JavaScript libraries that include a method to merge/extend (we’ll call it merge from here on) plain objects, but what if: 1) you’re not using one of those (unlikely these days), or 2) you need to do some object merge magic before one of those handy libraries loads (very possible, and the reason why I wrote this function, which has probably been written thousands of times in the history of JavaScript, but oh well)?

Here’s a native JavaScript function to do just that…
https://gist.github.com/Error601/9a181a0b9f414b752c38

In this example, I’m declaring a named function while also adding it as a method to an “APP” namespace object (you know, for the web app we’re writing).

// make sure we've got our APP namespace object
var APP = APP || {};

(function( undefined ){

    function isObject( obj ){
        return Object.prototype.toString.call(obj) === "[object Object]";
    }

    if (!isObject(APP)) {
        APP = {}
    }

    APP.mergeObjects = function mergeObjects( /* [true ,] objects */ ){

        var args = arguments,
            arg1 = args[0],
            arg2 = args[1] || {},
            len  = args.length,
            deep = false,
            i, arg, output = {};


        // first argument will be output object
        if ( isObject(arg1) ){
            output = arg1;
        }
        // unless set to true
        else if ( arg1.toString() === "true" ){
            deep = true;
            output = arg2;
        }

        // stop here and return the output object
        // if argument length is 0 or 1, or
        // if we're trying to deep merge a single object
        if ( len <= 1 || (len === 2 && deep === true) ){
            return output;
        }

        function processObject( obj ){
            var prop;
            for ( prop in obj ){
                if ( obj.hasOwnProperty(prop) ){
                    if ( deep && isObject(obj[prop]) ){
                        output[prop] = mergeObjects( true, output[prop], obj[prop] );
                    }
                    else {
                        output[prop] = obj[prop];
                    }
                }
            }
        }

        // loop over additional arguments
        for ( i = 1; i < len; i++ ){
            arg = args[i];
            if ( isObject(arg) ) {
                processObject(arg);
            }
        }

        return output;

    };

})();

Giant function or crazy simple RegExp?

Working with some old code I ran across a 37-line JavaScript function that seems to just strip non-alphanumeric characters from a text <input>. It took a string as its argument and returned a sanitized string with underscores in place of the bogus characters. There was also a function to throw up a custom modal dialog telling the user their input was being ‘corrected’ before submission (but not giving them a chance to stop and change it if they’d like).

The string replace method was called 30 separate times, like:

value = value.replace(/[&]/,"_"); // x30 to catch 30 different illegal characters

…30 separate times:

value = value.replace(/[&]/, "_");
value = value.replace(/[%]/, "_");  
//etc.

That’ll get the job done, in a very verbose and tedious way… But… How about just chaining the .replace() method, like:

value = value.replace(/[&]/,"_").replace(/[%]/,"_");  //etc.

But even that’s a bit silly. I thought, “Why not just put all the characters into a SINGLE regex and do a global search for those characters and replace them all at once.” That makes sense, right?

value = value.replace(/[\`~!@#$%^&*()\-_=+\[\]{};:'"<>?,.\/\\|\s]/g, "_");

That smashes it down to a single line (down from 30). But… What if we don’t have all the characters we want to block accounted for there? Someone could try to sneak in a © or ¢. There’s got to be a way to only ALLOW the proper (alpha, number, and underscore) characters. Of course there is!

value = value.replace(/\W/g, "_");

Is that really all I needed? Alright then. 30 lines down to ONE super-simple RegExp replace and we’re good to go.

Quite silly.

Here are some resources that helped set all of this silliness straight:

Kind of:
http://stackoverflow.com/questions/3780696/javascript-string-replace-with-regex-to-strip-off-illegal-characters

Closer:
http://stackoverflow.com/questions/388996/regex-for-javascript-to-allow-only-alphanumeric

The last bit of info that did the trick (the “Character Classes” section):
http://www.javascriptkit.com/javatutors/re2.shtml yes, really, an ancient JavaScript Kit link

Trigger ‘onchange’ event when value changes. (jQuery)

You’d think that when you changed a value in a form input, the browser would fire the “onchange” event for that element. This is partially true. It will do so if a user changes the value, but not if it’s changed programmatically via JavaScript. So I needed some JavaScript (irony?), and here’s what I found:

http://stackoverflow.com/questions/3179385/val-doesnt-trigger-change-in-jquery

And here’s what I used (with a new function name, while leaving .val() alone):

$.fn.valChange = function(){
    var prev;
    if ( arguments.length > 0 ){
        prev = $.fn.val.apply(this, []);
    }
    var result = $.fn.val.apply(this, arguments);
    if ( arguments.length > 0 && prev != $.fn.val.apply(this, []) ){
        $(this).trigger("change");
    }
    return result;
};

And here’s how to implement it:

HTML:

<input type="text" id="test" value="Test">
<button id="btn1">Button 1</button>
<button id="btn2">Button 2</button>

JavaScript:

// send a log message to the console when it changes
$("#test").change(function(){
    console.log("The value has changed");
});
$("#btn1, #btn2").click(function(){
    // set the value when clicking the buttons
    // and if it's different than it was,
    // trigger the "onchange" event for the input
    $("#test").valChange($(this).text());
});

And here’s the obligatory JSFiddle to go with it:
http://jsfiddle.net/fbdskfz9/

Get The Current Script’s Path (non-jQuery)

So, I use this snippet quite a lot, usually for loading a CSS file that’s in the same folder as the script file. I’ve used it with jQuery since it’s a very popular library (and we use it in the web app I work on), but this function can be performed without jQuery using the document.querySelectorAll(‘sel’) method.

function getScriptDir() {
    var scripts, src, path;
    scripts = document.querySelectorAll("script[src]");
    src = scripts[scripts.length-1].src;
    if (src.indexOf("/") !== -1) {
        path = src.split("/");
        path.splice(path.length - 1, 1);
        return path.join("/") + "/";
    }
    else {
        return "";
    }
}

This works because the script where this function resides doesn’t know about any other files that come after it (just be sure to fire it right away – DO NOT wait for the entire DOM to load).

Here are previous versions of this function…

The jQuery version is in this post:
https://error601.wordpress.com/2014/08/21/some-code-snippet-updates/

The “original” (included here for reference, but not recommended since it can’t handle src attributes without a slash, which is dumb):
https://error601.wordpress.com/2014/02/12/get-the-current-scripts-path/

Example: Get date format by class name and submit data via AJAX (with jQuery)

For this example, we’re going to leverage a function in a namespace (APP.utils) named (APP.utils.getValueByClass()) that I wrote in my last post (Set a value based on the presence of a class name (with jQuery)). We’re going to get the value of an input (a date), determine the date format by class name, and submit the day, month, and year to our web server via AJAX and display the response (text “success”) when done.

The HTML:

<!-- the 'us' class name indicates the date format, the placeholder directs the user -->
<input type="text" id="start" name="start" class="date us" placeholder="09/02/2014">
<p id="success"></p>

The JavaScript:

// this function gets us the day, month, and year values
APP.utils.getDateValues = function( date, format ){
    var parts, sep, d, m, y;
    // allow use of either "/" or "-" for separators    
    sep = (date.indexOf("/") > -1) ? "/" : "-";
    parts = date.split(sep);
    format = format.toLowerCase();
    if ( format === "us" ){
        m = parts[0];
        d = parts[1];
        y = parts[2];
    }
    else if ( format === "eu" ){
        d = parts[0];
        m = parts[1];
        y = parts[2];
    }
    else { // format assumed to be ISO
        y = parts[0];
        m = parts[1];
        d = parts[2];
    }
    return { year: y, month: m, day: d }
}

Then, it’s pretty trivial to get the parts of a date when submitting a form:

$("#form-id").submit(function(e){
    e.preventDefault(); // we don't want to do an actual form submit
    var $input, format, date;
    $input = $("#start");
    // determine the format by class name (us, eu, or iso)    
    format = APP.utils.getValueByClass($input, ["us","eu","iso"]);
    // get the day, month, and year values as properties to the "date" object
    date   = APP.utils.getDateValues($input.val(), format);
    // output will be: date: { year: 2014, month: 08, day: 28 }
    
    // post the data and display the response data
    $.ajax({
        type: "POST",
        url: "/rest/form/endpoint",
        data: {
            month: date.month,
            day:   date.day,
            year:  date.year
        }
    }).done(function(data){
        // server returns text "success" after saving the data
        $("#success").html(data);
    });
    return false;
});

That’s it. You get the day, month, and year values of a single-field date input, of which the format was determined by class name (in this case, we’re using the ‘us’ format), submit the data via AJAX, and display the returned data on the page. All with jQuery, because it makes using AJAX on the front-end pretty easy, and our app is already using it.

(here’s a jsFiddle to play with it – enter a date, change the format, then update to view the values below)
http://jsfiddle.net/g99ffked/2/

Set a value based on the presence of a class name (with jQuery)

In working on the web app that I’m employed to work on, I needed to check for the presence of a class name out of a few different possibilities so I could set the value of a variable based on that. If I only had to do this once or twice, and if there were only two options, I’d simply do:

var value = $('#element').hasClass('opt1') ? 'opt1' : 'opt2';

Piece of cake, right? Well, I had to do this many times, and once or twice there were more than two options. So I made a little function that will iterate over an array of possible values and check for a class name with that value, then return it.

Here’s what I came up with (yes, it uses jQuery because the web app uses it, so why not):

//"APP.utils" is the namespace where this function will live.
var APP = APP || {};
APP.utils = APP.utils || {};

APP.utils.getValueByClass = function( $container, values ){
    var val='';
    $.each(values, function( i, v ){
        if ($container.hasClass(v)){
            val = v;
            return false; // exit if we have a match
        }
    });
    return val ;
};

Here’s how you’d use it:

The HTML:

<!-- the 'us' class name indicates the date format, the placeholder directs the user -->
<input type="text" id="start" name="start" class="date us" placeholder="08/28/2014">
<p id="success"></p>

The JavaScript:

var format = APP.utils.getValueByClass( $('#start'), ['us','iso','eu'] );

The arguments are:

  1. a jQuery DOM object (not a string for the id or selector, a full jQuery object)
  2. an array of class names to look for (the first one found will be the returned value)

Now you’ve got a value for the format var to possibly use to determine how to split up the parts of a date input for form submission, which I will show in a later post.

How to update Adobe Flash Player on OS X in only 48 easy steps!

Here’s Adobe’s INSANELY convoluted and confusing process for updating Flash on OS X:

1) You’re notified that there’s an update to Flash, so you click the button to update.

2) The “Adobe Flash Player Install Manager” application launches. (seriously, who the crap comes up with this stuff?)

Update_Adobe_Flash_Player3) Click the “Download” button in the “Update Adobe Flash Player” window of the “Adobe Flash Player Install Manager” app that’s running. (why is the window name not the same as the application name? there’s only one window. ugh.)

4) You’re taken BACK to the browser that you were just yanked out of by Adobe’s annoying installer.

Flash_Player_Download_page5) You’re asked to do the REAL download (that other “Download” button in step 3 was just a link to their web page where you can get the actually installer). You realize the button says “Install now”, so I guess this is all I need to do and then I’m done. WRONG!

6) Download the file.

7.1) If you’re browser is set to auto-launch .dmg files, you’ve got it easy (kind of). The installer should launch automatically for you.

7.2a) But if you disabled this feature (which is a huge security issue, IMO), then you have to hunt down the downloaded .dmg file (named “AdobeFlashPlayerInstaller_14au_ltrosxd_aaa_aih.dmg” in this case)

7.2b) Double-click that to mount on your desktop, then you still have to…

7.2c) Double-click the installer application that lives inside that .dmg

Adobe_Flash_Player_Installer_dmg8) You’ll probably be notified that the application was downloaded from the Internet, and need to confirm that you do, in fact, wish to open it.

Adobe_Flash_Player_app_warning9) Since Adobe Flash Player needs admin-level permissions for whatever reason, you’re prompted to enter your username and password (if you’re an admin-level user, otherwise, you’ll need to enter a username and password for a different user that has admin privileges, which you may not be able to do, in which case, no update for you!).

Adobe_Flash_Installer_Permissions10) The “Adobe Flash Player Installer” downloads some other mystery file from the internet (could be anything at this point, and since you’ve given Flash your admin info, it can launch whatever it wants – maybe a nice shell script that does a sudo rm -Rf / on you?

11) If you have any of the following open: System Preferences, Firefox, Safari, or Google Chrome, the installer will halt until you close them, and THEN you can proceed.

Adobe_Flash_Player_Installer_RETRY12) Make sure the 300 tabs you have open don’t have anything important going on in them (like, ironically enough, writing a blog post about how shitty Adobe’s Flash Player bullshit is).
13) After clicking “Retry”, wait another 30 seconds for the installer to figure out what’s going on.
14) Installation complete. IT’S A FUCKING MIRACLE!

Adobe_Flash_Player_Installer_FINISH15) But wait! There’s More! Adobe launches your browser AGAIN and takes you to a page that confirms and congratulates you on making it through the hell known as their “Adobe Flash Player Browser Plug-in Updater Installer Manager Application Program”

Flash_Player_confirm_page16) Oh, and they spam you on this page to try to get you to drop your precious $$$ on their shitty software. Alright, Lightroom is pretty good, but c’mon, I just wanted to watch some silly kitty videos.