LinusU / node-appdmg

πŸ’Ύ Generate your app dmgs
MIT License
1.68k stars 152 forks source link

background image isn't displayed in macOS sierra #121

Closed hiroshi closed 7 years ago

hiroshi commented 8 years ago

No problem till OS X 10.11.5. I know sierra is beta, but I want to share an possible compatibility issue.

In the view options of mounted dmg, there is gray rect thumbnail area. https://gyazo.com/16e7bf5091b8aacfcfa3742d8851c8d5

hiroshi commented 8 years ago

FYI: Other major applications dmg such like Chrome or Firefox display background image as usual even on sierra beta.

purifier1990 commented 8 years ago

Can we know the root cause why this tool doesn't work on Sierra? I just used it yesterday, I thought it works well, but after I submitted, I found Sierra can't work, my project is under Perforce's watch, the only way is to fix .DS_Store file.

purifier1990 commented 8 years ago

And hi hiroshi, I think your work around way can't work since when you drag a picture into that place, the DS_Store will give it an absolute path, when you put your image in other Mac, it will still be empty. So I think we should figure it out why it can't work on Sierra.

hiroshi commented 8 years ago

FYI: I checked with macOS Sierra 10.12 GM (16A319), but no luck.

jprichardson commented 8 years ago

Does anyone have any thoughts or ideas what's going on with macOS Sierra? We experienced the same issue.

LinusU commented 8 years ago

I know that @cstruct came pretty far with a real .DS_Store implementation which would probably fix this. Hopefully we can get together sometime next week and just solve itβ„’

Iomegan commented 7 years ago

No luck with GM release of Sierra.

feross commented 7 years ago

Just installed Sierra 10.12.0 from the App Store, doesn't work.

jprichardson commented 7 years ago

It's my understanding that http://c-command.com/dropdmg/ creates them properly. If you feel it's worth it, someone could get down and dirty into the output and see what they're doing.

It's too bad Apple doesn't publish the specs to the https://en.wikipedia.org/wiki/Apple_Disk_Image format.

rajateltropy commented 7 years ago

Any updates on this?

arantes555 commented 7 years ago

Same issue here with final Sierra :/

develar commented 7 years ago

dmgbuild is broken as well.

ezekg commented 7 years ago

I'm not super experienced in debugging things like this, but I attempted to dig into this yesterday and compared output with Firefox and Chrome's .DS_Store files. When inspecting the generated .DS_Store's icvp record with this Python library, it looks like the beginning of the backgroundImageAlias blob contains whitespace and a random newline:

{'arrangeBy': 'none',
 'backgroundColorBlue': 1.0,
 'backgroundColorGreen': 1.0,
 'backgroundColorRed': 1.0,
 'backgroundImageAlias': '\x00\x00\x00\x00\x01 \x00\x02\x00\x00\nTest Title\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\x18"\x8bH+\x00\x05\x00\x00\x00\x12\x0cTestBkg.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\xd4\x18"\x8b\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x01\x00\x04\x00\x00\x00\x12\x00\x0e\x00\x1a\x00\x0c\x00T\x00e\x00s\x00t\x00B\x00k\x00g\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x16\x00\n\x00T\x00e\x00s\x00t\x00 \x00T\x00i\x00t\x00l\x00e\x00\x12\x00\x19/.background/TestBkg.tiff\x00\x00\x13\x00\x13/Volumes/Test Title\x00\xff\xff\x00\x00',
 'backgroundType': 2,
 'gridOffsetX': 0.0,
 'gridOffsetY': 0.0,
 'gridSpacing': 100.0,
 'iconSize': 80.0,
 'labelOnBottom': True,
 'showIconPreview': True,
 'showItemInfo': False,
 'textSize': 12.0,
 'viewOptionsVersion': 1}

