Why is ClickOnce downloading unchanged files? - c#

Context:
I'm using C# and Visual Studio 2015 to develop and deploy an application with ClickOnce, and I'm trying to shrink the ClickOnce update download size. ClickOnce is capable of delta-only updates:
When updating an application, ClickOnce compares the hash signatures of the files specified in the application manifest for the current application against the new version. If different, ClickOnce downloads the new version. If the signatures match, ClickOnce copies the existing file and uses it in the new version of the application. This approach prevents ClickOnce from having to download the entire application again, even if only one or two files have changed.
Problem:
I've verified that between updates of MyApp, the hash signatures of most files do not change (on the command line using shasum or in the actual manifest files). But ClickOnce still downloads every file on every update.
For instance, MyApp depends upon Emgu.CV.dll, and I just published MyApp 1.0.9.4 from within Visual Studio 2015. Here is the Emgu.CV.dll reference from the manifest file located in the publish output location, MyApp\Application Files\MyApp_1_0_9_4\MyApp.exe.manifest:
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Emgu.CV.dll" size="363520">
<assemblyIdentity name="Emgu.CV" version="3.0.0.2158" publicKeyToken="7281126722AB4438" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>lUb/oa0aQL6HWEhY8Juj6Mc1wChKo0owhJJ+sSfqZUs=</dsig:DigestValue>
</hash>
</dependentAssembly>
And here is the same .dll's dependency tag from a previous deployment, MyApp_1_0_9_2\MyApp.exe.manifest:
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Emgu.CV.dll" size="363520">
<assemblyIdentity name="Emgu.CV" version="3.0.0.2158" publicKeyToken="7281126722AB4438" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
<dsig:DigestValue>lUb/oa0aQL6HWEhY8Juj6Mc1wChKo0owhJJ+sSfqZUs=</dsig:DigestValue>
</hash>
</dependentAssembly>
They are identical. Notably, the <hash><dsig:DigestValue> content is identical, just like all of the other ~150MB worth of dependencies declared in their respective tags between versions 1.0.9.2 and 1.0.9.4.
Only a couple of hash values actually changed between those two manifest files. For example, the MyApp.exe hash changed from
JryzNpD+emqeruXW7X2unRm0i58w9z9ct++Jeog40FI=
to
tF/hs87T4n9sMgoUJUmk31zAUsi7MsWXhLdKGxlR+EM=
But a ClickOnce update from 1.0.9.2 to 1.0.9.4 downloaded MyApp.exe and Emgu.CV.dll and every other file, changed or not!
Why is ClickOnce downloading files whose hash hasn't changed?
Research so far:
This SO question is related, but the answer isn't applicable because I'm not rebuilding the assemblies that are being redundantly downloaded, they're just being copied (as is evident from the unchanging hash signatures).
This SO question is related, but the asker simply misunderstood what "Copy if Newer" meant.
I've read this troubleshooting MSDN page, my problem doesn't appear.

The issue is the ClickOnce progress dialog. It always shows the whole size of your application, even it only a single file is downloaded. Make sure to run a monitoring tool like Fiddler to see what actually is being transferred.

Related

C# application user settings maintained during update

I have a C# application that currently stores user settings/configurations in a separate xml file. My application uses a wix installer and id like to know if there is a way to preserve the xml file should the user be installing a newer version of the application if they install without first removing the older version. The xml file is stored in the CommonAppData folder and should be removed if the application is uninstalled.
Backup question - Is there a better way of doing this than my current method?
UPDATE
I have implemented the following code:
<CustomAction Id="Cleanup_Files" Directory="CompanyFolder" ExeCommand="cmd /C RD
"[CommonFolder]" /s /q" Execute="deferred" Return="ignore" HideTarget="no"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="Cleanup_Files" Before="RemoveFiles" >
Installed AND REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE
</Custom>
</InstallExecuteSequence>
This removes the CommonFolder directory as required on uninstall but it still removes the directory when upgrading. What changes are necessary to achieve this?
The easiest thing to do is: do not insatall this XML file by the setup, but instead let it create by the application if it is not there. By this, an update will not touch the file.
With this scenario it is also possible to migrate the settings from an older (or newer) version.
However, the file will also remain on uninstall. If it is a requirement to remove it in this case, you can do this by a custom action with a condition like Installed AND REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE
The solution for me was to follow the advice of Klaus but with some additional changes to my product.wxs file. I had to add 'AllowSameVersionUpgrades="yes"' to the MajorUpgrade section.
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of
[ProductName] is already installed." />
Thanks to Klaus for all of their advice!

