以编程方式将程序注册到添加/删除程序中并将文件存储在可执行文件中
Posted
技术标签:
【中文标题】以编程方式将程序注册到添加/删除程序中并将文件存储在可执行文件中【英文标题】:Programmatically registering program into Add/Remove programs and storing files within an executable 【发布时间】:2012-08-02 22:13:58 【问题描述】:我正在开发一个 Windows c# 控制台应用程序,我希望允许用户将其安装到他们的计算机上。
我想让我自己的 Windows 安装程序作为 Visual Studio 中内置的安装部署工具可执行,但似乎缺少自定义和文档功能。
因此,因为我想制作自己的 Windows 安装程序,我如何将我的程序注册到“添加/删除程序”窗口,以便他们可以选择再次卸载它,如果他们愿意,它会重新启动我的安装程序进行删除。
此外,可执行文件显然需要将文件复制到 PC 上的不同位置,即C:\Program Files
,所以我将如何将可执行文件存储在 Windows 安装程序可执行文件中,以便将它们移动到正确的位置。
这可能吗?
感谢您提供的任何帮助。
【问题讨论】:
您是否尝试过 ClickOnce 部署选项? 为什么要重新发明***?如果你不喜欢包含的 windows 工具,我会直接去 NSIS:nsis.sourceforge.net/Main_Page。 使用 WiX 怎么样? 【参考方案1】:您可以尝试使用ClickOnce 或Microsoft Installer technology (msi) 部署您的应用程序。
【讨论】:
ClickOnce 似乎比创建 Visual Studio MSI 提供的控制更少。【参考方案2】:不要构建自己的安装程序,请使用经过验证的部署工具,例如: NSIS、Inno Setup 或 WiX。所有这些都是免费的,并且有很多功能。
【讨论】:
不要忘记他们有自己的缺点,比如学习曲线、另一种编程语言、要处理的更多文件、位数(无 AnyCPU)、本地化 同时添加 bitrock。我用过一次。它很容易使用。但不是开源的。 "不要构建自己的安装程序" ,你得到-1 构建安装程序并不难。您将文件添加为资源并像 Neff 所说的那样注册它。然后,它完全在内部,并像您自己的 UI 一样打上烙印。 取决于您项目的性质,但对于我们的应用程序有很多不同的部分,编写我们自己的安装程序是我们做过的最好的决定。您可以完全控制您的安装体验,它可以使安装过程更加流畅,并且在我们的案例中,与我们使用 3rd 方工具时相比,自定义编写的安装程序快得令人眼花缭乱。 YMMV,但是学习别人的工具集所花费的时间可能会让你在编写自己的工具的道路上很好。【参考方案3】:我建议在这种情况下使用 MSI 安装程序,因为它可以让您控制包详细信息(即名称)、在客户端上复制文件的位置,并允许添加您想要作为 msi 一部分包含的额外文件安装程序。
【讨论】:
【参考方案4】:这是我们用来在添加/删除程序中注册程序的例程:
private void CreateUninstaller()
using (RegistryKey parent = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", true))
if (parent == null)
throw new Exception("Uninstall registry key not found.");
try
RegistryKey key = null;
try
string guidText = UninstallGuid.ToString("B");
key = parent.OpenSubKey(guidText, true) ??
parent.CreateSubKey(guidText);
if (key == null)
throw new Exception(String.Format("Unable to create uninstaller '0\\1'", UninstallRegKeyPath, guidText));
Assembly asm = GetType().Assembly;
Version v = asm.GetName().Version;
string exe = "\"" + asm.CodeBase.Substring(8).Replace("/", "\\\\") + "\"";
key.SetValue("DisplayName", "My Program");
key.SetValue("ApplicationVersion", v.ToString());
key.SetValue("Publisher", "My Company");
key.SetValue("DisplayIcon", exe);
key.SetValue("DisplayVersion", v.ToString(2));
key.SetValue("URLInfoAbout", "http://www.blinemedical.com");
key.SetValue("Contact", "support@mycompany.com");
key.SetValue("InstallDate", DateTime.Now.ToString("yyyyMMdd"));
key.SetValue("UninstallString", exe + " /uninstallprompt");
finally
if (key != null)
key.Close();
catch (Exception ex)
throw new Exception(
"An error occurred writing uninstall information to the registry. The service is fully installed but can only be uninstalled manually through the command line.",
ex);
【讨论】:
@MacGyver,B
表示“用连字符分隔的 32 位数字,用大括号括起来”,这是注册表用于 guid 的格式。 msdn.microsoft.com/en-us/library/97af8hh4(v=vs.110).aspx
因此,您的源代码中似乎未定义“UninstallGuid”和“UninstallRegKeyPath”。我假设第二个是卸载应用程序的 exe 路径。请问您能评论这两个吗?我也可以发布一个问题来撤消这个注册键,但这是我的第三个也是最后一个问题。
@MacGyver UninstallRegKeyPath
是顶部的字符串 @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
。我在方法的顶部对其进行了硬编码,但没有注意到错误处理中有对变量的引用。该 guid 只是您的安装程序的 guid。您为您的应用程序生成一个 guid,并在每次安装时使用相同的 guid,这是安装任何 Windows 应用程序的正常部分。它只需要在您应用的各个版本之间保持一致即可唯一标识您的应用(除非您支持多个并行版本,然后在一个版本中的发布是唯一的)。
@MacGyver,代码创建了一个注册表项。要撤消它,请删除注册表项。
@MacGyver,您希望不同安装的 guid 相同,因此不要使用 Guid.NewGuid()
。将 guid 硬编码到您的代码中并根据需要进行更新(当您想要新的并排安装应用程序时)。 ToString("B")
为您提供正确的 guid 格式。【参考方案5】:
看在上帝的份上,不要使用 clickonce ......这比它的价值更麻烦。如果您没有机器的管理权限并且需要安装某些东西,那么值得花时间请求许可。
【讨论】:
以上是关于以编程方式将程序注册到添加/删除程序中并将文件存储在可执行文件中的主要内容,如果未能解决你的问题,请参考以下文章
iOS - 以编程方式将我们应用程序的自定义 URI 添加到存储在日历中的事件中
如何使用 CEF WinForms 以编程方式将文件附件添加到网页
如何以编程方式添加到 NSMutableArray 并将其显示在 uitableviewcells 上?
如何以编程方式将音乐从 pc 同步到 iphone 音乐库? [关闭]