cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
SimonJohnson
Level 2

InstallShield LE, the Advertised ShortCut and error loading a DLL

I recently had to move some resources from one project into a new class library. This content is simply XML. In my IDE I have no problems running the software. I went into the InstallShield LE Setup process and added the output of the new project to the Application Files.

I run the Setup file that gets built by IinstallShield and this new project, X3_Content.dll, gets dumped into the installation folder with all the other bits and bobs. When I run the program from the shortcut that the InstallShield creates in the Start Menu I get an error when that DLL is not found. Sometimes my exeception lists that it fails to find the DLL in System 32, sometimes in the Start Menu folder of all places, and sometimes in other random locations that do not exist inside the install directory (below is what my log reports). Its supposed to be in the installation directory, which it is. When I run the application from the Program Files folder there is no issue the software loading the DLL.

Ive run the program from both the shortcut and the file directly and checked out the process to see where it resolves to and they both definately go to the same installation folder. I have checked for previously installed versions, multiple exes of the same name - nothing.
Anyone have any idea what this madness is!??!

Note: "X3_Content.DLL" is not the first DLL that would be called, there is one for the database interaction thats working before it gets this far

Note 2: X3_Content.DLL has no dependencies, its just embedded resources of XML inside of a file structure

[CODE]31/08/2016 16:05:19 1.0.0.1 ] System.IO.FileNotFoundException: Could not load file or assembly 'file:///C:\Windows\system32\X3_Content.dll' or one of its dependencies. The system cannot find the file specified.
File name: 'file:///C:\Windows\system32\X3_Content.dll'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at ZTT.SplashScreen.FileLoader.LoadPICSFile(PICS& pics)
at ZTT.Loader.LoadData(Manager dbMan)

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at ZTT.SplashScreen.FileLoader.LoadPICSFile(PICS& pics)
at ZTT.Loader.LoadData(Manager dbMan)[/CODE]
Labels (1)
0 Kudos
(2) Replies
Not applicable

Don't know about IS LE, but when setting up a shortcut in IS Premiere you can specify a 'Working Directory' for a shortcut. Normally this would be set to [INSTALLDIR] say.
0 Kudos
SimonJohnson
Level 2

Hysteresis wrote:
Don't know about IS LE, but when setting up a shortcut in IS Premiere you can specify a 'Working Directory' for a shortcut. Normally this would be set to [INSTALLDIR] say.


I didnt have this set, the accompanying text for Working Directory doesnt actually make it very clear that this is required. Maybe I still dont understand advertised shortcuts properly.

Ive just found a solution but it only compounds my confusion. In the code snippet below is the previous way of loading in the assembly.It relied on the fact that the DLL is in the executing directory because Im not a mad man and this is normal (right?). This project has to dynamically load different DLLS, so they cant be referenced because they may not be present. In my IDE or when I run the program directly or use a normal shortcut Windows is able to find the target DLL because its in the executing directory of the program. When run from an Advertised Shortcut instead it fails to find the DLL in the executing directory (is the executing directory different?), so it starts looking around the computer to see if its installed elsewhere - this is why usually the error shows up in System32. I have changed my code now to instead get the executing directory, look through the DLLs inside to get the ones I may need and then work with them and that seems to work with the Advertised Shortcut just fine.

Assembly assembly = Assembly.LoadFrom("X3_Content.dll");


But im still puzzled as to why an Advertised Shortcut can:

a) Create this scenario where the executing directory differs from that of the actual program (if thats whats happening)
b) Why the InstallShield "Project Assistant" makes no refernece to the "Working Directory" attribute of the shortcut if this is super important
c) How I am apparently the first person to ever encouinter this scenario!

EDIT: Below is my quick solution for anyone else one day who goes through this pain and wants an answer!
It gets the executing directory (which is different from the IDE/debugger to your installation target), pulls out a list of DLLs and then lets me get the one I need

[CODE]

DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location).ToString());
FileInfo[] fi = di.GetFiles("*.dll");
string path = "";

foreach (FileInfo f in fi)
{
if (f.FullName.Contains("_Content"))
{
path = f.FullName;
}
}

[/CODE]
0 Kudos