I couldn't find any other .DS_Store file that had whitespace/newlines before the volume name like what is generated here. Maybe that's an issue? The newline looks like it's coming from here, but I'm not 100% sure on that. I just know when printing that buffer with b.toString(), it also prints whitespace and a newline before the volume name. (Those could simply be garbage bytes getting converted into newlines when printing, I'm not sure.)

For comparison, here's the output when inspecting Firefox's .DS_Store,

{'arrangeBy': 'none',
 'backgroundColorBlue': 1.0,
 'backgroundColorGreen': 1.0,
 'backgroundColorRed': 1.0,
 'backgroundImageAlias': '\x00\x00\x00\x00\x02\xd2\x00\x02\x00\x00\x07Firefox\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xe4\xa9\xa9H+\x00\x05\x00\x00\x00\x14\x0ebackground.png\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xcd\xe4\x0f.PNGf8BIM\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xcd\xe4\xe1\xe9\x00\x00\x00\x11\x00\x08\x00\x00\xcd\xe4Gn\x00\x00\x00\x01\x00\x04\x00\x00\x00\x14\x00\x02\x00#Firefox:.background:\x00background.png\x00\x00\x0e\x00\x1e\x00\x0e\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00p\x00n\x00g\x00\x0f\x00\x10\x00\x07\x00F\x00i\x00r\x00e\x00f\x00o\x00x\x00\x12\x00\x1b/.background/background.png\x00\x00\x13\x00\x10/Volumes/Firefox\x00\x14\x01r\x00\x00\x00\x00\x01r\x00\x02\x00\x00\tAmericano\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\xda61H+\x00\x00\x00\x05\x03\x89\x0eFirefox-RW.dmg\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~TF\xcd\xe4\xaa&\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07Desktop\x00\x00\x10\x00\x08\x00\x00\xcc\xda|\x81\x00\x00\x00\x11\x00\x08\x00\x00\xcd\xe4\xe2f\x00\x00\x00\x01\x00\x0c\x00\x05\x03\x89\x00\x05\x03\x1b\x00\x02\x10q\x00\x02\x001Americano:Users:\x00stephen:\x00Desktop:\x00Firefox-RW.dmg\x00\x00\x0e\x00\x1e\x00\x0e\x00F\x00i\x00r\x00e\x00f\x00o\x00x\x00-\x00R\x00W\x00.\x00d\x00m\x00g\x00\x0f\x00\x14\x00\t\x00A\x00m\x00e\x00r\x00i\x00c\x00a\x00n\x00o\x00\x12\x00$Users/stephen/Desktop/Firefox-RW.dmg\x00\x13\x00\x01/\x00\x00\x15\x00\x02\x00\x0e\xff\xff\x00\x00\xff\xff\x00\x00',
 'backgroundType': 2,
 'gridOffsetX': 0.0,
 'gridOffsetY': 0.0,
 'gridSpacing': 100.0,
 'iconSize': 128.0,
 'labelOnBottom': True,
 'showIconPreview': False,
 'showItemInfo': False,
 'textSize': 12.0,
 'viewOptionsVersion': 1}

Also, should the background image be stored in the icvp record? It seems like it should be stored in the BKGD or pict record, according to this reverse-engineered specification. I see that the BKGD record is somewhat handled here, but I can't tell if it's actually used or not. Firefox's .DS_Store contains both BKGD and pict records.

Firefox's BKGD record,

('blob', bytearray(b'PctB\x00\x00\x03d\x00\x00\x00\x00'))

Firefox's pict record,

('blob', bytearray(b'\x00\x00\x00\x00\x03d\x00\x02\x00\x00\x08Firefox-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xe4\xa9\xa9H+\x00\x05\x00\x00\x00\x14\x14backgroundImage.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\xcd\xe4\xa9\xa7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xcd\xe4\xe1\xe9\x00\x00\x00\x11\x00\x08\x00\x00\xcd\xe4\xe1\xe7\x00\x00\x00\x01\x00\x04\x00\x00\x00\x14\x00\x02\x00*Firefox-:.background:\x00backgroundImage.tiff\x00\x0e\x00*\x00\x14\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00I\x00m\x00a\x00g\x00e\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x12\x00\x08\x00F\x00i\x00r\x00e\x00f\x00o\x00x\x00-\x00\x12\x00!/.background/backgroundImage.tiff\x00\x00\x13\x00\x11/Volumes/Firefox-\x00\x00\x14\x01\xe8\x00\x00\x00\x00\x01\xe8\x00\x02\x00\x00\tAmericano\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\xda61H+\x00\x00\x00|\xac\xbb\x1aDMGCanvasTemp_Firefox-.dmg\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~S\xf6\xcd\xe4\xa9\xa7devrddsk\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01T\x00\x00\x10\x00\x08\x00\x00\xcc\xda|\x81\x00\x00\x00\x11\x00\x08\x00\x00\xcd\xe4\xe1\xe7\x00\x00\x00\x01\x00\x18\x00|\xac\xbb\x00\x05\x03\xbf\x00\x05\x03\xbe\x00\x00(\xf1\x00\x00\x00r\x00\x00\x00n\x00\x02\x00bAmericano:private:\x00var:\x00folders:\x00bv:\x00qnn6wbj96tsf5d37hyy32y6r0000gn:\x00T:\x00DMGCanvasTemp_Firefox-.dmg\x00\x0e\x006\x00\x1a\x00D\x00M\x00G\x00C\x00a\x00n\x00v\x00a\x00s\x00T\x00e\x00m\x00p\x00_\x00F\x00i\x00r\x00e\x00f\x00o\x00x\x00-\x00.\x00d\x00m\x00g\x00\x0f\x00\x14\x00\t\x00A\x00m\x00e\x00r\x00i\x00c\x00a\x00n\x00o\x00\x12\x00Rprivate/var/folders/bv/qnn6wbj96tsf5d37hyy32y6r0000gn/T/DMGCanvasTemp_Firefox-.dmg\x00\x13\x00\x01/\x00\xff\xff\x00\x00\xff\xff\x00\x00'))

Anyways, that's all I got. I'm going to keep digging in when I have more time.

bprodoehl commented 7 years ago

I was seeing that as well. When I went in with Finder and manually set the background image, the resulting .DS_Store file was a lot smaller, but I couldn't make sense of the garbage at the beginning of the blob. I'll look to see if Finder sets icvp, BKGD or pict in the fixed .DS_Store.

develar commented 7 years ago

I found working solution and it will be fixed in the electron-builder soon. Experimental code: https://gist.github.com/develar/95d7b9ee5e9d8b44a460ebf16a652a1a Magic in the PERL code:

#!/usr/bin/perl -w

use Mac::Finder::DSStore qw( writeDSDBEntries makeEntries );
use Mac::Memory qw( );
use Mac::Files qw( NewAliasMinimal );

$name = $ARGV[0];
$bg_pic = $ARGV[1];

&writeDSDBEntries("/Volumes/$name/.DS_Store",
    &makeEntries(".background", Iloc_xy => [ 560, 170 ]),
    &makeEntries(".DS_Store", Iloc_xy => [ 610, 170 ]),
    &makeEntries(".fseventsd", Iloc_xy => [ 660, 170 ]),
    &makeEntries(".Trashes", Iloc_xy => [ 710, 170 ]),
    &makeEntries(" ", Iloc_xy => [ 335, 120 ]),
    &makeEntries(".",
        BKGD_alias => NewAliasMinimal("/Volumes/$name/.background/$bg_pic"),
        ICVO => 1,
        fwi0_flds => [ 100, 400, 396, 855, "icnv", 0, 0 ],
        fwsw => 170,
        fwvh => 296,
        icvo => pack('A4 n A4 A4 n*', "icv4", 100, "none", "botm", 0, 0, 0, 0, 0, 1, 0, 100, 1),
        icvt => 12
    ),
    &makeEntries("$name.app", Iloc_xy => [ 110, 120 ])
);
feross commented 7 years ago

Nice work everyone πŸ‘

@develar Isn't node-appdmg the correct place to fix this, not electron-builder?

develar commented 7 years ago

@feross I will test solution as part of electron-builder (appdmg have 2 native extensions β€” it causes issues for electron-builder users) and then open PR here. It is only one simple function β€” generic tool is not required for me. In any case I will contribute to this project if perl requirement will be approved (well, perl is bundled).

develar commented 7 years ago

Because I am not fan to investigate proprietary closed format, my solution is completely different to appdmg. Instead of just fix some bytes in the ds-store :( I reuse ideas from https://github.com/kenorb/binfiles/blob/master/make_dmg.pl and original make dmg from http://search.cpan.org/dist/Mac-Finder-DSStore/

Perl module is bundled β€” CPAN is not required.

Fixed version of electron-builder will be published soon.

@LinusU If my solution (in short: use perl instead of ds-store module) is ok, I can create pull request.

rkarroll commented 7 years ago

Any ideas on when we'll get this fixed in appdmg?

changkun commented 7 years ago

@rkarroll There has already been a solution comes out, please check @develar 's comments.

LinusU commented 7 years ago

@develar Would love to see a pull request, even if it uses perl πŸ’Œ

rkarroll commented 7 years ago

@changkun It's a bit over my head at the moment but I probably just need to read through it.

Cha-cho commented 7 years ago

I don't see how a perl script with confusing instructions can be considered a solution to a problem in a javascript based utility. Can someone explain it?

LinusU commented 7 years ago

with confusing instructions

What instructions?

node-appdmg would simply shell out to perl, the enduser wouldn't know that it's being used at all...

Cha-cho commented 7 years ago

node-appdmg would simply shell out to perl, the enduser wouldn't know that it's being used at all...

I apologize. I understand how it will work after the pull request. However there's a comment above that suggests there is a solution available right now. If there is a simple solution or workaround right now - before the pull request - I do not see it. Sorry for the confusion.

Sega-Zero commented 7 years ago

@LinusU @develar any news on this?

develar commented 7 years ago

@Sega-Zero I am busy currently, but I am planning to file PR.

myleshorton commented 7 years ago

Yeah I got caught in perl module conundrums trying to build @develar -- wanted a 32 bit perl (my perl skills are dated and lacking to begin with!)? If you're able to even build quick executable from that perl code, that would get me over the hump.

develar commented 7 years ago

@myleshorton See magic https://github.com/electron-userland/electron-builder/blob/master/src/targets/dmg.ts#L105 VERSIONER_PERL_PREFER_32_BIT: "true",

alex-zhang commented 7 years ago

Any updates?

zucher commented 7 years ago

Did you progress on this issue ? tks

alanosman commented 7 years ago

I'm having this issue also. Would like to know when it is fixed because we also hit this one today. I'm going to try the python workaround mention above.

alanosman commented 7 years ago

I was trying to understand develars fix, but don't really understand how to apply it. Could someone describe it a bit more clearly. i.e. is that a script to fix DS_Store? Are there any other solutions available?

al45tair commented 7 years ago

FWIW, I've fixed the problem in my dmgbuild project. You need to write a "bookmark" to the pBBk entry in the .DS_Store file. I'm not sure why Sierra doesn't like alias records any more (perhaps it only supports version 3 alias records; I think my code only works for version 2).

alanosman commented 7 years ago

Alastair,

Is that something you could make a PR for on this repo or provide instructions on how to fix manually? I really need a working version of appdmg. If that is the only change, I could run that for now until LinusU gets to integrate it completely.

thx!

LinusU commented 7 years ago

Any pr at this moment, even if the code is a bit ugly, would be highly appreciated :)

EvanBalster commented 7 years ago

+1 for whatever gets the job done!

annejan commented 7 years ago

Apparently Apple reverted something since the current version works fine on macOS Version 10.12.2 Beta (16C53a) Where it didn't work on the late Sierra beta's or stable . .

al45tair commented 7 years ago

@annejan I suspect they broke the code for version 2 aliases, and probably didn't notice until some of us started filing bug reports. Bookmark support is the right way to go anyway β€” it's the long-term replacement for aliases and is more flexible.

ghost commented 7 years ago

If anyone is interested, I made an ugly quick fix:

1) Added extra step in "appdmg.js"

  pipeline.addStep('Fixing background', function(next) {
    exec('fixbkg.sh',
      function (error, stdout, stderr) {
        next(error)
      }
    );
  });

