Something that might help future visitors:
As Govert said, the default behaviour is first to look in:
1. same directory as the .dna file, and
2. same directory as the ExcelDnaPack.exe file.
If you're trying to publish a 64 bit version of the add-in, you cannot let #2 happen, so you have to make a copy of ExcelAddin64.xll in the same directory as your MyAddin64.dna file.
As of the time of this post, to support both 32 bit and 64 bit excel, The NuGet package for ExcelDNA automatically adds following post-build steps:
(copy the *.dna config file to *64.dna so that it can be used by ExcelDnaPack to make a 64 bit version.)
xcopy "$(TargetDir)${projName}-AddIn.dna" "$(TargetDir)${projName}-AddIn64.dna*" /C /Y
(copy the ExcelDna.xll and 64 bit xlls so they can be used by ExcelDnaPack to make the packaged addins.)
xcopy "$(SolutionDir)packages\(etc)\ExcelDna.xll" "$(TargetDir)${projName}-AddIn.xll*`" /C /Y
xcopy "$(SolutionDir)packages\(etc)\ExcelDna64.xll" "$(TargetDir)${projName}-AddIn64.xll*`" /C /Y
(run DnaPack on both files to create the 32 and 64 bit addins)
"$(SolutionDir)packages\(etc)\ExcelDnaPack.exe" "$(TargetDir)${projName}-AddIn.dna"
"$(SolutionDir)packages\(etc)\ExcelDnaPack.exe" "$(TargetDir)${projName}-AddIn64.dna"
If you think anything like me, you didn't want your add-in named "whatever-packed.xll", you wanted it named "whatever.xll". So you take advantage of the "/O" flag that Govert kindly added to control the name of the output file:
Note: This is wrong, do not replicate:
"$(SolutionDir)packages\(etc)\ExcelDnaPack.exe" "$(TargetDir)${projName}-AddIn.dna" /O "$(TargetDir)${projName}-AddIn.xll" /Y
"$(SolutionDir)packages\(etc)\ExcelDnaPack.exe" "$(TargetDir)${projName}-AddIn64.dna" /O "$(TargetDir)${projName}-AddIn64.xll" /Y
Suddenly, your 64 bit add-in is still getting generated, but you start getting the classic error: "The file you are trying to open "MyAddin64.dll" is
in a different format than specified by the file extension. Verify the
file is not corrupted and from a trusted source before opening the file.
Do you want to open the file now?"
It's subtle, but what after much debugging and reading the ExcelDnaPack code, it turns out that this is all the fault of the way that "/Y" flag is implemented. Here's what happens:
1. You correctly copy the ExcelDna64.xll file to your build directory as MyAddIn-AddIn64.xll (and the .dna config file). So far so good.
2. ExcelDnaPack is run against MyAddIn-AddIn64.dna
3. ExcelDnaPack sees you wish to save your file as MyAddIn-AddIn64.xll - sure, no problem.
4. ExcelDnaPack sees the file MyAddIn-AddIn64.xll already exists - of course it does. You copied it there from the base ExcelDna64.xll (exactly as the default post-build script does) with the intent to overwriting it with a packed version. To you, this seems natural, but...
5. ExcelDnaPack deletes the file MyAddIn-AddIn64.xll (so that it can create a new file there)
6. Only now does ExcelDnaPack look for an .xll in the same directory as your .dna file with the same name. It was there, but the /Y option just deleted it.
7. Since it couldn't find MyAddIn-AddIn64.xll, it goes on over to the 'packages' directory (which is the fallback behavior) and grabs ExcelDna.xll, which is the wrong bitness. (that's an actual word by the way :p)
8. You now have your shiny new MyAddIn-AddIn64.xll in your debug folder, but it is actually a 32 bit add-in. Whoops.
This problem can be resolved/prevented by changing ExcelDna a number of ways:
- One way (and Govert has clearly considered this according to comments in the code) is to delete the fallback behavior of using the package ExcelDna.xll. This will avoid the need to try to encode logic about whether to use the 32 bit or 64 bit version and force the user to ensure the correct file is alongside their dna file.
- Change the behavior of the /Y flag. Instead of deleting the target file upfront, first generate the packed xll to a temporary file (microsoft software commonly does this by creating a file starting with ~), then overwrite the file at the very end. This will allow the same file to be used as an input, and then overwritten (which I feel might be a common desire).
- Make the input xll file an optional parameter. (like /I). If the user explicitly passes this, then the tool shouldn't attempt to use any "Fallback" strategy for picking an xll file, which can avoid confusion such as the above situation.
As a workaround, the solution to this is to either manually rename the output file, or change the file names of the transient input dna and xll file names, and optionally delete them after ExcelDnaPack is run, so a developer doesn't get confused about which add-in they should be pulling out of the build artifacts.
Here's my final Post-build events:
REM Copy the dna configuration file and name it so that it is used for the 64 bit version of the add-in.
xcopy "$(TargetDir)internalName.dna" "$(TargetDir)internalName64.dna*" /C /Y
REM Copy the template add-in and 64 bit version to the build directory.
xcopy "$(SolutionDir)packages\Excel-DNA.0.32.0\tools\ExcelDna.xll" "$(TargetDir)internalName.xll*" /C /Y
xcopy "$(SolutionDir)packages\Excel-DNA.0.32.0\tools\ExcelDna64.xll" "$(TargetDir)internalName64.xll*" /C /Y
REM Pack the add-in and 64 bit add-in with their dependencies so that it is a standalone add-in.
"$(SolutionDir)packages\Excel-DNA.0.32.0\tools\ExcelDnaPack.exe" "$(TargetDir)internalName.dna" /O "$(TargetDir)MyAddin.xll" /Y
"$(SolutionDir)packages\Excel-DNA.0.32.0\tools\ExcelDnaPack.exe" "$(TargetDir)internalName64.dna" /O "$(TargetDir)MyAddin64.xll" /Y
REM Delete the no longer necessary DnaPack source files
del /Q "$(TargetDir)internalName*.dna"
del /Q "$(TargetDir)internalName*.xll"