有这样的需求,一个系统,包含Web端的后台和Winform的绘图客户端程序,用户需要在Web端能够启动绘图客户端,并且不需要重新登录(因为已经登录了Web端了)。
那么在IE的Web端,如何启动Winform做的绘图客户端程序呢?当然对于其他桌面应用程序也是一样的。
总体思路是:
1. 在asp.net页面中增加一个按钮或者菜单,连接是调用一个JavaScript函数实现启动程序
2. 客户端的用户的环境变量有该应用程序的目录路径信息
3. Winform的绘图客户端程序能够处理传递过来的命令行的参数,实现登录启动

详细操作介绍如下:
1、asp.net页面中Javascript的代码如下:

Code
javascript:Run('EDNMS.UI.exe -u admin -p 4f5a51484e3c639b7c0e606511fe062d5f55aa0509638b385ed179e6d7fe4e9b7342f04c7c74b625574d6aa009693f386cef7b49536c3a4bfb5372675e76bb134f746a84466b7da86703');
Code
<script type="text/javascript" language="JavaScript">
function Run(command) 
    {            
        window.oldOnError = window.onerror;     
        window._command = command;     
        window.onerror = function (err){     
            if(err.indexOf('automation') != -1){     
                alert('命令已经被用户禁止!');     
                return true;     
            }
            else return false;
        };     
        
        try
        {
            var wsh = new ActiveXObject('WScript.Shell');     
            if(wsh)     
                wsh.Run(command);
            window.onerror   =   window.oldOnError;
        }
        catch (e)
        {
            alert('找不到文件EDNMS-DE.EXE(或它的组件之一)。请确定路径和文件名是否正确,而且所需的库文件均可用。')    
        }
    }    
</script>

2、为了使得Web端的Javascript能够调用EDNMS.UI.exe 的Winform程序,我们需要在安装Winform的时候,把安装路径加入到操作系统Path变量中,操作系统的Path变量的内容放置在注册表节点SYSTEM\\ControlSet001\\Control\\Session Manager\\Environment的Path中,下面是自定义安装操作的代码。

Code
    [RunInstaller(true)]
    public class InstallAction : Installer
    {
        private string virtualRoot = string.Empty; // 安装虚拟路径
        private string physicalRoot = string.Empty; // 安装物理路径
        
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private Container components = null;
        
         public InstallAction()
        {
            // 该调用是设计器所必需的。
            InitializeComponent();
        }
        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);

try
            {
                .
                    
                //修改Path环境变量
                UpdatePathEnvironment();
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message + "\r\n " + ex.StackTrace);
            }
        }
        
        /// <summary>
        /// 加入安装文件的路径,方便Web端访问
        /// </summary>
        private void UpdatePathEnvironment()
        {
            //得到原来Path的变量值
            string registerKey = "SYSTEM\\ControlSet001\\Control\\Session Manager\\Environment";
            string key = "Path";
            RegistryKey regKey = Registry.LocalMachine.OpenSubKey(registerKey);
            string result = regKey.GetValue(key).ToString();

//添加新的值
            if (result.IndexOf(physicalRoot) < 0)
            {
                result += string.Format(";{0}", physicalRoot);
            }

regKey = Registry.LocalMachine.OpenSubKey(registerKey, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue);
            regKey.SetValue(key, result);
        }
         .   
    }

3、Winform的绘图客户端程序能够处理传递过来的命令行的参数,实现登录启动
首先介绍一个能够处理命令行参数的公共类,他可以接受参数并把它放置到字典中

Code
using System;
using System.Collections.Generic;
using System.Text;

namespace WHC.EDNMS.Commons
{
    public class CommandArgs
    {
        Dictionary<string, string> mArgPairs = new Dictionary<string,string>();
        public Dictionary<string, string> ArgPairs
        {
            get { return mArgPairs; }
        }
    
