I'm looking for a way to take an icon from an executable, and create a new executable (using CSharpCodeProvider) that uses this icon.
The first part is easy, I do it using:
Icon icon = Icon.ExtractAssociatedIcon(path);
The problems come when I want to "attach" the icon. I tried using:
compilerParameters.CompilerOptions = #"/win32icon:"
But this solution requires the icon to be written in a file and I'd like to avoid that (one of the reason being it's such a mess to save an icon with more than 16 colors...).
Is it possible to use the System.Drawing.Icon object in memory directly?
EDIT: Just to be clear, I'm trying to obtain a code that can compile C# code into an executable. This executable will have an icon that is only hold in memory (as an Icon object) and not in a file (as a .ico file).
Use the IconLibrary to save Icon
Icon icon = Icon.ExtractAssociatedIcon(#"C:\Windows\System32\notepad.exe");
MultiIcon mIcon = new MultiIcon();
SingleIcon sIcon = mIcon.Add("notepad");
sIcon.CreateFrom(icon.ToBitmap(), IconOutputFormat.Vista);
sIcon.Save(#"c:\notepad.ico");
And use that for CompilerOptions
More information
https://msdn.microsoft.com/en-us/library/2aaxe43f.aspx
Solution :
In case anyone is looking to do the same thing, here is a method that brought the expected result (icon extracting with correct graphic quality).
I use Tsuda Kageyu IconExtractor in order to get the icon I want and convert it to Bitmap with the transparency.
Then I use the IconLibrary suggested by #mohsen to write in icon as a .ico file and then embed it with the CompilerOptions.
Related
I have a game application in Visual Studio 2012 C#. I have all the .png images I am using in the Resources file of the project.
Have you any idea why I can access all the files but one by using Properties.Resources?
I checked the full filePath and it's set to the resources folder. And it's added in the program as I did Add -> Existing Item and added the image.
It looks just like the other images. I have no idea why it's not loading. I need this since I need to send a .exe by email to my lecturer and without this image the project is nothing!
I added this in the resource file
internal static System.Drawing.Bitmap grid_fw {
get
{
object obj = ResourceManager.GetObject("grid.fw", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
and although now grid is available, it is returning null :/
Found from: Properties.Resources the icon name does not appear in the intellisense
You also need to add the icon to the Resources.resx file. Open it in
Visual Studio and drag your icon into the Icons menu of the resx and
it will become available.
Also, see Adding and Editing Resources (Visual C#)
You can get a reference to the image the following way:
Image myImage = Resources.yourImage;
If you want to make a copy of the image, you'll need to do the following:
Bitmap bmp = new Bitmap(Resources.yourImage);
Don't forget to dispose of bmp when you're done with it. If you don't know the name of the resource image at compile-time, you can use a resource manager:
ResourceManager rm = Resources.ResourceManager;
Bitmap yourImage = (Bitmap)rm.GetObject("yourImage");
The benefit of the ResourceManager is that you can use it where Resources.myImage would normally be out of scope, or where you want to dynamically access resources. Additionally, this works for sounds, config files, etc.
I am using a custom cursor named hand2.cur in my C#-WPF application. I have added the cursor to a folder named Images which has all the images that I use in my application. However I've realized that I cannot add relative path to use my custom cursor as:
Cursor newCur = new Cursor("Images\\hand2.cur");
window.Cursor = newCur;
So I used this:
string absolute = System.IO.Path.GetFullPath("hand2.cur");
Cursor newCur = new Cursor(absolute);
window.Cursor = newCur;
This tries to find the hand2.cur file in the \bin\Release folder. So I added the file there and I got it working.
But the problem is, if I Publish this application and use it on a different computer, it does not work. Now the problem is with the cursor file path, because if I deploy it after commenting those 3 lines, it works correctly. So what do I do to rectify this problem?
I am using other images from the Image folder in my XAML code and they seem to port fine. But then again my knowledge of WPF is limited so if anyone has any ideas, that would help.
EDIT: I have added my Images folder to the project. I have also set the Build Action of the cursor file hand2.cur to Embedded Resource. However when I use the following two lines, I get an XAMLParseException.
System.Windows.Resources.StreamResourceInfo info = Application.GetResourceStream(new Uri("pack://application:,,,/Slideshow;component/Images/hand2.cur"));
window.Cursor = new System.Windows.Input.Cursor(info.Stream);
The Inner Exception field when I view the details of the error reads: {"Cannot locate resource 'images/hand2.cur'."}
You could make the cursor a resource in your app/assembly and then use GetResourceStream with the pack Uri to the resources location. Pass the Stream of the StreamResourceInfo to the ctor of the Cursor. e.g.
var info = Application.GetResourceStream(new Uri("pack://application:,,,/Images/hand2.cur"));
var cursor = new Cursor(info.Stream);
I've got this working after I added the cursor file hand2.cur to my Resource1.resx resource file. Then I used the following statement in my code:
window.Cursor = new Cursor(new System.IO.MemoryStream(MyNameSpace.Resource1.hand2));
C# - Loading image from file resource in different assembly
I have a PNG image file which is stored in a project called SomeProject and displayed various times using XAML in that same project. In a different assembly, I now wish to access that same image. Previously I was simply specifying a relative path to the actual file which worked fine. However, when I build a release installer, the image files are packed into the SomeProject.DLL.
Is there any easy way I can access the PNG file from another assembly without simply resorting to copying the file locally to the second project? I though it might be possible using 'pack://' but I'm not having much luck.
// SomeOtherProject.SomeClass.cs ...
Image logo = new Image();
BitmapImage logoSource = new BitmapImage();
eChamSource.BeginInit();
// Following line works fine is Visual Studio, but obviously not after installation
// logoSource.UriSource = new Uri(#"..\SomeProject\Resources\Images\logo.png", UriKind.Relative);
logoSource.UriSource = new Uri("pack://application:,,,/SomeProject;component/Resources/Images/logo.png");
logoSource.EndInit();
logo.Width = 100; logo.Height = 100;
logo.Source = logoSource;
Any advice would be good.
If the images you wish to use as Content is in another assembly, you must copy them to the main projects directory.
You can use a Build event to do this:
Right click project that contains images -> Properties -> Buil Events -> edit post build to copy images to main project directory.
Then you have to use it as
pack://application:,,,/ContentFile.xaml
(Or)
If you need it in subfolder
pack://application:,,,/Subfolder/ContentFile.xaml
Have a look at this hfor more information http://msdn.microsoft.com/en-us/library/aa970069.aspx
Try to load your other assembly as followed:
Application.LoadComponent(new Uri(#"AnotherAssembly;;;component\AnotherResourceFilePath/logo.png", UriKind.Relative)));
LoadComponent function returns an object. It is up to you to cast it to the appropriate type.
The program crashes if there's no .ico file inside the same folder. I have:
Added the MyIcon.ico file in the Application section, also 'embed manifest with default settings' is checked.
Made the .ico file as Embedded Resource (Build Action) in the .ico file properties.
Added this.Icon = new Icon("plat.ico"); in the Public form.
So... why is the application not booting? What gives?
The constructor for Icon you are using tries to read "plat.ico" as a filename, not from embedded resources.
If you want to load the Icon from resources, you will need to explicitly get a Stream from the resource, then pass that into the Icon's constructor.
This will likely be something similar to:
// Add using System.Reflection; at the top of your file...
this.Icon = new Icon(
Assembly.GetExecutingAssembly().GetManifestResourceStream("YourNamespace.plat.ico")
);
Alternatively, you can use the constructor overload that pulls directly from a resource, by name, instead of a filename:
this.Icon = new Icon(this.GetType(), "plat.ico");
I had the same problem in a windows form, where the icon could not be found even though it was in the same directory as the form.
notifyIcon1.Icon = new Icon("enabled.ico");
I looked at the .ico file's properties in VS2010 and saw that Copy to Output Directory was set to Do not copy. I changed it to Copy always and that did the trick.
Sometimes the simplest solution is the best solution.
You need to set the icon file's "Copy to Output" to "Copy Always" or "Copy if Newer".
You are invoking wrong constructor. Just use this:
this.Icon = new Icon(this.GetType(), "plat.ico");
Is there a way to use a custom cursor in winforms?
There seems to be no option. But when I try to manually add a cursor as a resource, then call it from code, it says that it cannot convert from type byte[] to Cursor.
Adding custom icon to cursor in C# :
Add Icon file to Project resources (ex : Processing.ico)
And in properties window of image switch "Build Action" to "Embedded"
Cursor cur = new Cursor(Properties.Resources.**Imagename**.Handle);
this.Cursor = cur;
Ex:
Cursor cur = new Cursor(Properties.Resources.Processing.Handle);
this.Cursor = cur;
From the MSDN documentation on the Cursor class (with minor corrections):
// The following generates a cursor from an embedded resource.
// To add a custom cursor, create or use an existing 16x16 bitmap
// 1. Add a new cursor file to your project:
// File->Add New Item->Local Project Items->Cursor File
// 2. Select 16x16 image type:
// Image->Current Icon Image Types->16x16
// --- To make the custom cursor an embedded resource ---
// In Visual Studio:
// 1. Select the cursor file in the Solution Explorer
// 2. Choose View->Properties.
// 3. In the properties window switch "Build Action" to "Embedded"
// On the command line:
// Add the following flag:
// /res:CursorFileName.Cur,Namespace.CursorFileName.Cur
//
// Where "Namespace" is the namespace in which you want to use
// the cursor and "CursorFileName.Cur" is the cursor filename.
// The following line uses the namespace from the passed-in type
// and looks for CustomCursor.MyCursor.Cur in the assemblies manifest.
// NOTE: The cursor name is case sensitive.
this.Cursor = new Cursor(GetType(), "MyCursor.Cur");
I've used the LoadCursorFromFile() method from User32.dll. There are plenty of samples for this on the web.
OR
The ctor for the Cursor type also has a IO.Stream overload. Load your byte[] into a MemoryStream and feed that to the new Cursor.
After adding the file to the resources, in the properties window of the image: switch Build Action to Embedded Resource and write in your code:
"name of control".Cursor = new System.Windows.Forms.Cursor(Properties.Resources."name of image".Handle);
Convert your cursor from any format to ico using convertico.com(It is the best way of doing this), copy your cursor to your project's debug folder using file explorer and write this code(C#):
this.Cursor = new Cursor("default.ico");
I had the same problem for a while. So, as far as I understood, these are 2 ways to solving that issue:
Putting cursor .ico file into the Resources
Getting cursor from .ico file without putting it the resources
First case:
After putting to the resources you can just add .Handle after the name of resource while getting it. For instance:
this.Cursor = new Cursor(Properties.Resources.YourResource.Handle);
Second case:
This one looks a bit easier, but before that you should add your .ico file to project and in properties of that file you should set Always copy for file to be copied automatically to the execution folder. After that you can easyly use this:
this.Cursor = new Cursor("YourIcon.ico");
To my mind, using the resources for permanent files like cursor icons is the best practice, so the used the first one.