Deploying COM components with ClickOnce application - c#

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.

Related

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

Why is ClickOnce downloading unchanged files?

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.

Web Application Build Error: The CodeDom provider type Microsoft.VisualC.CppCodeProvider could not be located

I'm building/packing a web application in a build server, and it fails with the following message:
ASPNETCOMPILER error ASPCONFIG: The CodeDom provider type
"Microsoft.VisualC.CppCodeProvider, CppCodeProvider, Version=10.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be
located.
This is the build server environment:
Windows Server 2008 R2 Standard
TeamCity 8.0.4
.NET 4.5
Windows SDK for Windows 7 and .NET 4
Windows SDK for Windows 8 and .NET 4.5
Portable Class Library Tools
ASP MVC 4
It is a ASP MVC 4 web application, targeting .NET 4.5.
The build configuration consists in building the solution with MSBuild, and deploying it to a package, so I can publish it later.
Through the log of TeamCity, I can see the error arising when MSBuild runs aspnet_compiler.exe.
The builds with no problem in my DEV machine and can also publish it to a local IIS without problems.
Does anyone know what may be causing this issue?
UPDATE
See my answer below.
For me this error was popping up in VS2017 when building the web project. The fix was to make the node_modules directory hidden in File Explorer. Apparently this stops the ASP.NET compiler from scanning all these files and thus prevents the error.
This post gave me an important clue: apparently ASP.NET precompilation scans the project and output files and tries to compile every source file it finds in its way, despite its language (see here).
In the case, my web app depends on a project which includes some unmanaged dll along a ".h" file. These files are copied to the output directory ("Copy if newer") so I can pinvoke it at runtime.
It seems ASP.NET precompilation finds the ".h" and tries to compile it, even though there is no need of it. And, as I see it, it fails because my build server does not has the tools for the job (it looks like CppCodeProvider comes with the .NET 2.0 SDK).
When I changed the project not to copy those files to the output directory, the build ran fine. I also tested copying the files, but with "PrecompileBeforePublish" set to false in the publish profile, and it also worked.
Now I have some options, but I don't like any of them:
Disable "PrecompileBeforePublish". I believe the main disadvantage of that is the app users experience will be slower on the first site access.
Try to exclude files from the output folder and add them again after pre-compilation. That seems a lot of work for something I shouldn't be worrying in first place.
Try to tell "aspnet_compiler.exe" to exclude the offending files/folder when executing. I don't know how to do it using the publish profile, because I only have control over "PrecompileBeforePublish". Also, it seems "aspnet_compiler.exe" does not offer that option (here and here).
I think for now I'll disable "PrecompileBeforePublish", because it seems a fast path with few caveats. But I believe there should be a better way to handle it, excluding folders or file types from precompilation using the publish profile.
For the benefit of those who find this later on google...
Root Cause
As the error implies, the assembly "Microsoft.VisualC.CppCodeProvider" couldn't be found.
This was added to the Global Assembly Cache (GAC) as part of Visual Studio 2015 installation, but not Visual Studio 2017.
The Fix
The proper fix is to add the missing reference to the GAC.
Run the "Developer Command Prompt" as admin, and run the following
gacutil /i "path to CppCodeProvider.dll"
or gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2
017\Professional\Common7\IDE\PublicAssemblies\CppCodeProvider.dll"
e.g.
C:\Windows\System32>gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2
017\Professional\Common7\IDE\PublicAssemblies\CppCodeProvider.dll"
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.0
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
C:\Windows\System32>
On next build the following error is no longer thrown.
ASPNETCOMPILER error ASPCONFIG: The CodeDom provider type "Microsoft.VisualC.CppCodeProvider, CppCodeProvider, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be located.
This started happening when I updating to VS2017. The problem for me was node.js, if I deleted the node_modules folder then the project would build without errors. It turns out that changing the value of MvcBuildViews to false in the csproj file as suggested by anders here fixes it. This isn't ideal though since mvc views won't be compiled until IIS renders them. Personally, I just hide the node_modules folder to get around the issue but I wanted to add this answer in case it helps shed some light on the underlying issue for someone else.
<MvcBuildViews>false</MvcBuildViews>
In my case I had added an angular website to my solution which caused this error.
Resolved the error with following steps.
On the menu bar, choose Build > Configuration Manager.
In the Project contexts table, exclude the angular website (which contained node_modules)
In the Build column for the project, clear the check box.
Choose the Close button, and then rebuild the solution.
In my scenario, I have to ship a Perl interpreter with my ASP.Net website (don't ask why I need Perl, and I'm sorry I do in advance!), and that included .c files that caused the aspnet_compiler.exe to error out, as others have mentioned being their problem. The perl directory is in my bin folder, and is required at runtime.
The trouble I found was when you attrib +H the folder, it indeed was skipped by aspnet_compiler, but then wouldn't be in my publish output folder. So I had to hack it even more by hiding the folder, compile views, unhide folder, and then copy folder to the right location. This involved modifying the original AspNetPreCompile task. See below:
<!-- Overwrite AspNetPreCompile task because it was trying to compile .c files found in the Perl directory. This prevents that but still copies Perl to publish file. -->
<!-- Taken from: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\VisualStudio\v15.0\Web\Transform -->
<Target Name="AspNetPreCompile" DependsOnTargets="$(AspNetPreCompileDependsOn)" Condition="'$(AspNetPreCompile)' != 'false'">
<PropertyGroup Condition="'$(UseMetabasePath)' == 'true'" >
<_PreAspnetCompileMergeSingleTargetFolderFullPath></_PreAspnetCompileMergeSingleTargetFolderFullPath>
<_AspNetCompilerVirtualPath></_AspNetCompilerVirtualPath>
</PropertyGroup>
<PropertyGroup Condition="'$(UseMetabasePath)' != 'true'" >
<_PreAspnetCompileMergeSingleTargetFolderFullPath>$([System.IO.Path]::GetFullPath($(_PreAspnetCompileMergeSingleTargetFolder)))</_PreAspnetCompileMergeSingleTargetFolderFullPath>
</PropertyGroup>
<PropertyGroup>
<_PostAspnetCompileMergeSingleTargetFolderFullPath>$([System.IO.Path]::GetFullPath($(_PostAspnetCompileMergeSingleTargetFolder)))</_PostAspnetCompileMergeSingleTargetFolderFullPath>
</PropertyGroup>
<!-- Modification #1. -->
<Exec Command="attrib +H "$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl"" />
<AspNetCompiler
PhysicalPath="$(_PreAspnetCompileMergeSingleTargetFolderFullPath)"
TargetPath="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)"
VirtualPath="$(_AspNetCompilerVirtualPath)"
Force="$(_AspNetCompilerForce)"
Debug="$(DebugSymbols)"
Updateable="$(EnableUpdateable)"
KeyFile="$(_AspNetCompileMergeKeyFile)"
KeyContainer="$(_AspNetCompileMergeKeyContainer)"
DelaySign="$(DelaySign)"
AllowPartiallyTrustedCallers="$(AllowPartiallyTrustedCallers)"
FixedNames="$(_AspNetCompilerFixedNames)"
Clean="$(Clean)"
MetabasePath="$(_AspNetCompilerMetabasePath)"
ToolPath="$(AspnetCompilerPath)"
/>
<!-- Modification #2. -->
<Exec Command="attrib -H "$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl"" />
<!--
Removing APP_DATA is done here so that the output groups reflect the fact that App_data is
not present
-->
<RemoveDir Condition="'$(DeleteAppDataFolder)' == 'true' And Exists('$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\App_Data')"
Directories="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\App_Data" />
<CollectFilesinFolder Condition="'$(UseMerge)' != 'true'"
RootPath="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)" >
<Output TaskParameter="Result" ItemName="_AspnetCompileMergePrecompiledOutputNoMetadata" />
</CollectFilesinFolder>
<ItemGroup Condition="'$(UseMerge)' != 'true'">
<FileWrites Include="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\**"/>
</ItemGroup>
<!-- Modification #3. -->
<ItemGroup>
<Perl Include="$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl\**\*.*" />
</ItemGroup>
<!-- Modification #4. -->
<Copy SourceFiles="#(Perl)" DestinationFolder="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\bin\perl\%(RecursiveDir)"></Copy>
</Target>
DO NOT modify the original .targets file, copy this into your .csproj file as a child to the <project> node.
Key takeaways:
Use Exec command to attrib +H Directory before running aspnet_compiler.exe via the AspNetCompiler task, and attrib -H Directory afterwards.
Create an ItemGroup to suck in all the files that still need to be copied.
Run the Copy task, utilizing that ItemGroup to put the files where they need to be in order for the rest of the publish task to include them. We get to use all of the variables that Microsoft made when authoring this Task, so we can use those here too.
Pro to modifying the original task: very little changes about the normal behavior, so it should still just work.
Possible con to modifying the original task: Microsoft might change this task in the future, making our copy out of date.
If you don't have my weird requirements, the simpler solution to hiding a folder is as follows:
<Target Name="Test" BeforeTargets="AspNetPreCompile">
<Exec Command="attrib +H Directory" />
</Target>
<Target Name="Test" AfterTargets="AspNetPreCompile">
<Exec Command="attrib -H Directory" />
</Target>
Answer inspired by the comment twamley made in Arthur Nunes answer.
In my case it was the node_modules folder. I made this change in my csproj file for my .net 4.8 app to fix it.
This will just add the hidden attribute to the node_modules folder and then unhide it after the Razor pages are compiled.
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<Exec Command="attrib +H "$(ProjectDir)node_modules"" />
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
<Exec Command="attrib -H "$(ProjectDir)node_modules"" />
</Target>
Try doing the folowing.
Setting RequireTargetFramework to 4.0.
Link:ASPNETCOMPILER error ASPCONFIG: Could not load file or assembly 'Microsoft.VisualBasic.Activities.Compiler' or one of its dependencies
In my case the issue was that the web config of a parent solution (root level project) in IIS had this in it's web config (by mistake, not sure how it got there). Took a long time to track down, because nothing I could do in my solution/project could affect it in any way.
So might be worth checking the web.config of all that might be involved.
For me this error was showing when my website's physical path was invalid in IIS. To resolve that right click on website (Manage website -> Advanced settings -> Physical Path).
In my case, on a new machine, installed VS2017 and opened an asp.net core 1.1 web application from source control. The error showed up. I installed node.js and the project compiled.
My solution to this error was a combination of two pre-existing answers on this page. I had a .h file in my web project directory that had not caused a problem until I tried to build the project on a VS 2017 machine.
In my case I simply zipped it up, but the upshot seems to be that you can no longer keep unrelated code files in the web directory or VS will trip up trying to compile them.
I solved it with deleting node modules folder then running npm i from git bash and not from VS2019 built in terminal.
Copy cppprovider.dll from Visual Studio 2015 installation path to:
C:\Program Files (x86)\Microsoft Visual Studio
11.0\Common7\IDE\PublicAssemblies
An easy way to solve is that to reference the CppCodeProvider.dll.
It may locate at
C:\Program Files (x86)\Microsoft Visual Studio{version}\{edition}\Common7\IDE\PublicAssemblies
For example:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\PublicAssemblies\CppCodeProvider.dll
It will be in the bin folder.
I moved my solution from VS2019 to VS2022 and was having this error when I tried to publish solution. This is how I made the error disappear.
Right-click on References>> Add References
Then Search for Microsoft.VisualC
tick Microsoft.VisualC and Microsoft.VisualC.VSCodeProvider
click ok.
Error gone!
I installed VS2019 on a new laptop but kept getting the same error message as the OP. (it still worked fine on my desktop PC).
After a day or so of trying every answer on here and Google, and getting no joy, I tried using, from the toolbar, Build -> Publish Web App, which built my website into the Publish folder ok.
I then took this 'Publish' folder and copied it to a new place on my C:drive.
Then after closings and re-opening VS2019, started with "continue without code".
Then File -> Open -> Web Site... select my 'Publish' folder, and hooray I can now build and debug my project locally.
The issue was occurring for me when I was building a web project with node_modules. I fixed the error by enabling Desktop development with C++ option in my Visual Studio installer.
Source: https://developercommunity.visualstudio.com/t/cppcodeprovider-not-properly-installed-with-vs2017/240322#T-N333161
In Visual Studio 2017 CppCodeProvider.dll is getting shipped with “Desktop development with C++” as a result installing “Desktop development with C++” should resolve the issue.

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.