        public List<string> Params
        {
            get { return mParams; }
        }
        List<string> mParams = new List<string>();
    }

public class CommandLine
    {
        /// <summary>
        /// Parses the passed command line arguments and returns the result
        /// in a CommandArgs object.
        /// </summary>
        /// The command line is assumed to be in the format:
        /// 
        ///     CMD [param] [[-|--|\]&lt;arg&gt;[[=]&lt;value&gt;]] [param]
        /// 
        /// Basically, stand-alone parameters can appear anywhere on the command line.
        /// Arguments are defined as key/value pairs. The argument key must begin
        /// with a '-', '--', or '\'.  Between the argument and the value must be at
        /// least one space or a single '='.  Extra spaces are ignored.  Arguments MAY
        /// be followed by a value or, if no value supplied, the string 'true' is used.
        /// You must enclose argument values in quotes if they contain a space, otherwise
        /// they will not parse correctly.
        /// 
        /// Example command lines are:
        /// 
        /// cmd first -o outfile.txt --compile second \errors=errors.txt third fourth --test = "the value" fifth
        /// 
        /// <param name="args">array of command line arguments</param>
        /// <returns>CommandArgs object containing the parsed command line</returns>
        public static CommandArgs Parse(string[] args)
        {
            char[] kEqual = new char[] { '=' };
            char[] kArgStart = new char[] { '-', '\\' };

CommandArgs ca = new CommandArgs();
            int ii = -1;
            string token = NextToken( args, ref ii );
            while ( token != null )
            {
                if (IsArg(token))
                {
                    string arg = token.TrimStart(kArgStart).TrimEnd(kEqual);

string value = null;

if (arg.Contains("="))
                    {
                        string[] r = arg.Split(kEqual, 2);
                        if ( r.Length == 2 && r[1] != string.Empty)
                        {
                            arg = r[0];
                            value = r[1];
                        }
                    }
                    
                    while ( value == null )
                    {
                        string next = NextToken(args, ref ii);
                        if (next != null)
                        {
                            if (IsArg(next))
                            {
                                ii--;
                                value = "true";
                            }
                            else if (next != "=")
                            {
                                value = next.TrimStart(kEqual);
                            }
                        }
                    }
                    
                    ca.ArgPairs.Add(arg, value);
                }
                else if (token != string.Empty)
                {
                    ca.Params.Add(token);
                }

token = NextToken(args, ref ii);
            }

return ca;
        }

static bool IsArg(string arg)
        {
            return (arg.StartsWith("-") || arg.StartsWith("\\"));
        }

static string NextToken(string[] args, ref int ii)
        {
            ii++;
            while ( ii < args.Length )
            {
                string cur = args[ii].Trim();
                if (cur != string.Empty)
                {
                    return cur;
                }
                ii++;
            }

return null;
        }

}
}

然后在程序的入口Main函数中,增加对参数化的登录解析,如下所示

Code
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

if (args.Length > 0)
            {
                //args = new string[] { "-u ", "admin", "-p", "4e0a40090737639a661f6e7109f1062c585dff410f668c3c5f836caf8ef54e9a695bfe48647bb62450457fe40b6c383c6dbd6e0002673a4ae14a74634679bb12487c7fc0406e7aac6611" };
                LoginByArgs(args);
            }
            else
            {
                LoginNormal(args);
            }
        }

Code
        /// <summary>
        /// 使用参数化登录
        /// </summary>
        /// <param name="args"></param>
        private static void LoginByArgs(string[] args)
        {
            CommandArgs commandArgs = CommandLine.Parse(args);
            if (commandArgs.ArgPairs.Count > 0)
            {
                #region 获取用户参数
                string userName = string.Empty;
                string identity = string.Empty;
                foreach (KeyValuePair<string, string> pair in commandArgs.ArgPairs)
                {
                    if ("U".Equals(pair.Key, StringComparison.OrdinalIgnoreCase))
                    {
                        userName = pair.Value;
                    }
                    if ("P".Equals(pair.Key, StringComparison.OrdinalIgnoreCase))
                    {
                        identity = pair.Value;
                    }
                } 
                #endregion

if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(identity))
                {
                    bool bLogin = Portal.gc.LoginByIdentity(userName.Trim(), identity);
                    if (bLogin)
                    {
                        ShowMainDialog();
                    }
                    else
                    {
                        LoginNormal(args);
                    }
                }
            }
        }

至此,当客户端安装了绘图客户端后,Path的路径将加入安装的路径,在Web端通过javascript调用程序启动即能进行响应,并通过CommandLine辅助类解析参数后进行登录。
但要主要的是,Javascript能够调用本地的程序,是需要在IE中设置启用Javascript权限许可才可以。

转载于:https://www.cnblogs.com/wuhuacong/archive/2008/08/16/1268576.html