EXE file is not working

I have a .msi (windows installer package) file into my project . I generated .exe file from .msi file successfully but whenever I try to open that .exe file or run as administrator it does nothing . How to solve this? Anything will help regarding this . Please help
UPDATE
Here is my code for .msi file
components.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?include Defines.wxi?>
<Fragment>
<ComponentGroup Id="MenuComponents" Directory="ProductMenuFolder">
<Component Id="ProductMenuComponents" Guid="*">
<!--<Shortcut Id="UninstallPackage" Directory="ProductMenuFolder" Name="Uninstall package"
Target="[System64Folder]msiexec.exe" Arguments="/x {[ProductCode]}" Description="Uninstalls $(var.YourApplicationReference.TargetName)"/>-->
<RemoveFolder Id='ProductMenuFolder' On='uninstall' />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]'
Type='string' Value='' KeyPath='yes' />
</Component>
</ComponentGroup>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="FileWatcher">
<File Source="$(var.FileWatcher.TargetPath)" />
<!--Register this file as a Windows service-->
<ServiceInstall Id="ServiceInstaller"
Type="ownProcess"
Description="Sends Incoming mainframe files to the Webservice"
DisplayName="FileWatcher"
Vital="yes"
Start="auto"
ErrorControl="ignore"
Interactive="no"
Name="FileWatcher"
Account="[ACCOUNT]"
Password="[PASSWORD]">
<ServiceConfig Id="svcConfig" DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes" OnUninstall="no" />
</ServiceInstall>
<!--Set the user to be used by the service-->
<util:User Id="ServiceUser" Name="[ACCOUNT]" Password="[PASSWORD]" CreateUser="no" LogonAsService="yes" UpdateIfExists="yes" />
<!--Added example of how to stop service automatically-->
<ServiceControl Id="ServiceControl" Stop="both" Remove="uninstall" Name="FileWatcher" Wait="yes" />
</Component>
<Component Id="FileWatcher.Files" Guid="*">
<!--<Component Id="MAIDFileWatcher.Files" Guid="*">-->
<File Id="filB93E7D71690869B9CD2D0A479DB69C6C" Source="$(var.FileWatcher.TargetDir)\ExceptionHandling.dll" />
<File Id="fil487232F7A833919419AF9537A4390083" Source="$(var.FileWatcher.TargetDir)\ExceptionHandling.xml" />
<File Id="filDE3649B71309470D2D7C086E0FAABAE8" Source="$(var.FileWatcher.TargetDir)\itextsharp.dll" />
<File Id="filF73350F1AEF9ECF2621D4E63B9823029" Source="$(var.FileWatcher.TargetDir)\FileWatcher.exe.config" KeyPath='yes'/>
</Component>
</ComponentGroup>
product.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Version.wxi?>
<?include Defines.wxi?>
<Product Id="$(var.PRODUCTCODE)" Name="$(var.PRODUCTNAME)" Language="1033" Version="$(var.REVISION)" Manufacturer="$(var.MANUFACTURER)" UpgradeCode="$(var.UPGRADECODE)">
<Package InstallerVersion="400" Compressed="yes" InstallScope="perMachine" Comments="$(var.COMMENTS)" Description="$(var.DESCRIPTION)" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="ProductFeature" Title="$(var.PRODUCTNAME)" Level="1">
<ComponentGroupRef Id="ProductComponents" />
<ComponentGroupRef Id="MenuComponents"/>
</Feature>
<UIRef Id="USERUI" />
<?include Actions.wxi?>
</Product>
</Wix>
You can debug an msi installation with a command line like this:
msiexec /i someapplication.msi /L*vx log.txt
This will run the installer and output log info to a file called log.txt.
See also: Windows Installer Command Line Options
Another pro tip is to debug your installer in a virtual machine. Take a snapshot before installing so you can roll back, or repeat the installation after making code changes and start from a reproducible state. I can't imagine debugging installers without Hyper-V - it's essential to me.
This is basically just shooting from the hip, please ignore whatever is not relevant (maybe check the very last three bullet points first):
Best practice: first of all, you are installing multiple binaries with a single component. This is a violation of component creation best practice.
For something this small I would suggest you use one component per file. This solves all kinds of future problems with patching, upgrades and other things.
What happens if the component rules are broken? Please skim this, or take our word for it and just use one file per component. At least make a separate component for all binaries (required).
A little blurb about the nature and philosophy of component GUIDs: Change my component GUID in wix? Some find it helpful to understand the mysterious and always troublesome component GUIDs.
If you insist on using multiple files per component, make sure that the key file for the component is a versioned file. I would think WiX would auto-magic this.
If you don't have a versioned key file, you could risk the component not installing at all if there are files already in the target location.
If you do have a versioned key file, make sure that your install has a higher version binary than the one it may encounter on disk at the target location (if any). Please read about the MSI file versioning rules for an explanation.
Logging: Does your application have a log feature (by default, or one that you can enable) which you can use for debugging? Maybe to the system's event log? Wouldn't services write there?
Dependencies: Also, did you check the pointers I provided earlier with regards to dependency checking? C# Debug folder when copied to another location does not run the exe.
Checking first the modules view in Visual Studio, and then using Dependencies.exe to check for missing dependencies?
Using procmon.exe is a little involved, but almost always reveals surprises and problems that can be hard to detect in other ways: Registering a CPP dll into COM after installation using Wix Msi installer
Does Fuslogvw.exe tell you anything? (.NET assembly binding failures).
Service Credentials: are you sure that those login credentials are getting applied during installation?
Did you try to set them manually to see if the service will run then? Did you add these properties to the SecureCustomProperties list of properties allowed to pass to deferred installation mode?
I think WiX has "auto-magic" here and does this for you, I forget. Check SecureCustomProperties in the property table of your final, compiled MSI using an appropriate tool, for example Orca.
With that delayed service start setting, is the service even running? (got to mention it at least). Or did you say it crashes on launch?
Hard-coded references: pointers to missing resources.
Did you check all the manifest files and config files (FileWatcher.exe.config) for anything funky that points to resources on your developer box (erroneous, hard-coded references)?
Could there be lacking resource files? (images, dlls, etc...).
Architecture & runtime requirements: is the target computer the same architecture as your developer machine? Just to chalk it up, surely you would see a warning about this?
What is the CPU targeted by your code? Any CPU? Did you try to manually register the files on another machine (a clean virtual machine maybe).
Is there anything special about the problem, target computer? Does it have weird policies? Does it have security software blocking things? Does it lack a common runtime component that is installed on your development computer? (.NET, VC++ runtime, VC runtime, java, etc...). These are the things a procmon.exe session should reveal, or a check with Dependencies.exe should show.
Are you using the notorious FileSystemWatcher .NET class? I have used it only once many years ago, but it caused me a lot of grief and I had to stop using it. It did crash my service file regularly.
I will dig up some links here if you are using this class.
Found a couple for now: FileSystemWatcher events raising twice despite taking measures against it and FileSystemWatcher vs polling to watch for file changes.
When I have installed my EXE under %PROGRAMDATA% I had the same issue
When I have installed my EXE under %PROGRAMFILES% I solved the problem