aspnet_compiler looking for jsharp code provider on a C# mvc2 application

I am compiling an MVC2 application in Visual Studio 2010 on Windows 7 64-bit. I am running the following as a post-build event command:
aspnet_compiler.exe -v / -p \
It results in the following error:-
The CodeDom provider type "Microsoft.VJSharp.VJSharpCodeProvider, VJSharpCodeProvider, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be located
I have no J# in my solution. I've downloaded the J# 2.0 redistributable package Second Edition, but that didn't help.
The funny thing is, I ran this in a BRAND NEW MVC2 solution and got the same error! So it has nothing to do with my application.
What am I missing that's causing this error?
I have read many other posts that say you need to install the redistributable, add a reference in web.config etc. but they didn't help.
Any ideas??
I had this happen today, and found a solution of sorts.
I'm using VS 2010 and an ASP.NET MVC 3 site, using Razor, running in IIS (not IIS Express or Cassini).
In my case this error cropped up in my .cshtml views. For any view I opened, the first #using line was underscored with the error:
C:\PathToMyCode\PathToMyViews\Index.cshtml: ASP.NET runtime error: Could not load file or assembly 'VJSharpCodeProvider, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A)
There were also bizarre errors throughout the page, such as ambiguous references between two assemblies with the same name (e.g. a supposedly conflict between "System.Web.Helpers" and "System.Web.Helpers").
The cause: I was running the web site under a user account that didn't have sufficient permissions. The account had the IIS_IUSRS role, but apparently there's some other role or access it needs to make this work, or it may need access to a particular folder it couldn't get to.
Unfortunately, I don't know what it is, and I'm not excited about the idea of wasting hours to figure it out after I already spent way too much time trying to figure out how this happened in the first place.
But giving that user the Administrators role resolved the error.
I realize this isn't an ideal solution, but I hope at least it gets some people unstuck. If anyone figures out exactly what permissions are necessary to prevent this error, comment below and perhaps we can narrow it down.
#Adrian - I had this problem today and fixed it nearly straight away, it was trying to compile J# in a C# project, weird error. But the problem was I copied a .java file into my project folder and the issue occured. Once I removed that, it all compiled again fine.
#Kyralessa : I was having the exact same error. Adding the Administrators role to the user under which the website was running "fixed" the problem but as you said it is not an ideal solution.
So I was fiddling around with IIS settings and under the Basic settings of the website I switched to "Application user (pass-through authentication)" and the problem disappeared. The app pool still runs under the same (non-admin) user so there is no security issue.
Try installing one of the packages below:
32-bit: http://www.microsoft.com/download/en/details.aspx?id=18084
64-bit: http://www.microsoft.com/download/en/confirmation.aspx?id=15468
This got me past the error when none of the other solutions would work.
I was having this same error when I set MvcBuildViews property in the csproj to true. After much research and trial/error, I learned that the problem was because our site had .java files in the site's structure. These java files were not a part of the solution, simply loose files. The Aspnetcompiler task runs from the project root, so it finds all kinds of issues like duplicate web.configs and *.java files.
To deal with this, I created the following target in the MVC project file I was trying to debug:
<Target Name="MvcBuildViews" AfterTargets="Build" Condition="'$(MvcBuildViews)'=='true'">
<!-- This task performs compilation of the CSHTML files in the web structure
and will generate compiler errors if there are issues in the views, such as missing
resource strings, broken class locations, etc.
Due to an issue with the AspNetCompiler task identifing .java files as candidates for
compilation, we will temporarily rename all of the java files in the project to .xyz
so they are skipped by aspnet compiler. Then we rename them back.
Extra web.configs also cause an error, so those are temporarily moved. -->
<CreateItem Include="$(ProjectDir)**\*.java">
<Output TaskParameter="Include" ItemName="JavaFolderA"/>
</CreateItem>
<CreateItem Include="$(ProjectDir)obj\**\web.config">
<Output TaskParameter="Include" ItemName="ExtraWebConfigsA"/>
</CreateItem>
<Move SourceFiles="#(JavaFolderA)" DestinationFiles="#(JavaFolderA->'$(ProjectDir)%(RecursiveDir)%(FileName).xyz')"/>
<Move SourceFiles="#(ExtraWebConfigsA)" DestinationFiles="#(ExtraWebConfigsA->'$(ProjectDir)%(RecursiveDir)%(FileName).ccc')"/>
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
<CreateItem Include="$(ProjectDir)**\*.xyz">
<Output TaskParameter="Include" ItemName="JavaFolderB"/>
</CreateItem>
<CreateItem Include="$(ProjectDir)obj\**\web.ccc">
<Output TaskParameter="Include" ItemName="ExtraWebConfigsB"/>
</CreateItem>
<Move SourceFiles="#(JavaFolderB)" DestinationFiles="#(JavaFolderB->'$(ProjectDir)%(RecursiveDir)%(FileName).java')"/>
<Move SourceFiles="#(ExtraWebConfigsB)" DestinationFiles="#(ExtraWebConfigsB->'$(ProjectDir)%(RecursiveDir)%(FileName).config')"/>
</Target>
Hope this saves someone the 3 hours it took me to figure out...
Update:
Because this does add more time to the build, you may choose to add to the condition at the top to only perform this check during Release style builds:
<Target Name="MvcBuildViews" AfterTargets="Build" Condition="'$(MvcBuildViews)'=='true' AND '$(Configuration)' == 'Release'">

Categories

Resources