前言
C# Setup打包msi项目在创建快捷方式时如果需要修改图标时修改步骤比较繁琐,文章将介绍使用安装类如何创建程序快捷键以及如何运用,结尾有demo下载链接供参考(编译工具VS2019)。
一、创建安装类
1.创建一个空项目
2.在空项目中添加“Program.cs”类
3.添加“Installer1.cs”安装类
至此安装类创建完成,把下面代码添加至安装类。
/// <summary>
/// 进程名
/// </summary>
private const string course = "WindowsFormsApp1";
/// <summary>
/// msi项目中的ico文件名
/// </summary>
private const string iconame = "WindowsFormsApp1.ico";
/// <summary>
/// 桌面快捷键名
/// </summary>
private const string shortcutKeyName = "WindowsFormsApp1.lnk";
/// <summary>
/// 卸载快捷键名
/// </summary>
private const string uninstallKeyName = "WindowsFormsApp1_Uninstall.lnk";
/// <summary>
/// 安装包ProductCode值(修改版本号时,要同步更新)
/// </summary>
private const string ProductCode = "/x{C8402388-EA39-41E1-A1C1-73D3167A5602}";
/// <summary>
/// 依赖dll文件名
/// </summary>
private string[] filenames = { "" };
/// <summary>
/// 重写安装过程方法
/// </summary>
/// <param name="stateSaver"></param>
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
}
/// <summary>
/// 重写安装之前的方法
/// </summary>
/// <param name="savedState"></param>
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
protected override void OnBeforeInstall(IDictionary savedState)
{
base.OnBeforeInstall(savedState);
try
{
System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName(course);
foreach (System.Diagnostics.Process p in process)
{
p.Kill();
}
}
catch (Exception)
{
}
}
/// <summary>
/// 重写回滚方法
/// </summary>
/// <param name="savedState"></param>
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Rollback(IDictionary savedState)
{
base.Rollback(savedState);
}
/// <summary>
/// 重写卸载方法
/// </summary>
/// <param name="savedState"></param>
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);
try
{
System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName(course);
foreach (System.Diagnostics.Process p in process)
{
p.Kill();
}
}
catch
{
}
#region 删除快捷键
if (File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory) + @"\" + shortcutKeyName))
{
try
{
File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory) + @"\" + shortcutKeyName);
}
catch
{
}
}
if (File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + shortcutKeyName))
{
try
{
File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + shortcutKeyName);
}
catch
{
}
}
if (File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + uninstallKeyName))
{
try
{
File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + uninstallKeyName);
}
catch
{
}
}
#endregion
}
/// <summary>
/// 重写安装完成后函数
/// 实现安装完成后启动已安装的程序
/// </summary>
/// <param name="savedState"></param>
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
protected override void OnAfterInstall(IDictionary savedState)
{
base.OnAfterInstall(savedState);
Assembly assembly = Assembly.GetExecutingAssembly();
string path = assembly.Location.Remove(assembly.Location.LastIndexOf("\\") + 1);
try
{
string dirx86 = Environment.GetFolderPath(Environment.SpecialFolder.SystemX86);
if (Directory.Exists(dirx86))
{
foreach (var item in filenames)
{
try
{
if (File.Exists(dirx86 + @"\" + item + ".dll"))//如果系统dll文件夹中存在依赖文件就删除安装目录下的
{
File.Delete(path + item + "Temp.dll");//dll名称加Lytmi防止360杀毒提示
}
else
{
File.Move(path + item + "Temp.dll", path + item + ".dll");//将dll名恢复
}
}
catch
{
}
}
}
}
catch
{
}
try
{
string dir = Environment.GetFolderPath(Environment.SpecialFolder.System);
if (Directory.Exists(dir))
{
foreach (var item in filenames)
{
try
{
if (File.Exists(dir + @"\" + item + ".dll"))//如果系统dll文件夹中存在依赖文件就删除安装目录下的
{
if (File.Exists(path + item + "Temp.dll"))
File.Delete(path + item + "Temp.dll");
}
else
{
if (File.Exists(path + item + "Temp.dll"))
File.Move(path + item + "Temp.dll", path + item + ".dll");
}
}
catch
{
}
}
}
}
catch
{
}
#region 创建快捷键
//生成桌面快捷键
EstablishLNK(path, course, path + iconame);
//生成开始栏快捷键
EstablishLNK(path, course, path + iconame, shortcutKeyName);
//生成开始栏快捷键(卸载)
EstablishLNK(path, "msiexec", path + iconame, uninstallKeyName, ProductCode);
#endregion
安装完成启动软件
//string url = path + course + ".exe";
//if (File.Exists(url))
//{
// System.Diagnostics.Process.Start(url);
//}
}
/// <summary>
/// 通过注册表判断是否已经安装:
/// </summary>
/// <returns></returns>
public static bool Whether_to_install(string displayname)
{
try
{
//打开注册表64位
Microsoft.Win32.RegistryKey uninstallNode = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
//便利该注册表目录下是否存在目标安装软件
foreach (string subKeyName in uninstallNode.GetSubKeyNames())
{
Microsoft.Win32.RegistryKey subKey = uninstallNode.OpenSubKey(subKeyName);
object displayName = subKey.GetValue("DisplayName");
if (displayName != null)
{
//软件在注册表中注册的名称是否存在
if (displayName.ToString().Contains(displayname))
{
//object startpath = subKey.GetValue("Inno Setup: App Path");
KKpath 全局变量,得到KK软件的安装路径
//KKpath = startpath.ToString();
如果存在,则打开,另创立线程打开
//Thread t = new Thread(starKK);
//t.Start();
return true;
}
}
}
}
catch (Exception)
{
return false;
}
return false;
}
/// <summary>
/// 为某个文件创建桌面快捷方式(例如为xxx.exe创建快捷方式)
/// </summary>
/// <param name="workingDirectory">文件路径(不包含文件)</param>
/// <param name="fileName">文件名(不包含后缀)</param>
private void EstablishLNK(string workingDirectory, string fileName, string icoPath)
{
try
{
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
//string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\" + fileName + ".lnk";//修改“桌面”路径之后无法在桌面上显示
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory) + @"\"+shortcutKeyName);
shortcut.TargetPath = workingDirectory + fileName + ".exe"; //指定目标路径 (右键快捷方式的目标(T))
shortcut.WorkingDirectory = workingDirectory; //设置起始位置 (右键快捷方式的起始位置(S))
shortcut.WindowStyle = 1; //设置运行方式,默认为常规窗口 (右键快捷方式的运行方式(R))
shortcut.Description = "";//设置备注,鼠标放在图标上提示改文字 (右键快捷方式的备注(O))
shortcut.IconLocation = icoPath; //设置图标路径 (快捷方式的图标)
shortcut.Save(); //保存快捷方式
}
catch
{
}
}
/// <summary>
/// 为某个文件创建"开始"菜单栏快捷方式(例如为xxx.exe创建快捷方式)
/// </summary>
/// <param name="workingDirectory">文件路径(不包含文件)</param>
/// <param name="fileName">文件名(不包含后缀)</param>
/// <param name="icoPath">图标路径</param>
/// <param name="likName">快捷键(不包含后缀)</param>
/// <param name="fileName">卸载Arguments属性对应的 ProductCode 值</param>
private void EstablishLNK(string workingDirectory, string fileName, string icoPath, string likName, string arguments = "")
{
try
{
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + likName);//创建快捷方式对象
shortcut.TargetPath = workingDirectory + fileName + ".exe";//指定目标路径 (右键快捷方式的目标(T))
shortcut.WorkingDirectory = workingDirectory;//设置起始位置 (右键快捷方式的起始位置(S))
shortcut.WindowStyle = 1;//设置运行方式,默认为常规窗口 (右键快捷方式的运行方式(R))
shortcut.Description = "";//设置备注,鼠标放在图标上提示改文字 (右键快捷方式的备注(O))
shortcut.Arguments = arguments;// "/x {7E02EF8B-D7A8-40B0-9F84-067E010A93E7}"
shortcut.IconLocation = icoPath;//设置图标路径,这里不设置 (快捷方式的图标)
shortcut.Save();
}
catch (Exception)
{
}
}
添加引用-》IWshRuntimeLibrary
添加引用-》Microsoft.CSharp
二、使用安装类
1.进入自定义界面
2.选中“Install”添加自定义操作
3.双击进入Application Folder
4.选中安装类程序点OK关闭弹框。
5.“Uninstall”重复“Install”2-4步骤。
三、Demo使用
到Project1文件夹中运行Project1.sln
Demo下载
总结
Setup项目也可以生成快捷键,但是如果频繁换图标时就很痛苦,两种方式各有千秋可以都尝试一下。
参考资料:
为C#应用程序创建Visual Studio安装项目生成MSI包安装程序