C#进行Visio二次开发之Web端启动绘图客户端并登录相关推荐

  1. C#进行Visio二次开发之Web查看Visio图纸

    前面介绍的Visio开发知识,都是基于Winform的Visio的开发知识,图纸的展示都是基于Winform方式展示的.但很多时候,如果能够通过Web方式可以查看最新的图纸信息,那么系统将更加趋向完美 ...

  2. C#进行Visio二次开发之Shape的Data1、Data2、Data3的用处

    我们知道,Visio的Shape对象有有3个比较特别的属性,分别是Data1.Data2.Data3,平常我们很少用到它,因为我们如果需要属性的话,可能会通过ShapeSheet的Customed P ...

  3. C#进行MapX二次开发之MapX基础知识

    C#进行MapX二次开发之MapX基础知识 MapX的主要技术特点 (1). 以表(Table)的形式组织信息 每一个表都是一组MapInfo文件,这些文件组成了地图文件和数据库文件.为使用MapIn ...

  4. koa+mysql+vue+socket.io全栈开发之web api篇

    原文地址:koa+mysql+vue+socket.io全栈开发之web api篇 目标是建立一个 web QQ的项目,使用的技术栈如下: 后端是基于koa2 的 web api 服务层,提供curd ...

  5. U9二次开发之BP定时任务插件开发

    采购订单BP定时任务插件开发 最近我们公司要做采购订单审批和OA的集成,也就是把u9的审批流程搬到OA里去做.当业务员点击标准采购提交按钮的时候,把采购订单的信息触发到OA流程,在OA里做审核,OA审 ...

  6. Vissim11二次开发之C#---实现仿真时间内实施不同信号控制方案

    Vissim11二次开发之C#-实现仿真时间内实施不同信号控制方案 本文起源:近些日子,由于论文仿真需求,重重重操Vissim旧业. 先说下需求情况吧:路网区域优化前后两种信号控制方案,由于论文场景要 ...

  7. AutoCAD .Net二次开发之Editor选择集

    AutoCAD .Net二次开发之Editor选择集 PickFirst选择集 一般选择集 选择集过滤SelectionFilter Editor的路径: Autodesk.AutoCAD.Appli ...

  8. Datax 插件二次开发之parquet日志问题处理

    Datax 插件二次开发之parquet日志问题处理 Date: December 31, 2021 参考文档: https://blog.csdn.net/wuleidaren/article/de ...

  9. Revit二次开发之DMU

    Revit二次开发之DMU   Revit是一款三维联动的设计软件,一处修改处处修改, 比如,在三维视图修改了墙的位置,二维视图上墙的位置也跟着变化了,同时,墙上的门窗也会跟着移动. 这种联动关系是R ...

最新文章

  1. Servlet基础:接口、类、请求响应、配置、会话追踪、上下文、协作、异常
  2. VC++ 2010 MFC新特性学习 - 增强与Windows Shell的集成
  3. java 判断exception类型_Checked Exception | Java语言设计者的失误?
  4. Qt C++发送图片到QML显示
  5. UITableView的beginUpdates和endUpdates
  6. Spring学习-- SpEL表达式
  7. Git 在团队中的最佳实践--如何正确使用Git Flow
  8. netty搭建简单的文件服务器
  9. php 空文件夹,使用PHP删除空子文件夹
  10. 设计模式原则之五:里氏置换原则
  11. 【Yarn】工作机制及任务提交流程
  12. .NET/CLI元数据中使用的压缩整数
  13. [渝粤教育] 中国地质大学 中外美术史 复习题 (2)
  14. ftp服务器扫描不了文件内容,ftp服务器扫描不了文件
  15. excel公式失效、单元格内容拼接、定长补0、单元格内容和字符串拼接、判断后填充
  16. s5p6818/fs4418系统移植之uboot的移植
  17. 回溯法——最大团问题c
  18. hive —— 分区表
  19. Java HotSpot(TM) 64-Bit Server VM warning:
  20. 直播软件搭建直播服务架构

热门文章

  1. mysql复制学习二 安装及首次复制配置
  2. BAPI:BAPI_PRODORDCONF_CREATE_TT (TCODE:CO11N)
  3. Sqlserver存储过程和C#分页类简化你的代码!
  4. select2搜索动态加载
  5. c++ sort 从大到小排序_C语言必学的12个排序算法:堆排序(第7篇)
  6. 怎么确定迭代器后面还有至少两个值_学会迭代和迭代器,让你的程序更省内存...
  7. MetadataCache分析
  8. (26)Verilog HDL循环语句:repeat
  9. Mind+上传模式的第三方Arduino用户库实现 -DHT11温湿度模块
  10. android9的手机,可防手机上瘾?安卓9.0首批升级的机型都在这里