聆听风声 点点滴滴都很珍贵!

用C#创建我的第一个桌面应用

2020-06-19

作为一个刚刚投入c#怀抱的程序员,在大概浏览了一下基本语法后就开始动工了,演示性的创建了一个helloword的桌面应用。接下来开始创建使用的应用。

需求

有一个php搭建的网站,是一个公司内部使用的管理系统,在应用登录的时候需要统计登录员工的电脑ip地址。虽然需求很简单,但是真正做起来的时候发现以下问题:

  • 员工的ip地址是一个二级路由分配的
  • 公司系统在一级路由上

这样就会导致员工访问系统时,ip地址在经过二级路由会变成一级路由分配给二级路由的ip地址,在同一个二级路由下的员工登录系统ip是相同的。要解决这个问题需要在前端获取本地ip地址,这样就不是一个简单的问题了。因为js获取本地ip只有ie浏览器可以,还需要放开权限。这样使用起来就会很不方便,这就是要开发桌面应用的原因。

创建桌面

桌面使用的是Visual Studio 2019编辑器自带的工具,拖拽即可生成画面,使用起来比较简单。

image-20200619160457483

获取IP

获取本地的ip地址,多个ip进行拼接处理

private static string GetLocalIP()
{
    String ip = "";
    System.Net.IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
    for (int i = 0; i < addressList.Length; i++)
    {
        if (addressList[i].ToString().Length<=15)
        { 
            ip += addressList[i].ToString();
            ip += ",";
        }
    }
    return ip;
}

内容加密

对内容加密的方法

public static string Encrypt(string toEncrypt, string key, string iv)
{
    byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
    byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv);
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

    RijndaelManaged rDel = new RijndaelManaged();
    rDel.Key = keyArray;
    rDel.IV = ivArray;
    rDel.Mode = CipherMode.CBC;
    rDel.Padding = PaddingMode.Zeros;

    ICryptoTransform cTransform = rDel.CreateEncryptor();
    byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

    return ByteArrayToString(resultArray);
    //return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

采用bin2hex的方式转换数据

public static string ByteArrayToString(byte[] ba)
{
    StringBuilder hex = new StringBuilder(ba.Length * 2);
    foreach (byte b in ba)
        hex.AppendFormat("{0:x2}", b);
    return hex.ToString();
}

参考文章

访问网址

获取浏览器

此应用采用了默认浏览器打开网址的方式

System.Diagnostics.Process.Start("explorer.exe", "http://127.0.0.1:10002/index.php/user/login/token/"+ token);

标准浏览器注册表位置

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Clients\StartMenuInternet
HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet
public static void BrowsersData()
{
    RegistryKey browsersKey;
    browsersKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Clients\StartMenuInternet");
    if (browsersKey == null)
        browsersKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Clients\StartMenuInternet");
    using (browsersKey)
    {
        string[] subKeys = browsersKey.GetSubKeyNames();
        string locationPath = @"\shell\open\command";
        foreach (string key in subKeys)
        {
            RegistryKey appLocationKey = browsersKey.OpenSubKey(key + locationPath);
            Console.WriteLine("{0}:{1}", key, (string)appLocationKey.GetValue(null));
            appLocationKey.Dispose();
        }
    }
}

添加注册表

将当前的应用添加到注册表中

public MainWindow()
{
    ...
	string exepath = Process.GetCurrentProcess().MainModule.FileName;//获取当前应用的路径
}
protected void SetRegistry(string exepath)
{
    // 得到基项 HKEY_CLASSES_ROOT
    RegistryKey key = Registry.ClassesRoot;
    // 根据路径创建一个为test的项
    RegistryKey test = key.CreateSubKey("zyxt");
    // 在当前项下设置键值
    test.SetValue("URL Protocol", exepath);
    // 根目录下创建DefaultIcon
    RegistryKey DefaultIcon = test.CreateSubKey("DefaultIcon");
    // 根目录下创建shell项
    RegistryKey shell = test.CreateSubKey("shell");
    // shell目录下创建open项
    RegistryKey open = shell.CreateSubKey("open");
    // open目录下创建command项
    RegistryKey command = open.CreateSubKey("command");
    // DefaultIcon目录下设置键值
    DefaultIcon.SetValue("zyxt", exepath + ",1");//修改默认键的值,填空
    // command目录下设置键值
    command.SetValue("", "\""+ exepath + "\",\"%1\"");
    // 关闭项
    key.Close();
}
<body>
	...
    <a href="zyxt://">打开应用</a>
    ...
</body>

判断程序是否以管理员身份运行

/// <summary>
/// 确定当前主体是否属于具有指定 Administrator 的 Windows 用户组
/// </summary>
/// <returns>如果当前主体是指定的 Administrator 用户组的成员,则为 true;否则为 false。</returns>
public static bool IsAdministrator()
{
    bool result;
    try
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        result = principal.IsInRole(WindowsBuiltInRole.Administrator);

        //http://www.cnblogs.com/Interkey/p/RunAsAdmin.html
        //AppDomain domain = Thread.GetDomain();
        //domain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
        //WindowsPrincipal windowsPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
        //result = windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    catch
    {
        result = false;
    }
    return result;
}

数据格式转换

Hashtable格式数据转json数据

public string HashtableToWxJson(Hashtable data)
{
    try
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("{");
        foreach (object key in data.Keys)
        {
            object value = data[key];
            sb.Append("\"");
            sb.Append(key);
            sb.Append("\":\"");
            if (!String.IsNullOrEmpty(value.ToString()) && value != DBNull.Value)
            {
                sb.Append(value).Replace("\\", "/");
            }
            else
            {
                sb.Append(" ");
            }
            sb.Append("\",");
        }
        sb = sb.Remove(sb.Length - 1, 1);
        sb.Append("}");
        return sb.ToString();
    }
    catch (Exception ex)
    {
        return "";
    }
}

Comments

Content