2) Added script "fixbkg.sh" in run folder:

backgroundPictureName="background.tiff" #or how it's named in your options file
title="<App image title>"
applicationName="<App bundle name>"

echo '
   tell application "Finder"
     tell disk "'${title}'"
           open
           set toolbar visible of container window to false
           set statusbar visible of container window to false
           set the bounds of container window to {0, 0, 640, 480}
           set theViewOptions to the icon view options of container window
           set arrangement of theViewOptions to not arranged
           set icon size of theViewOptions to 72
           set background picture of theViewOptions to file ".background:'${backgroundPictureName}'"
           set position of item "'${applicationName}'" of container window to {192, 334}
           set position of item "Applications" of container window to {448, 334}
           update without registering applications
           delay 5
           close
     end tell
   end tell
' | osascript

I know that it's bad and full of duplications (yeah, you gotta duplicate a lot of info to fixbkg.sh) + it's opening finder in the middle of it's work, but it saved me, when I needed backgrounded dmg right NOW, so for me, its enough to wait for official fix. I also think it can be improved to reduce duplication, but I'd rather wait for entirely good solution. If anyone want to - you can make it better :) Hope that helps.

alanosman commented 7 years ago

@v-vodyanov can you tell me which folders I need to place these files? I tried the obvious one: node_modules/appdmg/lib.. didn't really know which run folder to place fixbkg.sh intro though. I'm assuming this all gets called when I run appdmg right?

