I have had the pleasure of using ISLE and its now got to the point where I have to post a question on SO. Ohh the headache.
I have tried added the Extended WPF Tookit via nuget and manually to my application but with no luck getting ISLE to include these assemblies when it builds the installer. I have done a dependency scan in ISLE and in both scenario the dependencies are present.
I am using a TeamCity (v8.1.1) build server to automate the build. Everything works fine except that it will not include the above mentioned assemblies in the package.
How do I solve this problem?
Update #1
With some more research it seems that ISLE on the dev. box picked up a wrong version of log4net.dll while the build server found the correct version.
Resolution - Cleared all log4net.dll found in the "%temp%\Temporary asp.net files" folder.
You solve the problem by turning off dependency scanning and take responsibility for knowing what your applications needs to run and what the best way for deploying it. Dynamic installation authoring has never fully worked and it never will. When you take into consideration all the different kinds of apps and the way they take their dependencies it becomes obvious.
The easy button is an illusion.
I am unaware of why ISLE has these inconsistency and obvious logic problems however I have resolved my issue, albeit the solution is shaky.
Issue #1
Firstly I encountered a XamlParseException due to a TypedInitializationException. An assembly could not be loaded and that assembly was noted in the Exception which turned out to be log4net. The log4net assembly was in the folder however it was the wrong version.
Somehow ISLE found an older version of this assembly in the "%temp%\ASP.NET Temporary files" folder and used that in the package. Clear all these files and give ISLE no choice but to use the assembly you have provided. NOTE: Don't get gungho and delete the culprit assembly if found in the folder of one or more of your installed applications - it just might stop working.
Issue #2
I realized that not only were the Extended WPF Toolkit but the output of a dependent console application was missing from the install directory.
You would expect ISLE to find all dependencies however it doesn't.
Based on the advice provided by ##Christopher Painter I added the primary output of the console application dependency manually. I expected this to solve the console dependency issue however it turned out to solve both.
Now does ISLE break internally if the one of the dependencies is unavailable, locked, or some exception occurred while adding to the output causing it to stop at that point and not add any more dependencies. Who knows, but I am sure there are some flaws within ISLE Microsoft if you are going to ship a 3rd party and only a 3rd party installer ensure that it works properly first.
Update #1
Running the build a second time on the TeamCity server resulted in the Extended WPF Toolkit not being added again. So it seems again the ISLE installer is really shaky.
Issue #3
Another option to solve the missing Extended WPF Toolkit assemblies would have been to add then explicitly as dependencies. ISLE however adds a explicit rather than relative path location to these files meaning that you need to recreate the folder structure on your build server (not good).
If anyone has a better solution I would love to hear it. This request also goes out to Flexera Software and hopefully the answer is not to upgrade to the PRO version or pay for support.
Related
I have an assembly (MYASM.dll) targeting .NETFramework 4.0 (with a strong name)
I want to deploy this assembly in a way it is part of .NETFramework (or the whole system thinks it is) on target machine.
By that I mean:
.NET runtime sees it at it sees System.dll (no need to deploy locally or provide a reference path)
MSBuild sees it when I do <Reference Include="MYASM" /> without needing a hintpath
User is able to make Add reference in Visual Studio and that introduces <Reference Include="MYASM" /> without the strong/full name
I have solved 1. (and apparently 2.) by adding it to the GAC. But this is apparently not sufficient.
I have partially solved 3. by putting my assembly in a special folder ([INSTALLFOLDER]\lib) and set registryKey HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0\AssemblyFoldersEx\MyAssemblies
Then I can do Add reference, but then I get:
<Reference Include="MYASM, Version=1.1, Culture=neutral, ..." /> in my csproj instead of just <Reference Include="MYASM" /> as I'd like.
With the second approach, if I manually edit the csproj, everything is OK, but I can't ask my users to do that.
What should I do here?
[EDIT] apparently it’s not obvious I have my own MSI. But yes I have. I don’t control users machines with a magic wand
No, you've taken this as far as it can go. It isn't actually that obvious how VS figures out to put the partial assembly name into the project file. This is not public code and can't be tampered with. Pretty sure it does not use a white-list and it can't pay attention to the reference assembly location.
Most likely detail is the PublicKeyToken of the assembly. The framework assemblies always have to exact same value for them, b77a5c561934e089. Its value is even prescribed in the CLI spec (Ecma-335). Next most likely by a considerable distance is the signing certificate, identifying the assembly as owned by Microsoft. Both however present the exact same problem, you can't get the private key that is required to strong-name or sign the assembly. They are locked inside a vault in Redmond, only trusted build engineers have access to them.
There is another nasty little detail you are overlooking, you are not nearly scared enough of DLL Hell. Cold hard fact is that if you ever expose the assembly in the GAC on another machine that is not in your control then you can never change it again. You can no longer modify the public interface of the assembly. Can't add a new public method or type, can't modify the arguments and return type of a method, can't add an enum member, etc. Even harsher, something Microsoft worries about, is that you can't really change private and internal members either. Programmers have a knack for using Reflection to poke around, terrific bug fixing tool. But at least you can tell them "don't do that!".
Making such modification requires increasing the [AssemblyVersion]. Now you get a different kind of DLL Hell, the machine might not have been updated by your installer. Or worse, a solution uses projects that have different references. Microsoft had to solve this problem for framework assemblies, they did so by modifying the CLR. Automatically forwarding old versions to new ones. The basic reason why using an assembly built for .NET 2.0 can be used in a .NET 4.x project. You can't get that kind of service for your own DLL.
"Don't do it" is the only good advice, getting in DLL Hell trouble is however a terrific learning experience I can recommend for anybody. Hell has to be experienced to be feared.
Best advice is to publish a Nuget package. They do the exact opposite, never deployed in the GAC and version numbers change very rapidly. But always available when a programmer needs it.
There are a few ways...
1) is to create a new setup and package this for the framework you target. You can Package this and have it deployed using the domain controller. When your users log in the domain will update the packages, this way you'll be able to deploy your software to specific users and or user groups. Depending on your infrastructure you'll have a software management infrastructure that you can use (2 links included).
2) Create a NuGet package if you're targeting developers. If your organisation host your own NuGet server limiting the distribution. Add the Package source to Visual studio open the Options Page, type NuGet in the search field and set the URL/ UNC path.
3) use OneClick deployment, this allows you to have the application download the updated dll's and install them on the machine. It requires a Code Sign certificate but you're probably signing your code anyway (better for Anti-Virus tools if you do).
Now linking your MyAsam.dll will be done by the application linking definition or IoC container. Basically, if it finds the dll and no version is defined it will take the first one it finds I think the order is 1 AppFolder, 2 GAC, 3 Path, not sure. This "take what you find" is generally referred to as "DLL-Hell", The NuGet and OneClick solution works best in this as You will always get the Updated dll that works for the application. Placing the DLL in GAC is going to get problematic if you have moe than 1 application using your dll and both need the "right" version where the "right version" differes between them....
If you have the source code available for MYASM.dll, then I would prefer adding a project reference to your consuming application. When doing so, Visual Studio shall create a GUID for all the referenced project.
For a project I am working on, I need to solve a mathematical model. I chose to do this using Microsoft.Solver.Foundation and the SolverFoundation.Plugin.LpSolve plugin. Both associated .dll files for these extension seem to work fine, as VS2015 recognizes and references them without a problem and compiles and runs my program without errors.
This is however up untill I try to actually solve my optimization, which needs "lpsolve55.dll" to work. I have downloaded this dll and put it in my project's bin/Debug folder, but for some kind of reason VS2015 just doesn't recognize it. I.e.
I can't reference it by simply browsing to it from my "Add Reference" tab.
It's impossible to (un-)register it via the regsvr32 cmd-prompt application, as it doesn't have any DLL (Un-)registry entry points.
The TlbImp.exe cmd-prompt application can't handle it.
So basically, after discovering the above (after trying the most-common internet solutions), I still feel quite dissatisfied to get the error message while I try to solve the optimization -
Unable to load DLL 'lpsolve55.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
The wierd part is also that I have another project in which I solve a similar problem, where there are absolutely no problems at all using lpsolve55.dll....
Some quick facts:
I reference .NET framwork 4.5.2. I have changed it to 4.5 as well as 4.0, but this didn't change anyting.
For as far as I can tell, the bin/debug folder of my projects are identical.
I am working on a fully updated windows 10 OS, 64 bits, while using visual studio 2015.
My question would thus be whether or not some of you have encountered a similar problem and if you were able to solve it in some way.
Highly appreciated!
After some careful analysis, I have found the answer to the problem. To be honest, as most things are, it was quite simple in the end. The lpsolve55.dll wasn't recognized because I didn't have my new bin-folder in the Path, which I did have with my old project. I simply forgot.
On a further note however, after the lpsolve55.dll directory was added to the path, I still got an error telling me there was no model to be found that could solve my directive. Since the error occured when I was calling the LPSolverDirective(), some research landed me on the following page:
http://lpsolve.sourceforge.net/5.5/MSF.htm
Above page gives a complete and stable way of how to acces lpsolve55.dll using the LPSolverPlugin straight out of Microsoft.Solver.Foundation.dll. After following the method in the link that involves editing my projects' bin/Debug and bin/Release folders, I got the LP model up and running within no-time.
Morale of the story - read the documentation. I am a bit of a beginner in programming entire multi-project solutions and using customly-added dlls, but hopefully this helps someone else experiencing the same. In the end, I learned a lot by simply trying different methods of getting it to work, so no time was wasted.
We're trying to switch a lot of projects over to use SDK7.1. This seems pretty straightforward with C++ projects, and you can change the 'Platform Toolset' property in the project settings to "Windows7.1SDK" and all is good.
But, with C# projects, (if you put the build output up to diagnostic mode), we can see that various tools such as sgen, resgen, LC, run from within a previous SDK 7.0A directory. Or, on some machines that we installed Vistual Studio 2012 on, some of these tools come from an v8.0A SDK folder.
Mismatches between the tools and the assemblies they produce seem to be causing various errors such as:
LC : error LC0000: 'Could not load file or assembly
'S:\Libraries\Bin\Release\Some.dll' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.'
It seems we can edit the .csproj files and almost ad-hoc, and BeforeBuild etc targets that redefine various SDKPath properties. This seems to force the right tools to be used. But, if feels very 'hacky'. And we must be missing setting something as we still get some errors.
Alternatively, we've found, we can change the registry value here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0\SDK40ToolsPath
to point at the correct SDK. But, it feels wrong to have to modify the environment to support this. We want to build old versions of our product, and having to switch the environment around to do this is ugly and error prone.
Is there any official way of doing this?
Thanks.
P.S. I found this question http://social.msdn.microsoft.com/Forums/en-MY/windowssdk/thread/ebc8914f-d4b5-44e7-8c76-10332d155812 where the poster seems to be asking a similar thing, but, the question didn't seem to get answered.
The following two articles talk about defining custom tool sets. Perhaps one of those needs defining for the 7.1 SDK, and then MSBuild can be directed to use it.
http://msdn.microsoft.com/en-us/library/bb383796(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/bb397428.aspx
Ok this question is more about understanding what the issues are as I dont think anyone will be able to tell me how to fix the problem.
I am writing a .net 4 application and I have a 3rd party dll ( hasp dongle protection ) that I want to reference.
Visual studio allows me to create the reference fine and use classes contained within the dll within my code.
The first issue occurs when the program is run and the dll is actually loaded. I then get the following error.
System.BadImageFormatException: Could not load file or assembly
'hasp_net_windows.dll' or one of its dependencies. is not a valid
Win32 application
This weblink states how to fix this error. Coud someone expalain what the issue is and why im getting it.
After following this advice I then set the main project build to x86 and I then get another error replacing the other. The new error is:
System.IO.FileLoadException: Mixed mode assembly is built against
version 'v1.1.4322' of the runtime and cannot be loaded in the 4.0
runtime without additional configuration information
This weblink states how to fix the error, but I dont have an app.config in my project and want to avoid having one if at all possible. If someone could explain what the issue is again that would be helpful?
Please let me know if you require anymore information.
The issue is the "bitness" of your application. Once chosen (32 bit or 64 bit) all DLLs within that process need to be the same. This exception tells me that one of your DLLs is the wrong "bitness".
You simply cannot have DLLs with different compilation targets within a given process, a process has "bitness" affinity.
If this is a third party unmanaged DLL then it is very likely 32-bit compiled.
Setting the build output as x86 for the root project (the one that creates the exe) should suffice as this will dictate the process that is created. Any other .NET projects can then simply be Any CPU and will fit in either the 32 or 64 bit runtimes.
Unfortunately for your second issue, the provided link is the way to solve it. There is nothing wrong with having an app.config in a project and you haven't stated why you don't want one.
The answer by Adam Houldsworth notwithstanding, I'd like to add that it is possible to do it without an app.config. However, this requires a tiny bit more work and potentially a proper understanding of COM interop. Whether it's worth the trouble is up to you of course ;).
You can set useLegacyV2RuntimeActivationPolicy programmatically by using the ICLRRuntimeInfo::BindAsLegacyV2Runtime method.
A quick rundown on how to do this is posted in this blogpost. Take note of his warning though, which might make you think twice in using this approach:
This approach works, but I would be very hesitant to use it in public
facing production code, especially for anything other than
initializing your own application. While this should work in a
library, using it has a very nasty side effect: you change the runtime
policy of the executing application in a way that is very hidden and
non-obvious.
I cannot use an app.config file because the assembly is loaded via COM from a native program.
I found the library that supports .net framework 4.0. here. In this scenario, no other solutions had worked for me.
So I recently updated my software and with the new version I supply a new dll-file, lets call it My.dll. Now, the old version works just fine on every computer I have tried.
The problems began with the new version. Specifically, so far on at least one computer, it states that "Could not load file or assembly My.dll". This even happens when I have dropped a copy of the software on a network drive and run the software directly from there. It works on every other computer but one, which still gives the exact same error where other computers work fine.
The dll in question is even in the same directory as the executable, so I'm really quite bummed here. I tried to google around a bit as well, but all the issues I found were related to ASP.NET specifically. Any ideas on how to go about finding the problem would be much appreciated.
It is possible that the computer in question has a DLL added to it's Global assembly cache. This would take priority over the DLL in the same folder.
More information about the GAC: http://msdn.microsoft.com/en-us/library/yf1d93sz(v=VS.100).aspx
Is there an old copy of the DLL lying around? Perhaps with a different name? I had a similar issue when I changed the name of a dll. Internally, the namespaces were the same.
In my case, an older version of the DLL was still there. .NET got confused with two assemblies in the bin directory having the exact same namespaces and classes, couldn't decide on which to load, and threw an exception.
Removing the older version of the dll solved the issue.
Use the Assembly binding log viewer and set it to log failures. This will give you some clues as to why it is not loading.
You could take a look at the error log using the Assembly Binding Log Viewer. First you have to turn on logging.
--Right Click on Project
--Goto Properties->Build tab
--Change Platform and Platform Target to Any CPU, Save and run