I have an already localized WinForms program with four languages. It consists of one EXE and several DLL's. All C# projects are contained in one solution. The satellite assemblies are generated automatically from localized resource files, e.g. Strings.fr.resx or MyForm.it.resx.
The source code is stored in Subversion, the centralized (build server) generated binaries in Artifactory. Maven is used for dependency resolution. The corresponding source code for the binaries (snapshot) is also stored in Artifactory. So, both binaries (DLL, EXE) and corresponding source code can be referenced from other projects.
Now, I want to add an additional language to the program without recompilation. The original binaries must not be touched.
The idea is to create an additional solution that depends (Maven) on the original program version. So, I get the binaries and source code. Then I can create tool projects for each original project to create the satellite assemblies, e.g. using a batch file. That will work for projects with localizable text and other things in resource files.
But what about Controls and Forms. Different languages may have different resulting control layouts, line breaks, position changes, sizes etc. It is not only text translation. So, the WinForms designer would be very helpful. Does anybody know a good way to create satellite assemblies containing controls?
Additional tools (e.g. Sisulizer) are not possible. The original binaries are strong named and the key is available only on the build servers. So, the new satellite assembly must be strong named with that key, too.
This is how I do by localized builds. I use a localization tool (Soluling) that can read the Windows Forms EXE. First, I use the GUI version of the localization tool to create a localization project file (XML file) that I include in my repo. Then in the build process on the build server, uses the command-line version of the localization tool to scan the EXE file. This scan process extracts the new or changed strings, and the build process sends them for translations. After that, the build process builds the satellite assembly files. The output artifacts of the build process are the main assembly (.exe), some other assemblies (.dll), and satellite assemblies (.resources.dll) for the main and other assemblies. This is all done by the command line version of the localization tool as part of the normal build process.
In your case, you don't want to rebuild the EXE. That is fine. You would only use the satellite build part of the build process.
In general, I use three kinds of build processes (depending on the project)
1) Local
I install the command-line version of the localization tool locally on my machine and call it from PowerShell or Bat file.
2) Own build server/agent
Same as above, but a task of the build pipeline calls the command-line version of the localization tool.
3) Cloud based build
This is a bit trickier because I cannot install my own software on a cloud build like Azure. I do this by including the command line version of the localization tool (single EXE, SoluMake.exe) into my repo. During the build, this EXE is then available in the Azure DevOps build machine and the build can use is just like in case #1 and #2.
Related
I've never done this before, because I've never needed to until now, but I need to build my windows forms application to a standalone executable. I'm aware of both Build and Publish options within Visual Studio however none do what I need. Build doesn't allow you to move the executable it makes, and Publish makes a setup to install on the computer.
My goal is for the application to open without installation.
In the /bin/Debug/ directory made by the Build option, I have an executable, four dlls required, two .pdb file, and few other standard files (.manifest, .config, etc.). I was hoping to get any requirements built inside the executable.
How do I do this? All my searching has taken me to bunch of tutorials on how to make applications from scratch and how to use the csc.exe console command.
You can merge the separate assemblies to make it one single executable.
There is a tool called ILMerge that is capable of doing that for you. Another method is described in this post, which also works for WPF.
What you want is to embed the .DLLs in the .exe file so you can move it freely and only need the .exe , you just didn't search for the right thing,
here is what you are looking for :
It is possible to merge .NET executables with libraries. There are multiple tools available to get the job done:
ILMerge is a utility that can be used to merge multiple .NET assemblies into a single assembly.
Mono mkbundle, packages an exe and all assemblies with libmono into a single binary package.
IL-Repack is a FLOSS alterantive to ILMerge, with some additional features.
See : Embedding DLLs in a compiled executable
this is indeed a duplicate but i don't have the reputation to mark it as so.
I can't seem to find the solution I'm looking for in the similar questions, but that might be because of my lack of searching skills.
Either way, I have a using System.Runtime.InteropServices; in my C# project which I use to unzip a downloaded .zip file.
My problem arises from the following: I hate installers... Thus I need a way to include the Interop.Shell32.dll file into the .exe which is located in the project's \bin\Debug folder.
Thus avoiding the need for an installer which adds the Interop.Shell32.dll into the program's path and avoiding the need for an extra file download along with the .exe if I don't use an installer.
What would be the best/most efficient way for me to do so? (Preferably without having to include a load of extra code into the program)
There are several useful tools; I'm not exactly sure what is being sought, so I will provide a small listing of tools/approaches that I use.
ILMerge for merging multiple managed assemblies such as the project output and external assemblies/PIAs. Make sure the PIA/assembly being merged is allowed to be distributable as such or see #3.
Embedded resources for including "external data" including non-managed DLLs which might be external requirements for managed assemblies. These non-managed DLLs/COM libraries can be bound/loaded at runtime after extraction.
dotNetInstaller for making a unified launcher/installer (it is a bootstrap and can provide embedded resources). This can be used in conjunction with a normal MSI (VS Setup Project) installer to handle prerequisites such as installing official distributable packages or it could simply be used to launch the executable (no "installer" except those for prerequisites).
You can use ILMerge. Taken from the Microsoft webpage:
ILMerge is a utility for merging multiple .NET assemblies into a single .NET assembly. It works on executables and DLLs alike and comes with several options for controlling the processing and format of the output.
I have a large solution currently under VS2010, with lots of projects and dependencies. Some of them are installed to the GAC, some of them are just included from a "lib" folder. I need to build one of my projects (specifically a WinForms app) to able to run on any, non-development computers without any installation process (except for the .NET runtime of course), just as portable apps do.
For this to work, I need to have all of the referenced DLLs and their whole dependency tree in the output folder of my EXE. I can do it for exemple by marking the dependencies to "Copy local" in the properties window, but that works only for the direct references of the EXE project, so it's far not enough. Another way is to make a setup project, but my client and also I want to avoid that (in the final version I'm gonna use ClickOnce). Of course I can always do it purely by hand, gathering all the DLLs manually, but that's quite a nightmare.
Is there some tool, msbuild trick, command-line option, whatever hack to force Visual Studio to gather the whole dependency tree of my EXE during build, and copy them to the output folder? So that I could just ZIP everything together and send to my client.
I actually chose a somewhat "middle" solution, the following way.
I created a "dummy" setup project, not caring about setting anything but adding the project outputs (primary output, localized resources, contents, etc.). It was a 2 minute task this way.
I built the setup project, and got the MSI file as the output.
I've extracted the contents of the MSI file to a specific folder, called "MyAppPortable" for example. I found the solution here. The command-line command is
msiexec /a "absolute_path_to_my_MSI_output" /qb TARGETDIR="absolute_path_to_my_desired_output_folder"
I got the full application with all of its resolved dependencies (except for late-binding dependencies, but I took care of them manually, by adding them as references to my projects). I could ZIP the whole folder, put it on another computer, and voila, everything worked fine.
Basically, using Visual Studio, you can set all of your Solution's Projects to build into the same Output folder and use this folder as your Windows Form application folder (where the application EXE will reside).
By doing this, you will coordinate all of the possible assemblies references that your app is depend on.
In VS 2012, right-click on a Project => Properties => Select Build (left pane) => Set your Output path:
I would select a a solution-level folder as the Output path.
And if it's prohibited to perform such a modification at your workplace so I would suggest you to use dependency analysis tools like the following in order to interrogate and gather the appropriate assemblies that your app is depend on and will require at run-time:
Dependency Walker
NDepend
Red-Gate Reflector
Update:
Using the above mentioned tools will not yields assemblies references which are late-bounded (at run-time), for this case you may use: Fusion (the Assembly Binding Log Viewer)
Check out the Fody/Costura recommendation from this question:
Embedding DLLs in a compiled executable
It's great! I just tried it out for a similar need and in less then a few minutes I had a completely portable (except the .Net framework) exe that I could easily give to co-workers.
So I made a C# project in visual studio with 3 class library projects. Everything works fine when debugging but When I try to deploy. Database and Program installs just fine but when I try to open the Application, I get an Assembly or File not Found Exception. The DLL he can't find is a class library in my project.
On the File System Editor, VS automatically detected the dependencies and included the 3 dll files in to application directory. I tried excluding these dll's and just adding the class library projects's primary output's (Same dll) but still the same error.
I used a Custom Installer class for creating my database on installation. But I don't think that is relevant.
If you have verified that your 3 assemblies are indeed deployed to your destination folder,
it could very well be an another dependency that you have not included in your setup project.
Please double check that you indeed have the right number of assemblies included.
You can also right click the setup project and refresh dependencies.
Have you checked that dependencies in the setup project aren't excluded (by mistake)?
Furthermore, it may also be a .NET profile issue. Do you depend on assemblies that are only available in the full .NET profile, and your destination only has the client profile installed?
In worst case, run the SysInternals process monitor and that way figure out which assembly is missing.
you need to include all dll's that are not part of the .net framework with your deployable. Your custom installer will copy these files to the location of the executable on install.
i usually create a folder called /deploy and copy all my needed dlls in there. I also change my projects settings to output to the /deploy-directory (instead of bin/). after you build, this directory will contain all dll's and other resources needed to run the application.
In VS, I've only tested code and debugged it, but never actually prepared anything for a finalized program or release. Some of the programs I've downloaded have had dlls that need to be in the folder they're in, and I've had programs that come as just one .exe. Is there a way to compile all the files into one application and not have external dlls? Is this bad programming practice for some reason? How do I compile my VS program into one executable file?
I know this is quite an obvious question, which is why I can't really find an answer, because it would be too obvious to write any kind of tutorial on it.
With a managed language like C# or VB.NET, ILMerge is a utility that you can use.
ILMerge is a utility for merging multiple .NET assemblies into a single .NET assembly. It works on executables and DLLs alike and comes with several options for controlling the processing and format of the output.
If the question is just around getting VisualStudio to build executable programs, it does it every time you run them within it. If you are using all of the default settings, open your project folder and look for a /bin directory. Underneath it, there is a /debug and a /release directory. If you build your program in debug mode, look in the /debug directory, if you build it in release mode, look in the release directory. VS will put everything that your program needs within that directory. You can copy all of those files to another machine that has the .Net runtime installed and it should run.
If the question is more about combining multiple dlls into a single exe, actually, there is a tutorial on it at CodePlex:
As you know, traditional linking of object code is no longer necessary
in .NET. A .NET program will usually consist of multiple parts. A
typical .NET application consists of an executable assembly, a few
assemblies in the program directory, and a few assemblies in the
global assembly cache. When the program is run, the runtime combines
all these parts to a program. Linking at compile time is no longer
necessary.
But sometimes, it is nevertheless useful to combine all parts a
program needs to execute into a single assembly. For example, you
might want to simplify the deployment of your application by combining
the program, all required libraries, and all resources, into a single
.exe file.
http://www.codeproject.com/KB/dotnet/mergingassemblies.aspx
Lastly, if the question is about building an installer for broad distribution, Jan Willem B has a sample for WIX: Using WIX to create an installer: quickstart tutorial
Yes, you can use ILMerge for embedding managed .Net DLLs! Example here.