Cultureinfo not applied after build on build server - c#

Ok, this one is really weird.
We have a main project. Lets call it 'MyApplication'.
To make it multilingual, we added a new project in the solution called 'MyApplication.Languages' which contains all the resx files in different languages.
In our Main() we have the following code to switch the CultureInfo:
Thread.CurrentThread.CurrentUICulture = new CultureInfo("nl-NL");
Obviously, we have a resx.nl-NL file and we are referencing this file in our code.
This works perfectly when we execute the code locally, whether it is in Debug or Release mode.
But when the application is build on the build server, the language is never anything other then English. Even when we explicitly set it to "nl-NL" like in the example above.
Does anyone have any idea what could be the issue here?

After much trial and error we found out that the multilingual files where not stored in 1 assembly, but in several (one for each language that is configured).
These assemblies are stored in separate folders. In our case en and nl
During the copy from the artifacts directory, we did not take this into account and therefore, there was no other language then the default English
Hope this helps anyone out there

Related

C# localization different in the IDE and real life

My code is prepared for English and German. I have the statement
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE");
or
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
before the
InitializeComponent() statement;
It works fine with the initial window including the menu-items coming up in German or English. But only when compiled and run within the IDE.
When I publish the project as a ClickOnce-programm, install it as that and run it, then the initial window comes up with German menu-items ALL THE TIME!
Windows 7, VS 2013 Community, .NET 4.0,
My guess is that the English resource files were not copied as part of the published package.
Make sure that the resource files are part of the project.
Click on the file and look at the properties. Under the advanced properties, you'll see "Build Action" and it should be set to "Content" (looking at one of my projects now and that's what it says).
Thanks for the tip. Yes, you are right! The "en..."-files weren't published. I checked it thru ProjectName\Publish\Application-Files. And the two "en.." - resources were "excluded". (I don't know when that happened because it worked fine before). Anyway, the files are now "included" and everything works great.
Harry

Renamed C# project, can't get rid of the old dll