ghost commented 7 years ago

@alanosman well, I've placed "fixbkg.sh" right in the folder I ran "appdmg" command. You can always write absolute path instead of just "fixbkg.sh" in the first place :)

As for "appdmg.js" itself, in my case (OS X) it's placed in "/usr/local/lib/node_modules/appdmg/lib/appdmg.js"

iRobertas commented 7 years ago

@v-vodyanov after which step your step should be added ? I tried in different order and looks like its not executed and build doesn't fails.

ghost commented 7 years ago

@iRobertas I've placed it after step "Making all the visuals" to make changes after appdmg additions and before temp image is unmounted.

iRobertas commented 7 years ago

@v-vodyanov ye I added this step to the same place. Does your step shows in build log when executed ? Like: [16/20] Making all the visuals... [ OK ] [17/20] Fixing background... [ OK ]

ghost commented 7 years ago

@iRobertas yep, it is:

[ 1/21] Looking for target...                [ OK ]
[ 2/21] Reading JSON Specification...        [ OK ]
[ 3/21] Parsing JSON Specification...        [ OK ]
[ 4/21] Validating JSON Specification...     [ OK ]
[ 5/21] Looking for files...                 [ OK ]
[ 6/21] Calculating size of image...         [ OK ]
[ 7/21] Creating temporary image...          [ OK ]
[ 8/21] Mounting temporary image...          [ OK ]
[ 9/21] Making hidden background folder...   [ OK ]
[10/21] Copying background...                [ OK ]
[11/21] Reading background dimensions...     [ OK ]
[12/21] Copying icon...                      [ OK ]
[13/21] Setting icon...                      [ OK ]
[14/21] Creating links...                    [ OK ]
[15/21] Copying files...                     [ OK ]
[16/21] Making all the visuals...            [ OK ]
[17/21] Fixing background...                 [ OK ]
[18/21] Blessing image...                    [ OK ]
[19/21] Unmounting temporary image...        [ OK ]
[20/21] Finalizing image...                  [ OK ]
[21/21] Removing temporary image...          [ OK ]

By the way, on the "Fixing background" step it opens temp image in finder, I guess it's ok, but can be a little confusing, that's why I don't think of it as a permanent fix.

hiroshi commented 7 years ago

It seems that this issue resolved by 10.12.2 (16C67).

gielcobben commented 7 years ago

I've still have the same bug on 10.12.2 (16C67).

feross commented 7 years ago

Works for me! Great work everyone πŸ‘

gmale commented 7 years ago

The fix from @v-vodyanov worked for me. Thanks! But at first I got the error: ReferenceError: exec is not defined

which I simply fixed by running npm -g install exec and then adding var exec = require('exec') to the top of the appdmg.js script.