关于C# winform唤起本地已安装应用程序(测试win10,win7可用)
想要唤起本地已安装应用程序,我想到的有三种可行的方法:
第一种就是打开本地的快捷方式(有的应用可能没有快捷方式,但这种方法效率最高,可配合其他方法使用),快捷方式分为本地桌面快捷方式和开始菜单中的快捷方式两种。
下面讲找出快捷方式路径的方法:
本地桌面快捷方式:用户可能更改过默认的桌面路径,此时以前添加的快捷方式还在默认的c盘下路径,之后创建的快捷方式则会在新的桌面路径之下。
因此我们首先获取到当前桌面的目录地址,代码如下:
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //在path后面拼上 应用的名字.lnk 就是快捷方式的路径啦
如果未更改过桌面目录,默认的c盘路径如下:
"C:\Users\Public\Desktop\" + appName + ".lnk"
开始菜单的快捷方式:(默认主要有两种,在后面拼上应用的名字.lnk 就是快捷方式的路径啦)
C:\ProgramData\Microsoft\Windows\Start Menu\Programs
C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
然后把打开对应路径下的文件就可以实现打开本地快捷方式啦。
打开的方法主要有三种:(详情可查看此篇文章https://www.cnblogs.com/y-yp/p/8782641.html),我只是用了下面这种,原因是比较简单:
System.Diagnostics.Process.Start(@"C:\Users\Public\Desktop\" + appName + ".lnk");
此方法打开失败会返回异常,因此要用try{}catch{}语句把上面四种可能的快捷方式遍历一遍,并使其忽略返回的异常信息。
当然这种方法显然不是特别的完美,可在遍历完之后,未找到应用的情况下再去注册表中查找应用程序的可执行(.exe)文件的路径,也就是第二种方法。
第二种就是查找注册表,找出应用程序的安装路径,然后运行其中的.exe文件,如下:
由于win10和win7注册表结构有些不同,我们首先需要判断系统的版本,然后执行不同版本的代码即可:
Version currentVersion = Environment.OSVersion.Version;
Version compareToVersion = new Version("6.2");
if (currentVersion.CompareTo(compareToVersion) >= )
{
//win8及其以上版本的系统
}else{
// win7及其以下版本的系统
}
win10主要在HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store下,里面直接存放的就是.exe文件的路径,代码如下:
//win8及其以上版本的系统
using (RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store"))
{
if (key != null)
{
bool isFind = false;
string[] sname = key.GetValueNames();
for (int i = ; i < sname.Length; i++)
{
if (sname[i].ToString().Substring(, ) == "C:" || sname[i].ToString().Substring(, ) == "D:" || sname[i].ToString().Substring(, ) == "E:" || sname[i].ToString().Substring(, ) == "F:" || sname[i].ToString().Substring(, ) == "G:" || sname[i].ToString().Substring(, ) == "H:") //查到的注册表可能有SIGN.MEDIA=2CE47846 VS2010\setup.exe,E:\win10\Opera\launcher.exe,需要判断
{
int ss = sname[i].ToString().LastIndexOf("\\");
string s = sname[i].ToString().Substring(ss, sname[i].Length - ss);
string sss = s.Substring(, s.Length - );
if (sss == appName.Text.Trim() + ".exe")
{
MessageBox.Show(sname[i].ToString());
try
{
System.Diagnostics.Process.Start(@sname[i].ToString());
isFind = true;
break;
}
catch {
continue;
}
}
}
}
if(!isFind){
MessageBox.Show("未找到应用,换个名字试试吧!");
}
}
}
}
win7主要有三个目录,里面存放的是有应用相关命名的文件夹,内部有个 InstallLocation 字符串,其值是文件的安装路径,需再拼上 .exe文件名 + “.exe”(特例:QQ需要先进入Bin目录下):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 此为64位应用的路径。
注意:此处需要将winform窗体改为64位应用,否则打开上述路径会被微软重定向到下面32位的目录。操作如下:
右键项目-->属性-->生成,勾选掉首选32位。

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall 此为32位应用的路径
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
代码如下,把三个路径都加以实现即可:
using (RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", false))
{
if (key != null)
{
//foreach (string keyName in key.GetSubKeyNames())
string[] SubK = key.GetSubKeyNames();
MessageBox.Show("length:" + SubK.Length);
for (int i = ; i < SubK.Length; i++)
{
//MessageBox.Show(SubK[i]);
using (RegistryKey key2 = key.OpenSubKey(appName.Text.Trim(), false))
{
if (key2 != null)
{
string installLocation = key2.GetValue("InstallLocation", "").ToString();
if (!string.IsNullOrEmpty(installLocation))
{
MessageBox.Show("路径:" + installLocation);
try
{
System.Diagnostics.Process.Start(@installLocation + "\\" + win7_txt.Text.Trim());
isFind2 = true;
break;
}
catch
{
MessageBox.Show("别循环!");
}
}
}
}
}
if (!isFind2)
{
MessageBox.Show("未找到应用,换个名字试试吧!");
}
}
}
第三种方法就是使用user32.dll提供的API:FindWindowA和ShowWindow,这种方法很简单,但是这个方法只能打开已经在后台运行的应用(如果有更好的API请大佬下方留言)。
首先在CLASS在声明API与常量:
[DllImport("user32.dll", EntryPoint = "FindWindowA")]
private extern static IntPtr FindWindowA(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
public const int SW_SHOWMAXIMIZED = ;
public const int SW_SHOWNORMAL = ;
然后调用即可:
IntPtr hwnd = FindWindowA("WechatMainWndForPC", null);
if (hwnd != IntPtr.Zero)
{
MessageBox.Show("找到窗口");
ShowWindow(hwnd, );
}
else
{
MessageBox.Show("没有找到窗口");
}
其中FindWindowA需要两个参数(目标窗口类名,目标窗口标题),返回一个窗口的句柄(整数型),其中本地已打开窗口的标题(通用,一次获取后面即可通过findWindowA调用,类名获取未找到方法,还请大佬可以指导一下)可用py脚本获取:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from win32gui import *
titles = set()
def foo(hwnd,mouse):
#去掉下面这句就所有都输出了,但是我不需要那么多
if IsWindow(hwnd) and IsWindowEnabled(hwnd) and IsWindowVisible(hwnd):
titles.add(GetWindowText(hwnd))
EnumWindows(foo, 0)
lt = [t for t in titles if t]
lt.sort()
for t in lt:
print(t)
然后ShowWindow中传入FindWindowA得到的句柄和窗口的显示命令两个参数即可。
ShowWindow第二个参数:
SW_HIDE 隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED 最大化窗口,并将其激活
SW_SHOWMINIMIZED 最小化窗口,并将其激活
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL 与SW_RESTORE相同
关于C# winform唤起本地已安装应用程序(测试win10,win7可用)的更多相关文章
- 升级本地已安装的 Node 和 npm 版本
Mac升级本地已经安装的NodeJs和Npm到最新版,可以使用一下方式进行升级和更新. 其实windos上升级nodejs也很简单,只需在nodejs官网下载安装最新的msi即可. 值得注意的是安装时 ...
- hbase本地模式-安装及基本测试
解压缩hbase二进制安装文件到/opt目录下: #tar -zxvf hbase-0.98.6-cdh5.3.6.tar.gz -C /opt/cdh-5.3.6/ 编辑配置文件,这里仅配置数据目录 ...
- VB.Net遍历已安装的程序卸载信息
Private Shared Function ProgramExists(ByVal pgName As String) As Boolean Dim temp As String = Nothin ...
- 关于 Visual Studio 2017 ,或2019 ,Installer 没检测到已安装的程序.以及C++ 创建项目失败
解决方法: 首先, 把 本机 的Installer.exe 卸载了. 2 , 重新下载 Installer.exe 打开后发现 ,又重新检测到 VS 2019 ,或2017了
- 技能Get·将浏览器已安装程序打包
阅文时长 | 0.51分钟 字数统计 | 820字符 主要内容 | 1.前言&环境说明&预备知识 2.详细步骤 3.声明与参考资料 『技能Get·将浏览器已安装程序打包』 编写人 | ...
- 构建一个Gods Eye Android应用程序:第1部分 – 收集已安装的Android应用程序
首先问候一下我的黑客伙伴们,在之前的Introduction to Amunet 教程中,我们了解到Amunet可能是一个间谍Android应用程序. 我不浪费太多时间因而直入主题. 在本教程中,我们 ...
- 列出 Ubuntu 和 Debian 上已安装的软件包
列出 Ubuntu 和 Debian 上已安装的软件包 如果你经常用 apt 命令,你可能觉得会有个命令像 apt 一样可以列出已安装的软件包.不算全错. apt-get 命令 没有类似列出已安装软件 ...
- 谷歌浏览器(chrome)查找、打包已安装的扩展程序
我们有时候会安装浏览器扩展程序,正常情况下,我们回去谷歌应用商店里面进行下载,但是这个需要VPN,有时候我们没法使用VPN,想从其他已安装扩展程序的浏览器上直接安装就可以使用我们下面这个方法 win1 ...
- 安装pytorch成功但cuda不可用
贴上我看的教程https://zhuanlan.zhihu.com/p/26871672 一开始想用pycharm装pytorch,但不知道为什么一直失败.后来只能conda pip安装 但conda ...
随机推荐
- (一)、Java内存模型
简述 Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM),来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效 ...
- skywalking的插件管理agent管理
转载自博客:https://my.oschina.net/eacdy/blog/4304312/print Java Agent是插件化.可插拔的.Skywalking的插件分为三种: 引导插件:在a ...
- elasticSearch插件的安装以及使用nginx的modles收集nginx的日志
1.首先在windows环境上搭建es的集群 集群的配置如下 #node01的配置: cluster.name: es-itcast-cluster node.name: node01 node.ma ...
- JavaWeb网上图书商城完整项目--day02-2.regist页面输入框得到焦点隐藏label
实现当光标输入在输入输入框的时候,将后面的内容隐藏,例如在用户名称输入信息的时候,后面的用户名不能为空隐藏 我们来看看regist.js的代码: //该函数在html文档加载完成之后会调用 $(fun ...
- android 6.0 权限设置详解
从Android 6.0版本开始,在安装应用时,该应用无法取得任何权限. 相反,在使用应用的过程中,若某个功能需要获取某个权限,系统会弹出一个对话框,显式地由用户决定是否将该权限赋予应用. 只有得到了 ...
- JavaWeb网上图书商城完整项目--day02-26.查询所有分类功能之DAO层实现
我们按照表示的设计 以及: package com.weiyuan.goods.category.domain; import java.util.List; public class Categor ...
- MySQL按指定字符合并及拆分
按照指定字符进行合并或拆分是经常碰到的场景,MySQL在合并的写法上比较简单,但是按指定字符拆分相对比较麻烦一点(也就是要多写一些字符).本文将举例演示如何进行按照指定字符合并及拆分. 1. 合并 M ...
- 线性dp 打鼹鼠
鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个n*n 的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气.你可以控 ...
- py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe. : java.lang.IllegalArgumentException: Unsupported class file major version 55
今天小编用Python编写Spark程序报了如下异常: py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apach ...
- 【错误】fatal: destination path already exists and is not an empty directory. 错误及解决办法
今天在使用Git for Windows clone代码时,遇到了题目所示的错误,简单来说就是目标路径‘.’已经存在并且不是一个空目录. 可是在我在文件夹下并没有看到任何文件,显示“该文件夹为空”,然 ...