I am writing a Web API application. To begin with, I created the project and gave it a short name, like pnlink.csproj which compiled into pnlink.dll - all OK so far.
Then at one point I decided to rename the project and dll into something a bit more fitting the rest of my naming scheme and the project file became pnlink.Rest.Api.csproj. Also, Assembly Name and Default Namespace were changed accordingly.
Today I noticed that the bin directory contains the old pnlink.dll (which wasn't touched in several months, according to the filesystem information). The new pnlink.Rest.Api.dll is also present and is newly touched. I removed the old pnlink.dll and saw that the application is not able to run any more. It compiles fine, but in runtime I get the 404 message when I navigate to the root (instead of going to the default controller (which only produces some welcome message)). Other navigation paths work fine, actually.
I can find no references to pnlink.csproj or pnlink.dll or anything like that anywhere in the application code.
I of course tried to delete all compilation results (obj, bin) and compile everything from scratch, all to no avail.
Any ideas are much appreciated!
Oh, I've got it... What an idiotic situation.
The new assembly's HomeController was incorrectly inherited from ApiController and did not produce the right output on the root URL. Somehow when the old dll was in the bin folder, it managed to hook up to the handling of the request and handle the root properly.
Sorry about confusing everybody and thank you for the input!

MFC / C#.NET mixed mode localization (multi language / multilingual application)

we have a complex application here which is written in MFC and C# and running in mixed-mode. We're now trying to set up a multi-lingual version of this application. So I created English resource files (in the .NET part) for every existing resource file and translated all necessary strings. E. g.: MyResource.resx and MyResource.en.resx. Original language is German.
Now if I start the solution containing only the .NET-Projects with the Thread.CurrentThread.CurrentUICulture set to 'en-US' all the dialogs and texts appear in English as expected. The MFC part (the compiled code in the .exe file) is translated with a tool called Lingobit which replaces the strings in that .exe file and it works fine. So far, so good.
But when it comes to start the full mixed-mode application all the English resource files of the .NET part are ignored and it falls back to the German ones.
I additionally tried to use Lingobit to translate the .NET-DLLs. Lingobit creates a separate mylib.resource.dll of my original mylib.dll which seems to be ignored, too.
I'm running out of ideas here how to create an English version of this application. Any suggestion how to make my mixed-mode application use the English resource files?
Thanks in advance.
The solution itself was quite simple, but it took me a while to find it. If you compile the .Net project Visual Studio creates a "en"-Folder in your output folder (e. g.: bin/Debug/). This folder is not created with the compilation of the mixed mode version, so just copy it from your .Net output folder to your mixed mode output folder.
In addition I'll create a little script to copy it to the needed location after the build.
Have a good one everybody.

Project management (sort of)

We have a big project(solution) with several smaller projects using some common assemblies (no GAC). Every time a project is changed and has to be tested, all files in the solution must be deployed in a testing location, separate from the main branch.
I would like to deploy only the files that have changed and use the ones not changed from the main branch. Something like this:
[MainBranchFolder]
File1.dll
File2.dll
File3.dll
.....
[Branch1 subfolder]
File2.dll
So, Branch1 contains only File2.dll. When the programs runs, it will look for any dlls in current folder and, if not found, will look into Parent folder.
I know a solution for this problem that requires some code changes but I wonder if something like this can be achieved using configuration only
[Edit] I see several ppl suggested some source code management. However this is not a source code issue, it's a binary code issue. MainBranch in my example is not source code, is a folder with all the compiled assemblies (exe and dll) in my projects
It sounds like you could use some Software Configuration Management (SCM)!
There are many choices out there and a quick Google search will reveal plenty. My preference is definately GIT.
Check out: http://git-scm.com/
with the Team Foundataion Server, you can do that with the customized build.
All of the responses seem to have a Code Versioning theme, which I'm seeing is not what you're looking for.
I ran into a different, but potentially similar situation:
3 Applications, each requires the same librar(ies).
Publishing the primary application requires the other 2 to be updated.
GAC was not an option (don't ask!)
Solution 1: I know where it is, just give me the damn thing!
(Which also let me store all kinds of useful common settings dictated by the master installed program.)
My solution was to maintain a known registry key:
Part 1: The registry Entry
HKLM\Software\FoobarInternational\CommonLibrary1 [String]
In CommonLibrary1 I stored the path to the common DLL's.
Part 2: The common "find my dll" library
Think plugin architecture - it looks in current dir for dll, and if fails, checks the the provided registry key for correct location.
Solution 2: Taking a walk
In a similar manner to solution 1, the library starts in its current directory, looks for the DLL, and if its not found, checks 1 directory higher.
Here are a few links to help you with each:
Getting the Parent Directory
Using the assembly once you find it
Talking to the registry
If you want the current directory of the code running (note: if the code is in a separate dll, you will get the location of THAT dll!)
Assembly.GetExecutingAssembly().Location
OR depending on what you need . .
string directoryName = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;

Visual Studio Long wait before Starting to build

We have a moderately sized solution, with about 20 projects. In one of them I have my business entities. On compiling any project, visual studio waits and hangs about one and a half minutes on this BusinessEntities project.
I tried our solution in SharpDevelop and it compiles our complete solution, in 18 seconds. Similar timing with MSBuild.
My guess is that VS is trying to find out if the project needs a compile, but this process is about 15 times slower than actually performing the compile!!
I can't switch to the great sharpdevelop, it lacks some small, but essential requirements for our debugging scenarios.
Can I prevent VS from checking this project, And have it compile the projects without such a check, just like sharpdevelop?
I already know about unchecking projects in configuration management to prevent building some projects, but my developers will forget they need to compile this project after updating to latest sources and they face problems that seem strange to them.
Edit: Interesting results of an investigation: The delay happens to one of the projects only. In configuration manager I unchecked all projects, then compiled each of them individually. All projects compile in a few seconds!! The point is this: if that special project is built directly, compiles in a few seconds, if it is being built (or skipped, because it is up-to-date) as a result of building another project that depends on it, VS hangs for about a minute and half, and then decides to compile it (or skip it). My conclusion: Visual studio is checking to know if any files are changed, but for some reasons, for this special project it is extremely inefficient!!
I'd go to Tools -> Options -> Projects and Solutions -> Build and Run and then change the "MSBuild project build [output|build log] verbosity" to Diagnostic. At that level it will include timings which should help you track down the issue.
We had the same problem with an ASP.NET MVC web project running in Visual Studio 2013. We build the project and nothing happens for about a minute or so and then the output window shows that we are compiling.
Here's what fixed it... open the .csproj file in a text editor and set MvcBuildViews to false:
<MvcBuildViews>false</MvcBuildViews>
I had to use sysinternals process monitor to figure this out but it's clearly the cause for my situation. The site compiles in less than 5 seconds now and previously took over a minute. During that minute the Asp.net compilation process was putting files and directories into the Temporary Asp.net Files folder.
Warning: If you set this, you'll no longer precompile your views so you will lose the ability to see syntax errors in your views at build time.
There is the possibility that you are suffering from VS inspecting other freshly built assemblies for the benefit of the currently compiling project.
When an assembly is built, VS will inspect the references of the target assembly, which if they are feshly built or new versions, may include actually loading them in a .Net domain, which bears all the burdens of loading an assembly as though you were going to run it. The build can get progressively slower as it rebuilds more and more projects. When one assembly becomes newer the others do a lot more work. This is one possible explanation for why building by itself, versus already built, versus building clean, all have seemingly relevantly differing results. Its really tht the others changed and not about the one being compiled.
VS will 'mark down' the last 'internal' build number of the referenced assembly and look to see if the referenced assembly actually changed as it rolls through its build process. If its not differnt, a ton of work gets skipped. And yes, there are internal assembly build numbers that you dont control. This is probalby not in any way due to the actual c# compiler or its work or anything post-compile, but pre-compile steps necessary for the most general cases.
There are several reference oriented settings you can play with, and depending on your dev, test, or deployments needs, the functional differences may be irrelevant, however may profoundly impact how VS behaves and how long it takes during build.
Go to the references of one of the projects in Solution Explorer:
1) click on a reference
2) open the properties pane if its not (not the Property Pages or the Property Manager)
3) look at 'Copy Local', 'Embed Interop Types', 'Reference Output Assembly'; those may be very applicable and probably something good to know about regardless. I strongly suggest looking up what they do on MSDN. 'Reference Output Assembly' may or may not show in the list.
4) unload the project, and edit the .proj file in VS as text. look for the assembly reference in the XML and look for 'Private'. This means whether the assembly referenced is to be treated as though its going to be a private assembly from the referencing assemblies perspective, vs a shared one. Which is sort of a wordy way of saying, will that assembly be deployed as a unit with the other assemblies together. This is very important toward unburdening things. Background: http://msdn.microsoft.com/en-us/magazine/cc164080.aspx
So the basic idea here is that you want to configure all of these to be the least expensive, both during build and after deployment. If you are building them together, then for example you probably really don't need 'Copy Local'. Id hate to say more about how you should configure them without knowing more about your needs, but its a very fine thing to go read a few good paragraphs about each. This gets very tricky however, because you also influence whether VS will use the the stale old one when resolving before the referenced one is rebuilt. As a further example explaiing that its good to go read about these, Copy Local can use the local copy, even though its stale, so having this set can be double bad. Just remember the goal at the moment is to lower the burden of VS loading newly built assemblies jsut to compile the others.
Lastly, for now, I can easily say that hanging for only 1.5 mins is getting off very lucky. There are people with much much worse build times due to things like this ;)
Some troubleshooting idea's that have not been mentioned:
Clean solution?
Delete Obj and Bin folders plus the .suo file? FYI, neither Clean nor Rebuild will delete non-build files, eg files copied during a pre-build command.
Turn off VS scanning outside files. Options > tools > environment > document > detect when file is changed outside the environment?
Rollback SVN history to confirm when it started to occur? What changed? If the project file on day 1 takes the same time, recreate the project, add all the files and build.
Otherwise could you please run Process Monitor and let us know what Visual Studio is doing in the prep-build stage?
Sounds silly, but remove all breakpoints first. It sped up my pre-build checks massively - still don't know why though.
Based on the (limited) information provided one possibility is that there could be a pre-build action specified in the project file that is slow to compile.
Try disabling platform verification task as described here.
If your individual projects are compiling correctly then all you can do is change order of compilation by setting dependent projects explicitly in configuration.
Try to visualize your project dependency hierarchy and set dependent projects. For example, if your business entities project is referenced in each project, then in configuration of each project, this project must be selected as dependent.
When an explicit build order is not set, visual studio is analyzing projects to create an order of building project. Setting explicit dependent projects wiki make visual studio skip this step and use the order provided by you.
With such an extreme delay on a single project and no other avenue seeming to provide a reason I would attempt to build that specific project while running procmon from sysinternals and filter out all the success messages. You could probably also narrow it down to just the file system actions as well. From your description I might guess that the files are being locked by an external source like the event collection or workflow management process services.
Other things to consider would be whether or not this is a totally clean build machine or if it has been used to perhaps test the builds as well? If so, is there a chance that someone mapped an IIS application path to the project directly or registered it as a service location?
If you run procmon and see no obvious locks or conflicts I would create a totally new solution and project and copy the files over to see if that project also has the same delay. If it does have the same delay I would create a sample project of the same type but generic data (essentially empty) and see if that too is slow. If the new project with the same files builds fine you can then diff the directories to see what the variance is that causes the problem (perhaps a config or project setting).
For me, thoroughly disabling code analyzers helped per instructions here:
https://learn.microsoft.com/en-us/visualstudio/code-quality/disable-code-analysis?view=vs-2019#net-framework-projects.
I thought my code analyzers were already off, but adding the extra xml helped.
Thanks Kaleb's for the suggestion to set "MSBuild project build [output|build log] verbosity" to Diagnostic. The first message took more than 10 seconds to display:
Property reassignment: $(Features)=";flow-analysis;flow-analysis" (previous value: ";flow-analysis") at C:\myProjectDirectory\packages\Microsoft.NetFramework.Analyzers.2.9.3\build\Microsoft.NetFramework.Analyzers.props (32,5)
Which led me to the code analyzers.
Just in case someone else trips into this issue:
In my case the delay was being caused by an invalid path entry in "additional include directories" that referred to a non accessible UNC location.
Once this was corrected, the delay disappeared.

Categories

Resources