Deploying COM components with ClickOnce application

We're developing a C# WPF (.Net 4.0) application that requires screen "recording". We've evaluated ByteScout's Screen Capture SDK (free trial available), and it does exactly what we need to it.
However, the problem is that our application is designed to be deployed by ClickOnce, to our clients' machines (not on our network), and who will likely be logged in as limited, non-administrative users. The SDK has a redistributable component, but this requires to be installed separately - no good for ClickOnce.
ByteScout seemingly address this need in their documentation, under the section "Registration-free deployment":
/*
* REGISTRRATION FREE SCENARIO DEPLOYMENT: allows to just copy DLLs from the SDK without installing them
* See SAMPLE.EXE.manfest as the sample.
* 1) Rename "SAMPLE.EXE.manifest" into the actual application name (e.g. "MyApp.exe.manifest")
* 2) Edit this .manifest file and replace "SAMPLE.EXE" with your application name (e.g. "MyApp.exe")
* 3) Copy put this .manifest file into the same folder where your MyApp.exe is located
* 4) Copy all dlls from /x86/ folder into the same folder as your application
* So you will have files in the folder:
* - MyApp.exe
* - MyApp.exe.manifest
* - BytescoutVideoMixerFilter.dll
* - BytescoutScreenCapturingFilter.dll
* - BytescoutScreenCapturing.dll
* 5) Now you should be able run MyApp.exe without Screen Capturing SDK installed
So: I created an app.manifest file - my project didn't have or need one before - and added in the following from the SAMPLE.EXE.manifest mentioned above:
<file name="BytescoutScreenCapturing.dll">
<comClass
description="Capturer Class"
clsid="{48967118-C4C9-435C-94D8-001247B9A52A}"
threadingModel="Apartment"
progid="BytescoutScreenCapturing.Capturer"
tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" />
<comClass
description="C:\Documents and Settings\Administrator\My Documents\Capture From Entire Screen\bin\Debug\BytescoutScreenCapturing.dll"
clsid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}"
threadingModel="Both" />
<typelib tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}"
version="1.0"
helpdir="C:\Documents and Settings\Administrator\My Documents\Capture From Entire Screen\bin\Debug\" />
</file>
<comInterfaceExternalProxyStub
name="ICapturer"
iid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" />
<comInterfaceExternalProxyStub
name="IVideoWMVSettings"
iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" />
<file name="BytescoutScreenCapturingFilter.dll">
<comClass
description="Bytescout Screen Capturing Filter"
clsid="{0F5D4CE4-2166-4FF7-9AA1-91330D35978A}"
threadingModel="Both" />
<comClass
description="Screen Capturing Property Page"
clsid="{22DD33B0-30C4-420D-A955-844E2B85A1F3}"
threadingModel="Both" />
<comClass
description="Screen Capturing Property Page"
clsid="{9D153AAA-0477-4C2E-B827-211F10561B44}"
threadingModel="Both" />
<comClass
description="Screen Capturing Property Page"
clsid="{26882CF7-F62F-47DB-9A3C-D1191591BD04}"
threadingModel="Both" />
</file>
<file name="BytescoutVideoMixerFilter.dll">
<comClass
description="Bytescout Video Mixer Filter"
clsid="{4407F28D-97C2-41C5-A23F-2FAE465CE7BB}"
threadingModel="Both" />
</file>
So my app now has:
A reference to BytescoutScreenCapturingLib, with "Embed Interop Types" set to "True"
The three DLLs - BytescoutScreenCapturing.dll,BytescoutScreenCapturingFilter.dll and BytescoutVideoMixerFilter.dll added to the project as "Content", with "Copy to Output Directory" set to "Copy Always"
The above app.manifest file.
The project builds fine, but when I now run it the app crashes. Looking in the Event Viewer, I see the error:
Activation context generation failed for "myapp.exe.Manifest".
Error in manifest or policy file "myapp.exe.Manifest" on line 89. The value "" of attribute "resourceid" in element "typelib" is invalid.
Bytescout also have a sample Console Application, and I've having the same issue with this: the project builds fine, but it fails with the above error. I've tried engaging with their support, but I'm not getting much responses apart from "try reading the documentation".
I've tried "self-registering" the COM components; I don't have much (or indeed, any) experience with COM, but all the sample code I've tried doesn't appear to (A) work and (B) work without Adminstrative privileges or (C) both. I'm not sure if it's something that COULD work in my scenario.
Can anyone advise on how to proceed please? All we need is the DLLs to be "registered" and available for use within my code, without having to install them.
EDIT: If I edit the generated myapp.exe.Manifest file, and set "resourceID" to be "1", I get a further error:
Activation context generation failed for "myapp.exe.Manifest".
Error in manifest or policy file "myapp.exe.Manifest" on line 103. The value "" of attribute "tlbid" in element "comClass" is invalid.
If I remove the app.manifest file from my project, and set the Isolated setting on the reference DLL to True, the error on startup changes to:
Activation context generation failed for "myapp.exe.Manifest".
Dll redirector contributor unable to add file map entry for file BytescoutScreenCapturing.dll; Two or more components referenced directly or indirectly by the application manifest have files by the same name.

c# app works on dev box, has dll conflicts when deployed (oh, no, not again)

My app uses Nuget packages including Spring.rest and spring.social.twitter. Two library oddities crop up when deployed (deploying is pretty much just installing the .net45 framework and then everything in my release folder onto another machine via WIX).
First oddity is that Nuget has common.logging 2.1.2 installed on my dev box (used by spring.rest), but when spring.rest loads on the prod box, it's looking for 2.0.0. No idea why, as I don't even have 2.0.0 on my dev box, but I can download that version and copy it onto prod, and get past that one.
The second one is the spring.social - nuget decided to use the net20 libs (it's using the net40-client for spring.rest), which works fine on dev, but they (the spring.social libs) decide they need the net20 version of the spring.rest.dll on the prod box. If I change my csproj to use the net40 spring.social libs, I can't compile, because apparently they are not identical even in the same version (link failures on two function calls that work with the net20 dll). If I change spring.rest down to net20, again I can't compile, so that isn't an option.
They aren't strongly named (of course), and they are really the same version and same architecture, so I'm not sure that I could even put them in the GAC if I wanted to. I did try putting both versions in the GAC, but although I got no installer errors from my MSI, it also just did not put the libs with the same names in (I had put almost all of them there for giggles, and the rest worked). The app will run on a dedicated box, so I "own" everything about it and can do all kinds of evil things to it that would be verboten in a "normal" user app, but this little circle of fun has me baffled.
Trying to track down what is running on the dev box (to see if perhaps it is reaching out to some other location to find libs), I tried DepencyWalker (depends), but since everything is delay-loaded, it doesn't do much, even with profiling, since that stops when it hits the entry point. I tried fuslogvw, but common.logging and spring.rest don't even show up? The only nuget packages I see in fuslogvw are spring.social.twitter and newtonsoft.json, and they are both loaded from my bin folder as expected. As I'm out of ideas, I'm turning to the wonderful SO community. What are some good next steps?
Thanks,
Greg
Most likely the .config file in production and on your development machine differs. If the
dev .config file contains a bindingRedirect and your production .config does not this could be the cause for the observed behavior.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="en-us" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.71).aspx

Application crashes in InitializeComponent()

First off, I'm using Visual Studio 2010, Measurement Studio 2010 plugin, C# and .NET 4.0.
My application receives data from a USB device and graphs the data using a WaveformPlot() [which is a part of Measurement Studio]. I'm able to run the application fine in debug and release modes and even run it fine directly using the EXE file in the bin folders, on the development computer.
However, I am simply unable to run it in a different computer. I'm using ClickOnce to create an install file and folders, and I copy the publish folder from my development computer to the client computer. I then run the install file, ClickOnce downloads .NET (if it's not already installed) and then opens the application. The application shows my initial dialog asking me to choose a COM port from the many available. Once I do this, my code goes through the InitializeComponent() after which the main form is supposed to show up.
The main form doesn't open up after the initial box. Using Debug.WriteLine statements, I've been able to narrow it down to
this.waveformPlot = new NationalInstruments.UI.WaveformPlot();
It crashes here. It doesn't show me any error message or anything. It works fine on my development computer, just not on other computers. I included the National Instruments DLL files and other National Instruments components are initialized fine. It's just this one that doesn't. The application shows up in the Windows Task Manager for a while and then just vanishes after like 10 seconds.
What should I do?
Update 1
After reading another unrelated question on Stack Overflow, I realized that I could put the Application.run and the form1 mainform = new form1() in a try-catch block.
System.TypeInitializationException: The type initializer for 'NationalInstruments.UI.Internal.WaveformPlotElement' threw and exception. --> System.IO.FileNotFoundException: Could not load file or assembly 'NationalInstruments.Common.Native.dll' or one of its dependencies. The specified module could not be found.
Since I at least know it's an exception now, I'll work on it, try to figure out which DLL is missing and why, and update this question.
Update 2
I checked the application files that are in the publish folder, and it does include the 'NationalInstruments.Common.Native.dll'. I have no idea why it can't load it.
Update 3
I ran Fusion Log Viewer on the client computer and saw that the NationalInstruments.Common.Native.dll was loaded succesfully. But still, the debug exception message shows up as shown in the OP,
Could not load file or assembly 'NationalInstruments.Common.Native.dll' or one of its dependencies"
Screenshot of what the Fuslogvw.exe shows
Fuslog Viewer shows that all the assemblies have been loaded successfully. I checked on the client computer. Although, the National Instruments DLL files have a line which says "GAC lookup unsuccessful" in them while the other assemblies don't.
DebugViewer displays the exception that I print out using Debug.writeLine. This shows that the NationalInstruments.Common.Native.dll or one of its dependencies could not be loaded.
I am very confused.
I tried adding references to the project, using a decompiler to check references, using other install programs (other than ClickOnce) and none of them seem to be getting me anywhere. :(
Update 4
I just found out yesterday that the application was installing and running fine on 64-bit systems. The two computers I tried it on before were 32-bit Windows 7 systems.
I am looking to see if that could help me somehow.
The application was compiled on my 64-bit Windows 7 development laptop. The 'Platform' drop down menu in 'Build' under project properties shows 'Active (x86) and I have 'Any CPU' as the platform target.
After spending lots of time on this issue, I spoke to someone from National Instruments, and he helped me solve the issue I was having. I had previously noticed, by checking the module dependencies of mstudiocommon.2010.msm, that it (mstudiocommon.2010.msm) was looking for the vs100_crt_x86.msm file, but the installer had detected (and added) a vs90_crt_x86.msm (in the 'Detected Dependencies' of the installer project). Right-clicking the installer project and adding the VS100 .msm file manually fixed the issue that I was having.
Below, is a screenshot of the module dependencies that I could see for the mstudiocommon and mstudioui merge modules:
Although, I didn't quite understand why Visual Studio was detecting VS90 instead of VS100, I am happy that I finally fixed this problem, and I'll leave this for another day.
Try Fusion Log Viewer from SDK to identify which library causes the problem.
Without logs and error messages it's too difficult to find what is wrong. You should put a try catch in your code where you try to access the library components waveformPlot and print the error message and the stacktrace. After you can see what is missing.
You can use use either Reflector or JustDecompile to get what references 'NationalInstruments.Common.Native.dll' needs. From the sounds of it though with the word Native in the name of the DLL it maybe a wrapper around someother native Win32 C dll. Do you have those in the same folder? It may also be a wrapper around a COM dll which maybe is not registered?
I think what happen is that someone have installed application on target system that is using only subset of latest NI components. To fix this issue I have added bindingRedirect to app.config. It worked.
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NationalInstruments.Common" publicKeyToken="DC6AD606294FC298" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-13.0.40.190" newVersion="9.1.40.159"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NationalInstruments.Common.Native" publicKeyToken="DC6AD606294FC298" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-13.0.40.190" newVersion="9.1.40.159"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I had the same problem and when having tons of references in your project it's really hard to find what assembly is actually missing. Especially if you're having this problem on a clients computer without Visual Studio.
After an hour or two messing around with fuslogvw.exe and not being able to get a clear answer I just googled "detect missing assemblies .net application" and found http://www.amberfish.net/
It works like charm, there is a free trial and the developer only asks a very democratic price for it... Very Cool !!
PS. I'm in NO WAY affiliated with amberfish, today is the first time I found out about this tool. the tool this guy built should be in the default toolkit of Windows. Just what i needed.

Categories

Resources