In my WinForms app, if I set an icon for my app and an icon for my Form, the icon appears twice in my executable. Is it possible to avoid this?
(This question has been asked before, here, but the answers didn't seem to solve the problem. vanmelle's answer appears to extract only one icon (e.g., 16x16), Sunlight's answer extracts only the 32x32, and lc's answer doesn't solve the problem: there is still a duplicated icon in the executable.)
If it's not possible to accomplish this task, why is this? What is it about using the same icon for an executable and a Form that's so hard in WinForms?
This is an inevitable consequence of running managed code on a completely unmanaged operating system. Windows Explorer only knows how to read unmanaged resources. You can see what they look like, use File + Open + File in Visual Studio and select your .exe. You'll typically see three resource groups listed there:
RT_MANIFEST, contains the manifest that tells Windows that your program is Vista aware
Version, contains the file version resource with values derived from your AssemblyInfo.cs file. You see its content when you use Properties + Details tab in Explorer. Note how the super important [AssemblyVersion] isn't visible in Vista and up
Icon, contains the icon you added.
This unmanaged resource data is separate from the managed resources you added. Managed resources are compiled into the assembly manifest. Unmanaged resources are stored in the .rsrc section of the image file. You can override the auto-generated version with the /win32res command line option. Which requires a .res file, a binary file that is generated from a .rc resource script by the rc.exe resource compiler. An age old Windows SDK tool.
This may change some day, the super-secret Midori project is a rumored to focus on a managed operating system. For now, we'll have to make do with the glue.
Related
We have an enterprise management software that our clients deploy to a Windows network shared folder that several users from several terminal servers launch our program from.
What we're trying to achieve is a way to replace a DLL while the program is being used by the users to apply patches to fix bugs. At the moment weirdly enough, we are able to rename the old DLL to replace and apply the new one without any errors regarding the file being used.
This causes us two problems though:
the new DLL isn't loaded by the application if an instance of the same application is still using the old DLL (I think this is a case of https://en.wikipedia.org/wiki/DLL_Hell#Shared_in-memory_modules)
Exceptions are thrown left and right by applications that were run before the replacing because they were only loaded partially (lazy loading) and the when its time to go look into the file for the parts that are missing that are being requested the IL code doesn't match what's in memory anymore.
The bottom line of this is I think that we're doing something we are not supposed to: renaming something that is being used.
The possible solutions I found so far are two:
launch the application with a new AppDomain with shadow copying enabled, but this is not reliable as every client has its own environment and we might get unexpected permission errors or something of this nature
load assemblies without locking them. On this note we've looked into using reflection (which we actually use to some extent) but we're unsure on how to load through reflection assemblies that are already referenced in the project by the DLL (we have multiple DLL referecing other DLL that are referencing other DLL, etc....).
Do any of you have any other idea on how to overcome this problem safely? Or how to solve the last point I mentioned above with the reflection?
You could try a poor man's version of blue/green deployment.
Deploy your application files into two identical folders
\\SomeMachine\d$\MyApp\Green
\\SomeMachine\d$\MyApp\Blue
Now put a shortcut in the root folder like this:
\\SomeMachine\d$\MyApp\MyApp.lnk
Start out with the shortcut pointing at the .exe in the Green folder.
Tell your users to always launch the application using the shortcut only (rather than navigating into the Green or Blue folders and launching it there).
When it's time to update a DLL, follow this process:
Make the modification in the Blue folder
Do whatever testing is required in the Blue folder.
Once you're sure it works, update the MyApp.lnk shortcut to point at Blue.
Users who started their application before your update will continue to hit the Green folder until they exit the application. Anyone who starts the application anew will hit the Blue folder.
The next time you have to update a DLL, reverse the process. Make the modification in the Green folder, then update the shortcut to point at Green.
This way, you are always updating a folder that nobody is using, then making it available via the shortcut. As long as people exit the application every now and then, you should be able to deploy seamlessly.
If you don't want to use a .lnk file (e.g. your clients aren't on Windows), there are other similar ways to do this by either mapping a drive letter or using a symbolic link. But the principle remains the same.
The problem concerns Windows Forms.
I have no idea how to do it. I've tried following:
1) Add a Bitmap (CarControl.bmp) do the solution, then set BuildAction to Embedded Resource and add the ToolBoxBitmapAttribute like:
[ToolboxBitmap(typeof(CarControl),"CarControl")]
2) Going into Properties, then in Resources section I've added some images. Still doesn't work.
Can anybody help?
Naming is very important, otherwise it does not work.
[ToolboxBitmap(typeof(CarControl), "Resources.CarControl.png")]
Another important note:
If you open the solution of your CarControl you will always see the default gear icons for the controls of your actual build. But if you make a build and you add the controls of this (released) library to the Toolbox either by drag-and-dropping the dll or by Right click/Choose Items..., then the icon will appear.
If you did everything well, you will able to find the embedded resource in the compiled .dll when you open it with Reflector or other disassembler tool. The following example is from System.dll:
You should find a <DefaultNamespace of your project>.<Your resources folder>.CarControl.png here.
I accidentally deleted my project from visual studio2013/projects/myproject. I did a system restore and got the folder myproject. I am unable to see my code form or design form but I can run my application.
What d I have to do to be able to edit my code?
System Restore will only revert the computer's state (including system files, installed applications, Windows Registry, and system settings), not user files, and your sourcecode files are user files.
Since you can still run the application, then you must have a compiled executable somewhere. I suggest that you download dotPeek from JetBrains and then you can open your application up in it and decompile your assembly back into source code.
The code will be a bit ugly; your nice, meaningful variable names will probably be gone, but at least it's a starting point. Here's the link to dotPeek. https://www.jetbrains.com/decompiler/
BTW, I'm assuming that you've already tried to get the files back from the Recycle Bin.
We have successfully localized our windows-forms application. One form refuses to use the localized resources and is always shown with the embedded resources. I checked the following points:
The forms Localizable attribute is true
At runtime the UI-culture is set correctly
The satellite assembly is in the correct location
With SysInternals process explorer I verified that the process uses the satellite assembly
I opened the satellite assembly with IL-Spy and checked that it contains the translated resources
In the debugger I stepped into Microsofts ComponentResourceManager.ApplyResources Method for a button. It finds the text property but as the code is optimized I cannot see the really interesting things.
All other forms (different assemblies) appear with the correct language, only this one ...
I hope someone out there has a helpful idea.
Just stumbled upon the same issue but could solve it.
I just imported the localized resx files into the project. So the *.de.resx were part of the project, but the localized resources were not applied to all forms.
Referring to http://msdn.microsoft.com/library/y99d1cd3%28v=vs.110%29.aspx, the localized resource files should appear beneath the form (as a sub item).
So my solution was:
- go through all forms, change language from Default to German and back to Default.
- as a result, the *.de.resx files were listed as sub items of the forms
- then overwrite the just created *.de.resx files with the localized ones
Then it works for all forms. I have no idea, though, why it worked before for 3 forms out of 4.
What is the recommended way to add a new language to a Windows Forms application? Do I really need to click through all forms of my application for creating the empty resx files for the new language? Of course, I could edit the project file manually...
I'm trying to figure a way to specify my C# application to use an embedded resource (icon) as my application icon (the one displayed for taskbar, task switch, etc).
Yet, as I already embedded my icon in a resource, I can manage to use it in my forms but not with my application yet.
In fact, if someone could first tell me where I'll be able to set this (which file) by hand instead of using the VS2010 GUI to specify it, that'd be a great start!
Yet, my icon is available in these 2 ways :
{{Namespace}}.Properties.Resources.c_name.ico and in {{Namespace}}.Refs.c_name.ico (as a property of a public static class inside a class library).
Windows is an unmanaged operating system that doesn't know beans about managed resources. The only icon it can display is one that's embedded as an unmanaged resource. You can see what unmanaged resources look like in Visual Studio. Use File + Open + File and pick a .NET exe file (won't work in Express). A .NET program should have three of them, an icon, a manifest that declares the program compatible with UAC and a Version resource. This is all done automatically by the compiler, note for example how the Version resource properties match the attributes you set in AssemblyInfo.cs
The IDE makes it simple to set the icon for a program, you use Project + Properties, Application tab, Icon setting. Just pick the same .ico file as you embedded as a managed resource. Forget about trying to share, it cannot work by design.
Simply set
Icon=yourNamespace.Properties.Resources.yourEmbeddedIconName;
System.Drawing.Icon.FromHandle(Properties.Resources.EliminarNota.GetHicon());