用C#如何安装部署一个可以通过双击图片或者右键点击图片弹出菜单打开的图像浏览器程序

如题。图像浏览器的所有功能都已经实现。是个C#编写的桌面应用程序。
现在主要是对项目的打包和安装部署的技术不太理解。
因为不太想以那种只能先运行程序,才能打开图片浏览的方式(感觉很不方便)。但是又不太清楚还有其他的什么方法启动程序。
在网上查了一下,好像说要用操作系统的Shell,好像要修改注册表。
希望有人能详细讲解一下。我会酌情加分。。。
如果能推荐一些可贵的链接或者书籍同样感激不尽。。。
最新回答
思念满溢

2024-11-03 05:32:45

VS的安装部署不太好用,如果要在安装的时候就进行文件关联可以去找一些专门的安装打包工具来打包,在安装的时候可以设置用命令来修改注册表进行文件关联。下面要说的方法不是这种。

下面有两个函数,一个是关联文件,一个是删除文件关联。思路是这样的,在程序安装后第一次运行程序时使用SaveReg()方法关联文件,以后就不自动关联了。在Form_Load事件里先判断是不是第一次运行,然后用:
SaveReg(@"C:\youEXE.exe", ".jpg");
注意,上面的“C:\youEXE.exe”换成你的程序的绝对地址,地址可以用代码来获取。

这样只是关联了文件,不知道你有没有在main函数里设置获取命令的语句,把Main()函数改成:
static void Main(string[] args)
{

}
不知道你对这个熟不熟,当文件关联后(比如.jpg文件),双击.jpg文件打开,程序的主函数会接受到打开命令,这些命令的字符串就存储在数组string[] args里面。其中args[0]里是命令的条数,args[1]是第一条命令,args[2]是第一条命令的参数。比如双击.jpg文件打开后,这里的:
args[0]=3;
args[1]="open";
args[2]="图片地址";

那么可以把args[2]中的图片地址显示出来就实现了你要的双击文件打开了。

我晕,打字真累。。

下面的是关联文件的两个方法:

//注意要引用:using Microsoft.Win32;

/// <summary>
/// 设置文件关联
/// </summary>
/// <param name="p_Filename">程序的名称</param>
/// <param name="p_FileTypeName">扩展名 </param>
public static void SaveReg(string p_Filename,string p_FileTypeName)
{
RegistryKey _RegKey = Registry.ClassesRoot.OpenSubKey("", true); //打开注册表

RegistryKey _VRPkey = _RegKey.OpenSubKey(p_FileTypeName);
if (_VRPkey != null) _RegKey.DeleteSubKey(p_FileTypeName, true);
_RegKey.CreateSubKey(p_FileTypeName);
_VRPkey = _RegKey.OpenSubKey(p_FileTypeName, true);
_VRPkey.SetValue("", "Exec");

_VRPkey = _RegKey.OpenSubKey("Exec", true);
if (_VRPkey != null) _RegKey.DeleteSubKeyTree("Exec"); //如果等于空 就删除注册表DSKJIVR

_RegKey.CreateSubKey("Exec");
_VRPkey = _RegKey.OpenSubKey("Exec", true);
_VRPkey.CreateSubKey("shell");
_VRPkey = _VRPkey.OpenSubKey("shell", true); //写入必须路径
_VRPkey.CreateSubKey("open");
_VRPkey = _VRPkey.OpenSubKey("open", true);
_VRPkey.CreateSubKey("command");
_VRPkey = _VRPkey.OpenSubKey("command", true);
string _PathString = "\"" + p_Filename + "\" \"%1\"";
_VRPkey.SetValue("", _PathString); //写入数据

}
/// <summary>
/// 删除文件关联
/// </summary>
/// <param name="p_FileTypeName">扩展名 .VRD </param>
public static void DelReg(string p_FileTypeName)
{
RegistryKey _Regkey = Registry.ClassesRoot.OpenSubKey("", true);

RegistryKey _VRPkey = _Regkey.OpenSubKey(p_FileTypeName);
if (_VRPkey != null) _Regkey.DeleteSubKey(p_FileTypeName, true);
if (_VRPkey != null) _Regkey.DeleteSubKeyTree("Exec");

}
花若怜

2024-11-03 05:43:33

双击图片打开程序可以参考下面的代码,我也刚刚遇到了这个问题!
注册表关联可以参考楼上的代码,或者直接文件夹选项--设置图片文件使用你自己的程序打开即可。

#region Main method
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//if (args.Length != 1)
// return;
Process instance = RunningInstance();
if (instance == null)
{
Application.Run(new frmCoolForm(args));
}
else
{

IntPtr strPtr = Marshal.StringToHGlobalAnsi(args[0]);
COPYDATASTRUCT copyData;
copyData.dwData = 0;
copyData.cbData = (uint)Encoding.Default.GetByteCount(args[0].ToCharArray(), 0, args[0].Length);
copyData.lpData = strPtr;
IntPtr ptr = Marshal.AllocHGlobal((IntPtr)(Marshal.SizeOf(copyData)));
Marshal.StructureToPtr(copyData, ptr, true);
SendMessage(instance.MainWindowHandle, WM_COPYDATA, -1, (int)ptr);
HandleRunningInstance(instance);
}
}

//start
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
private const int WS_SHOWNORMAL = 1;
private const int WM_COPYDATA = 0x004A;
//end

public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);

//遍历正在有相同名字运行的例程
foreach (Process process in processes)
{
//忽略现有的例程
if (process.Id != current.Id)
{
//确保例程从EXE文件运行
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") ==
current.MainModule.FileName)
{
//返回另一个例程实例
return process;
}
}
}
return null;
}

public static void HandleRunningInstance(Process instance)
{
//确保窗口没有被最小化或最大化
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);

//设置真实例程为foreground window
SetForegroundWindow(instance.MainWindowHandle);
}

protected override void WndProc(ref Message m)
{

switch (m.Msg)
{
case WM_COPYDATA:
string[] path = new string[1];
//if(m.WParam!=IntPtr.Zero)
COPYDATASTRUCT copyData = (COPYDATASTRUCT)Marshal.PtrToStructure((IntPtr)m.LParam, typeof(COPYDATASTRUCT));
if (copyData.lpData != IntPtr.Zero)
path[0] = Marshal.PtrToStringAnsi(copyData.lpData, (int)copyData.cbData);
showIt(path);//这里是关键,获取图片路径,添加你自己的处理代码 就可以了。
break;
}
base.WndProc(ref m);
}

//[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
public uint dwData;
public uint cbData;
public IntPtr lpData;
}

#endregion
总有贱妇计谋本宫

2024-11-03 04:04:35

没有做过,但是有一个思路供LZ参考。
http://www.qqgb.com/Program/VB/VBJQ/Program_172301.html
(代码是VB的,主要是思路)
就此问题欢迎交流。
活给自己看

2024-11-03 02:25:39

不懂,关注。。
个人认为,这个应该是通过修改注册表,把你的程序关联到特定的文件扩展名上,这个相对比较容易。
然后,怎么让程序知道,需要打开的文件是哪个呢?怎么接受这个参数是个问题。
ミー身王八气▔,▔

2024-11-03 02:14:15

vs的新建项里有建立安装部署的选项,查一下那个怎么用就可以了