I'm using Azure 2.7.
I created a C# cloud service that only contains a single worker role. After it's done, the solution contains
A ccproj
A csproj
Both are using the setting of AnyCPU.
I then added the PropertyGroup "Debug|x64" and "Release|x64" into both projects. Also changed the default to x64 for both. As a result, an x64 build.
However, whenever I select "publish" on the "ccproj", I notice that it always builds AnyCPU instead of x64. I cannot find how to force it to build x64 for packaging and deployment.
I then edited both proj file again, and removed the PropertyGroup for "Debug|AnyCPU" and "Release|AnyCPU". After I did this, and when I tried to build x64 again, I got error as:
C:\Program Files
(x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(723,5):
error : The OutputPath property is not set for project
'AzureWorkerRoleExample.ccproj'. Please check to make sure that you
have specified a valid combination of Configuration and Platform for
this project. Configuration='Release' Platform='AnyCPU'. This error
may also appear if some other project is trying to follow a
project-to-project reference to this project, this project has been
unloaded or is not included in the solution, and the referencing
project does not build using the same or an equivalent Configuration
or Platform.
I could not figure out how to work around this error.
Any idea on how to force VS to make a x64 build of cloud service and deploy it?
One workaround I found is that: keep AnyCPU property groups, but also put
<PlatformTarget>x64</PlatformTarget>
in the group. Thus the AnyCPU assembly are actually targetting to x64. But this sounds hacky.
Any idea?
Thanks a lot!
We're using SlowCheetah to do app.config transforms for a project. However, when trying to move the build process to Visual Studio Online, I can no longer build the solution. The build fails because the .dll.config file cannot be found. I believe this is caused by SlowCheetah.
Here's what we're using: SlowCheetah 2.5.10.6. As the build template I'm using the TfvcTemplate.12.xaml process. My NuGet version is 2.8 and Package Restore is enabled for the solution.
I've come across a few similar issues but most solutions apply to VS2012 or older versions of SlowCheetah and NuGet.
Update June 17
After looking more carefully at the log file generated by MSBuild, I found that the transform succeeds, and when my project is built, I see this line in the log: Copying file from "obj\Release\Assembly.Worker.csproj-sc.App.config" to "C:\a\bin\Assembly.Worker.dll.config".
However, I also have an Azure cloud service project, which is built next. Here's where the build fails.
This is what I find in the log: C:\a\src\ProjectFolder\Assembly.Azure\Assembly.Azure.ccproj(101,5): error MSB3030: Could not copy the file "..\Assembly.Worker\bin\Release\Assembly.Worker.dll.config" because it was not found.
So apparently SlowCheetah creates a transformed config file and saves it as a .csproj-sc.app.config file, while the Azure project looks for a normal app.config file. Interestingly, building the Azure project locally works fine.
In the end I fixed the problem by changing the SlowCheetah.Transforms.targets file in the Properties folder.
At line 157 I inserted the following code to copy the transformed file to the path that Azure expects:
<Copy Condition=" '$(_Sc_HasAppConfigTransform)'=='true' "
SourceFiles="$(__SC_IntermediateAppConfig)"
DestinationFiles="$(MSBuildProjectDirectory)\bin\Release\$(MSBuildProjectName).dll.config"
SkipUnchangedFiles="true" ContinueOnError="false" />
I've been extremely frustrated trying to deploy a C#/WPF application I've created that has some references to 3rd party DLLs. I created a folder in the project, called lib, where I placed all of these DLLs. In VS2012, I added the references by browsing to that folder, and selecting all the DLLs. Copy Local is set to true for all. Everything is fine when I build and run, but when I choose publish, and create a OneClick Installer, things aren't so smooth. During the publish wizard, I set it to install from disk, and set it to never check for updates. I take that folder, place it on a flash drive, plug it into another PC, run the setup, and it throws an Exception. I believe I know what is happening, but I cannot figure out how to package this in order to deploy it correctly.
One of my DLLs is a C# wrapper to a DLL that is designed for a C++ project. We'll say, Application requires DLL1 and DLL1 requires DLL2. DLL2 cannot be added as a reference in the project because is not a .NET DLL. DLL1 requires DLL2 to be in the same folder in order to pick it up. I'm using CefSharp which wraps the Chromium Embedded Framework.
I've tried placing the required DLLs for CefSharp.dll in the publish/Application Files directory, but it did not work. I noticed that all of the DLLs that are there from VS2012 have a .deploy extension on them, I even went and added that extension on to see if it was scanning for that to pick up, but it did not work either. This is my first time doing development and deployment for a Windows application and all of the tutorials on MSDN or blog posts I've read do not seem to cover this case, and I do not see any other options in the deployment manager to handle these types of cases.
If it helps, the Exception Code that is thrown is: CLR20r3
When I catch and display Exception, all of the info I am provided basically says CefSharp.dll or one of it's dependencies cannot be loaded. Which I've gotten before when DLL2 was not in the same folder as DLL1.
Can anyone provide help on how to deploy from VS2012 with a situation like this?
Thanks in advance!
Edit: Info Update
I was attempting to push a debug build version to a test machine without Visual Studio installed. When building for CefSharp or any other C++ Runtime DLL, it will look for all of the Debug versions of the DLL which are usually the same name, but with the letter 'd' added to the end. As mentioned below, the Debug version of the C++ Runtime is not redistributable. Not that you can't manually add those DLLs to your project and set them as Copy Always, but that's kind of a hack job. I started a new project from scratch, added all Release versions of the DLLs, built, and everything was fine.
I've been tearing my hair out trying to fix this very problem this morning and eventually found the solution. It seems you already know which DLLs etc. you need for CefSharp to work but I thought I would run through this in case anyone else is having the same problem. I have a C# WPF application and I'm using CefSharp as the web view. I'm using CefSharp v1 because I need the JavaScript -> C# bridge they provide which isn't yet implemented in v3. Here are the rough steps I went through in setting up the project (I'm using VS2013 but this will probably work in VS2012).
Installing CefSharp
Install CefSharp.Wpf through NuGet (I'm using v1.25.7)
That should put the relevant files in $(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef
Configuring Build
To get the CefSharp DLLs to copy to our build folders, right-click on your project, select Properties -> Build Events and enter the following in the "Post-build event command line":
xcopy "$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef*" "$(TargetDir)" /s /y /i
That should now copy all of the required DLLs from the cef folder as well as the devtools_resources.pak file and the locales folder plus its contents. I require them in my project as I need the chromium dev tools.
Double-check your project references contain CefSharp and CefSharp.Wpf. That should have been taken care of by NuGet.
Taking care of Visual C++ 2012 Runtime Files
I didn't want the user to have to download the whole Visual C++ 2012 Runtime Files as part of the deployment so through Visual Studio, add the folder Lib\Microsoft.VC110.CRT and add the 3 DLLs (msvcp110.dll, msvcr110.dll, vccorlib110.dll) from the following folder on your machine to the folder you just created in your project:
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\redist\x86\Microsoft.VC110.CRT
Select the 3 DLL files in Visual Studio, right-click -> properties. Make sure Build Action is set to "None" and Copy to Output Directory is set to "Do not copy". Now you need to add another post-build event to make sure these are copied properly (i.e. copied to the root so they sit alongside the CEF dlls and your project exe) for debug.
Right-click on your project, select Properties -> Build Events and enter the following in the "Post-build event command line" just after your other xcopy command for CEF:
xcopy "$(ProjectDir)Lib\Microsoft.VC110.CRT*.*" "$(TargetDir)" /s /y /i
At this point, everything should be building. To publish the app with ClickOnce, I need it to push all of the CEF DLLs out as well as ensuring the files/folders required for chromium dev tools are present. If you don't need the dev tools or all of the DLLs then you can tweak this accordingly.
Ensuring CEF and C++ runtime files are deployed with ClickOnce
Right click your project in Visual Studio and select "unload project".
Right click and select to edit the csproj file.
Before the closing </Project> tag add this
<ItemGroup>
<Content Include="$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(ProjectDir)Lib\Microsoft.VC110.CRT\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
That will add everything from the cef folder into the project and make sure the C++ binaries are copied to the root of the project on deployment. In my case for CEF, I'm using the \**\* syntax at the end of the Include and %(RecursiveDir) to ensure all of the files are copied as well as the locales folder with its contents and structure preserved. Having set <Visible>false</Visible> you won't see the items in the solution explorer.
Relax
Now if you publish your app, it should copy over all of the required files and folders.
You could try this which solved a similar issue for me:
Add the DLL's that are not .NET libraries to the solution as files:
Right click project > Add > Existing Item
Then set their build action to Content and "Copy to output directory" to "Copy Always".
That way the libraries will be included in the output directory.
Since you already tried manually adding the suspect dll and it still does not work, the next thing I would do is run fusion and see what it really is complaining about, in other words what exactly is the dependency that can not be loaded. Here is a good tutorial on how to hunt down these types of errors:
Back to Basics: Using Fusion Log Viewer to Debug Obscure Loader Errors
Maybe you can work it out from the https://github.com/Code52/DownmarkerWPF sources?
They have at least a working ClickOnce installer for their app embedding CefSharp. I know because that's the way it got installed on my machine!
update just saw in comments that it's the VC Redist that you say you are missing then Distributing the Visual C++ Runtime Libraries (MSVCRT) seems relevant.
Also I seem to remember something vaguely about that for "VCRedist reasons" you are not supposed to distribute debug versions of your application. Can't you just switch from a Debug to a Release version? With this I think you can either bundle the needed VCRedist files as suggested in the CefSharp FAQ or add VCRedist as a prerequisite in your installer. DownmarkerWPF does it with their WIX installer setup which you can find on a branch in their GitHub repo. Something similar is AFAIK possible with the VStudio bundled installer if that's what you use.
Thanks to Barrie's answer to this, it helped me greatly. I'm using his answer below, but updating it to work for the latest CEF using Visual Studio 2015.
NOTE: I am only building/targeting the x86 platform. You may need to change or include x64 in the copy commands below to suit your needs.
Installing CefSharp
Install CefSharp.Wpf through NuGet (I'm using v51.0.0)
NuGet Library After Install
That should put the relevant files in
$(SolutionDir)packages\CefSharp.Wpf.51.0.0\CefSharp (CefSharp.Wpf)
$(SolutionDir)packages\CefSharp.Common.51.0.0\CefSharp (CefSharp.Common)
$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF (Cef x86 redist)
$(SolutionDir)packages\cef.redist.x64.3.2704.1432\CEF (Cef x64 redist)
Configuring Build
To get the CefSharp DLLs to copy to our build folders... I don't believe this is necessary anymore with the later versions of CefSharp. I found that I didn't need any of the "Post-build event command-line" xcopy stuff to get Click-Once to ship it out. (And yes, DevTools works too!)
Taking care of Visual C++ 2012 Runtime Files
(Switched to VCR 2013) I didn't want the user to have to download the whole Visual C++ 2013 Runtime Files as part of the deployment, so through Visual Studio, add the folder lib\Microsoft.VC120.CRT and add the 3 DLLs (msvcp110.dll, msvcr110.dll, vccorlib110.dll) from the following folder on your machine to the folder you just created in your project:
C:\Windows\SysWOW64
(Didn't see them in C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist)
At this point, everything should be building. To publish the app with ClickOnce, we need it to push all of the CEF DLLs. You can tweak this accordingly...
Ensuring CEF and C++ runtime files are deployed with ClickOnce
Right click your project in Visual Studio and select "unload project".
Right click and select to edit the csproj file.
Before the closing tag add the following:
<!-- BEGIN: CUSTOM ITEM GROUP INCLUDES INTO THE PROJECT (SO CLICK-ONCE PUBLISHES THEM) -->
<ItemGroup>
<Content Include="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\**\*" Exclude="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\x86\**\*;$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\locales\**\*.pak">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\**\en-GB.*;$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\**\en-US.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\x86\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\CefSharp.Common.51.0.0\CefSharp\x86\**\CefSharp.BrowserSubprocess.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(ProjectDir)lib\Microsoft.VC120.CRT\**\*">
<Link>%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<!-- END: CUSTOM ITEM GROUP INCLUDES INTO THE PROJECT (SO CLICK-ONCE PUBLISHES THEM) -->
That will add everything from the cef folder into the project and make sure the C++ binaries are copied to the root of the project on deployment. Having set false you won't see the items in the solution explorer.
REMEMBER: I am only building/targeting the x86 platform. You may need to change or include x64 in the copy commands below to suit your needs.
Publish
Now if you publish your app, it should copy over all of the required files and folders.
(EXTRA INFO) Supporting Older Operating Systems Info Below
If you need to use CefSharp for older machines (XP & Vista), simply
install CefSharp.Wpf through NuGet using the older v47.0.0 version and change your .NET targeting to .NET 4.0 Client Profile.
Chromium ended support for XP and Vista in April 2016, CefSharp version 47 (or there abouts) still had support for it.
Another note on a problem and fix for XP:
There is a Chromium issue for XP deployments. Below is the article describing the fix followed by steps to deploy fix for JBCB.
Here's the link to the article:
https://bitbucket.org/chromiumembedded/cef/issues/1787
...in it you'll see a reference to download a "dbghelp.dll". Download and extract.
YOU CAN TAKE A POST-INSTALL APPROACH LIKE BELOW OR CHOOSE TO INCLUDE THE DLL ALONG WITH YOUR OTHER PUBLISHED FILES. I'M CHOOSING NOT TO DEPLOY THE EXTRA DLL AND ONLY DEPLOY ON XP MACHINES (WE ONLY HAVE FEW) MANUALLY.
Take these steps to fix deployment on an XP machine:
Install the CefSharp Browser on the XP machine (via Click-Once)
Copy the "dbghelp.dll"
Paste it in the local install directory on the XP machine (per the instructions in previous link: along side the "libcef.dll" file).
NOTE: For click-once installs, will be in a sub-folder under this location:
C:\Documents and Settings\<UserName>\Local Settings\Apps\2.0\<auto-gen ostificated ID>
Read very carefully the official list of CefSharp dependencies - there are a lot of them! You need to get them all into the ClickOnce bin folder somehow.
Here is how I solved it:
Before deploying, install the latest version of Visual C++ Redistributable. on each PC you are deploying to (using group policy or just manually).
Start with a blank test project.
Add project references to CefSharp, CefSharp.Core, etc.
Add each dependency into a single folder in the project directory to keep them organised (Files\CefSharp\).
Ensure all files are configured with Build Action: Content, and Copy to Output Dir: Copy always.
Make a function Initalise_CefSharpFiles() to copy the files/folders into the bin root folder (where CefSharp looks for them). For example, copy from: Bin\Files\CefSharp\* to: Bin\*.
And finally at run time, call Initalise_CefSharpFiles() once after the app loads, and before initialising CefSharp's settings.
I have a publish profile set up in a VS 2012 project. When I right click on the project in VS, select Publish and click on the [Publish] button, it publishes the project to the server using the settings provided in the Publish Profile.
When I use msbuild and the command line, with the following syntax:
msbuild.exe .\mvc.csproj /p:PublishProfile=DevServer
/p:DeployOnBuild=True /p:Password=MyPassword /p:AllowUntrustedCertificate=true
Then it builds the project, and gives me a message:
Package "mvc.zip" is successfully created as a single file at the following location: file:///c:/code/mvcsite/obj/Debug/Package
And then provides info on how to deploy the package.
How can I deploy from the command line? My ultimate goal is to run the deployment through TeamCity, and am right now trying to get my command line properties correct. However, the most that I can do from the command line right now is to create the deployment package, but not to run the actual deployment. How can I do both (preferably with one statement, to duplicate what happens in VS2012 when I deploy from there)?
Since you are building the .csproj you missed one important property
/p:VisualStudioVersion=11.0
This property was introduced in MSBuild 4.5 to facilitate project sharing between VS 2010 and VS 2012. A drawback; when building the .csproj you need to specify the value for this property. When building the solution file the value can be derived from the solution file version. Read more at my blog http://sedodream.com/2013/01/06/CommandLineWebProjectPublishing.aspx.
I'm using FxProtect .NET assembly obfuscator and I want to deploy the obfuscated .DLL that is in the package to Azure. How do I put back the DLL that I obfuscated back into the package? Do I unzip the .CSPKG that gets deployed to Azure and copy and paste the obfuscated DLL into the extracted .CSPKG folder and then zip it again to deploy?
If packaging from Visual Studio or MSBUILD, I'd like to suggest that you run a post-build event that obfuscates the generated .DLL's
I have a similar situation where I have a set of Azure packages that include references to assemblies which need to be obfuscated (they are part of a public SDK). I use Dotfuscator as the obfuscation tool, but the process will likely work for other vendors as well. Here is how I solved this issue:
In my case, the Azure package(s) contain a reference to a WebRole project. That WebRole project then contains project references to several other library projects that need to be obfuscated.
The build process takes three passes:
Build the solution, which contains all of the libraries and web projects. I have used the Visual Studio Configuration Manager to disable building of the Azure package projects, though that is not required.
Run the obfuscation tool to obfuscate the assemblies that require it.
Build and package just the Azure packages (via the Publish target) and instruct MSBuild not to also build any referenced projects.
That last part is key. If you don't tell MSBuild to not build referenced projects, it will rebuild them all, undoing the obfuscation. You do this by including the property BuildProjectReferences=false when building the packages.
To build the Azure packages from an MSBuild script, I use the following:
<!-- This should be run after Obfuscation to ensure the SDK assemblies included in the packages are obfuscated -->
<MSBuild Projects="..\Path\My.CloudService.ccproj" Targets="Publish" Properties="BuildProjectReferences=false;PublishDir=..\artifacts\MyCloudService" />