Unity3D将程序运行日志、配置文件目录、EXE快捷方式实现一键到达

如题
先上懒人下载链接
从unity2017开始发布程序,日志就不在程序同级目录了。这使得发布之后找日志、查bug比较麻烦。当然可以发布时选择dev模式调试,在屏幕上查看,但不方便。
先看一下一般找到打开log日志需要多少步骤:
在这里插入图片描述
一般打开streamingAsset文件夹需要的步骤
在这里插入图片描述
本帖主要解决的问题:
1.exe同级目录一键打开log日志
2.exe同级目录一键打开streamingAssets配置目录
3.streamingAssets目录一键返回exe根目录
4.自动创建exe快捷方式至电脑桌面
在这里插入图片描述在这里插入图片描述
实现原理
命令行……批处理……bat
当然也有直接在C#代码里用Shell命令实现的,我是觉得还得拖进来dll太麻烦,不如直接用计算机自带的bat命令!!!

上代码

//=====================================================
// - FileName:      #AutoCreateShortCut#.cs
// - Created:       #Guido Kuo#
// - CreateTime:    #2020/4/22#
// - Email:         #kuoguido@gmail.com#
// - Description:   #通过命令行方式创建相关快捷方式,以解决需要多次打开相关文件夹查找程序运行日志、配置文件、桌面快捷方式等#
// - (C) Copyright 2020 - 2099,Inc.
// - All Rights Reserved.
//======================================================
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;

public class AutoCreateShortCut : MonoBehaviour
{
    #region 定义变量
    /// <summary>
    /// 程序根目录路径
    /// </summary>
    private string _rootPath;
    /// <summary>
    /// 协程等待文件创建的间隔时间
    /// </summary>
    private const float IntervalTime = 1.5f;

    private bool _isStartDestroy;
    private bool _pathHasChinese;
    private int _recordInt;//1代表有中文字符就提示   2代表忽略永不提示且不执行本脚本
    private const string RecordIntKey = "RecordIntKey";
    #endregion

    void Awake()
    {
        if (PlayerPrefs.HasKey(RecordIntKey))
        {
            _recordInt = PlayerPrefs.GetInt(RecordIntKey);
        }

        if (_recordInt == 2)
        {
            Destroy(GetComponent<AutoCreateShortCut>());
            return;
        }
        _rootPath = Directory.GetParent(Application.dataPath).FullName + "\\";
        InitCreateLogLnk();
        InitCreateStreamingAssetsLnk();
        InitCreateReturnLnk();
#if !UNITY_EDITOR && PLATFORM_STANDALONE_WIN
        InitCreateCurrentExeToDesktop();
#endif

    }

    #region 初始化创建
    /// <summary>
    /// 创建程序桌面快捷方式
    /// </summary>
    void InitCreateCurrentExeToDesktop()
    {
        string exeShortCutName = Application.productName + ".lnk";
        string exeShortCutPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\";
        string exeShortCutBatPath = Application.dataPath + "/CreateExeInk.bat";
        string exeFilePath = _rootPath + Application.productName + ".exe";
        string exeShortCutContent = /*"%1 mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"cmd.exe\",\"/c %~s0 ::\",\"\",\"runas\",1)(window.close)&&exit\n" +*/
        "mshta VBScript:Execute(\"Set a=CreateObject(\"\"WScript.Shell\"\"):Set b=a.CreateShortcut(\"\"" +
        exeShortCutPath + exeShortCutName + "\"\"):" + "b.TargetPath=\"\"" + exeFilePath +
            "\"\":b.WorkingDirectory=\"\"%~dp0\"\":b.Save:close\")";
        JudgmentFile(exeShortCutBatPath, exeShortCutContent, exeShortCutPath, exeShortCutName);
    }
    /// <summary>
    /// 创建日志快捷方式
    /// </summary>
    void InitCreateLogLnk()
    {
        string logShortCutName = "Log.Lnk";
        string logShortCutBatPath = Application.dataPath + "/CreateLogLnk.bat";
        StringBuilder sb = new StringBuilder();
        string debugFilePath = sb.Append(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)).Append("Low\\").Append(Application.companyName).Append("\\").Append(Application.productName).Append("\\output_log.txt").ToString();
        if (!File.Exists(debugFilePath))
            File.Create(debugFilePath);
        //如果创建不成功就取消下面的注释   注释为管理员身份运行批处理
        string createLogShortCutContent = /*"%1 mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"cmd.exe\",\"/c %~s0 ::\",\"\",\"runas\",1)(window.close)&&exit\n" +*/
            "mshta VBScript:Execute(\"Set a=CreateObject(\"\"WScript.Shell\"\"):Set b=a.CreateShortcut(\"\"" +
            _rootPath + logShortCutName + "\"\"):" + "b.TargetPath=\"\"" + debugFilePath +
            "\"\":b.WorkingDirectory=\"\"%~dp0\"\":b.Save:close\")";
        JudgmentFile(logShortCutBatPath, createLogShortCutContent, _rootPath, logShortCutName);
    }
    /// <summary>
    /// 创建外部加载文件夹快捷方式
    /// </summary>
    void InitCreateStreamingAssetsLnk()
    {
        if (!Directory.Exists(Application.streamingAssetsPath))//创建StreamingAssets文件夹
            Directory.CreateDirectory(Application.streamingAssetsPath);
        if (Directory.Exists(Application.streamingAssetsPath))
        {
            string streamingAssetsShortCutName = "StreamingAssets.url";
            string streamingAssetsShortCutBatPath = Application.dataPath + "/CreateStreamingAssetLnk.bat";
            //如果创建不成功就取消下面的注释   注释为管理员身份运行批处理
            string createStreamingAssetsShortCutContent = /*"%1 mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"cmd.exe\",\"/c %~s0 ::\",\"\",\"runas\",1)(window.close)&&exit\n" +*/
                "echo [InternetShortcut] > \"" + _rootPath + streamingAssetsShortCutName + "\"\n" + "echo URL=file:///" + Application.streamingAssetsPath + " >> \"" + _rootPath + streamingAssetsShortCutName + "\"";
            JudgmentFile(streamingAssetsShortCutBatPath, createStreamingAssetsShortCutContent, _rootPath, streamingAssetsShortCutName);
        }
    }
    /// <summary>
    /// 创建返回程序根目录快捷方式
    /// </summary>
    void InitCreateReturnLnk()
    {
        if (!Directory.Exists(Application.streamingAssetsPath))//创建StreamingAssets文件夹
            Directory.CreateDirectory(Application.streamingAssetsPath);
        if (Directory.Exists(Application.streamingAssetsPath))
        {
            string returnShortCutName = "A_ReturnRootFolder.url";
            string returnShortCutBatPath = Application.dataPath + "/CreateReturnLnk.bat";
            //如果创建不成功就取消下面的注释   注释为管理员身份运行批处理
            string returnShortCutContent = /*"%1 mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"cmd.exe\",\"/c %~s0 ::\",\"\",\"runas\",1)(window.close)&&exit\n" +*/
                "echo [InternetShortcut] > \"" + (Application.streamingAssetsPath + "/" + returnShortCutName).Replace("/", "\\") + "\"\n" + "echo URL=file:///" + _rootPath.Replace("\\", "/") + " >> \"" + (Application.streamingAssetsPath + "/" + returnShortCutName).Replace("/", "\\") + "\"";
            JudgmentFile(returnShortCutBatPath, returnShortCutContent, Application.streamingAssetsPath + "/", returnShortCutName);
        }
    }
    #endregion
    /// <summary>
    /// 判断文件
    /// </summary>
    /// <param name="batPath">bat批处理路径</param>
    /// <param name="shortCutContent">bat批处理内容</param>
    /// <param name="shortCutPath">快捷方式路径</param>
    /// <param name="shortCutName">快捷方式名称</param>
    void JudgmentFile(string batPath, string shortCutContent, string shortCutPath, string shortCutName)
    {
        if (File.Exists(batPath))
        {
            if (JudgmentContent(batPath, shortCutContent))
            {
                if (File.Exists(shortCutPath + shortCutName))
                    return;
                else
                    StartCoroutine(CreateShortCutLnk(batPath, shortCutContent, shortCutPath, shortCutName));

            }
            else
            {
                File.Delete(batPath);
                File.Delete(shortCutPath + shortCutName);
                StartCoroutine(CreateShortCutLnk(batPath, shortCutContent, shortCutPath, shortCutName));
            }
        }
        else
            StartCoroutine(CreateShortCutLnk(batPath, shortCutContent, shortCutPath, shortCutName));
    }

    /// <summary>
    /// 判断bat批处理内容是否相同
    /// </summary>
    /// <param name="batPath">bat批处理路径</param>
    /// <param name="compareContent">对比的内容</param>
    /// <returns></returns>
    bool JudgmentContent(string batPath, string compareContent)
    {
        return File.ReadAllText(batPath) == compareContent;
    }
    /// <summary>
    /// 判断字符串中是否包含中文
    /// </summary>
    /// <param name="str">需要判断的字符串</param>
    /// <returns>判断结果</returns>
    bool HasChinese(string str)
    {
        return Regex.IsMatch(str, @"[\u4e00-\u9fa5]");
    }
    #region 创建的协程

    /// <summary>
    /// 创建快捷方式
    /// </summary>
    /// <param name="batPath">bat批处理路径</param>
    /// <param name="shortCutContent">bat批处理内容</param>
    /// <param name="shortCutPath">快捷方式路径</param>
    /// <param name="shortCutName">快捷方式名称</param>
    /// <returns></returns>
    IEnumerator CreateShortCutLnk(string batPath, string shortCutContent, string shortCutPath, string shortCutName)
    {
        if (HasChinese(shortCutContent))
        {
            _pathHasChinese = true;
        }
        else
        {
            if (!File.Exists(batPath))
            {
                File.Create(batPath);
                yield return new WaitForSeconds(IntervalTime);
#if UNITY_EDITOR
                AssetDatabase.Refresh();
#endif
                File.WriteAllText(batPath, shortCutContent, Encoding.Default);
                yield return new WaitForSeconds(IntervalTime);
#if UNITY_EDITOR
                AssetDatabase.Refresh();
#endif
                Application.OpenURL(batPath);
            }
            else
            {
                if (!File.Exists(shortCutPath + shortCutName))
                {
                    Application.OpenURL(batPath);
                }
            }
        }
    }

    IEnumerator WaitToDestroy()
    {
        yield return new WaitForSeconds(IntervalTime * 5);
        Destroy(GetComponent<AutoCreateShortCut>());
    }

    #endregion
    void OnGUI()
    {
        //if (Input.GetKeyDown(KeyCode.C))
        //{
        //    PlayerPrefs.DeleteAll();
        //}
        if (_pathHasChinese)
        {
            GUI.BeginGroup(new Rect((float)Screen.width / 2 - 200, (float)Screen.height / 2 - 200, 400, 400));
            GUI.Box(new Rect(0, 0, 400, 400), "");
            GUIStyle gs = new GUIStyle();
            gs.alignment = TextAnchor.MiddleCenter;
            gs.fontSize = 25;
            gs.normal.textColor = Color.red;
            string content = "路径中有中文,请检查文件路径!";
            GUI.Label(new Rect(0, 0, 400, 50), content, gs);
            gs.fontSize = 23;
            gs.normal.textColor = Color.white;
            GUI.Box(new Rect(140, 100, 120, 50), "");
            content = "退出检查";
            if (GUI.Button(new Rect(140, 100, 120, 50), content, gs))
            {
                Application.Quit();
#if !UNITY_EDITOR
                Process.GetCurrentProcess().Kill();
#endif
            }
            GUI.Box(new Rect(140, 200, 120, 50), "");
            content = "忽略本次";
            if (GUI.Button(new Rect(140, 200, 120, 50), content, gs))
            {
                Destroy(GetComponent<AutoCreateShortCut>());
            }
            gs.normal.textColor = Color.green;
            GUI.Box(new Rect(140, 300, 120, 50), "");
            content = "永久忽略";
            if (GUI.Button(new Rect(140, 300, 120, 50), content, gs))
            {
                PlayerPrefs.SetInt(RecordIntKey, 2);
                Destroy(GetComponent<AutoCreateShortCut>());
            }
            GUI.EndGroup();
            if (_isStartDestroy)
            {
                StopCoroutine("WaitToDestroy");
                _isStartDestroy = false;
            }
        }
        else
        {
            if (!_isStartDestroy)
            {
                StartCoroutine("WaitToDestroy");
                _isStartDestroy = true;
            }
        }

    }
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Unity 3D中,我们可以使用C#代码来读取配置文件。首先,我们需要创建一个文本文件来存储配置数据。可以使用任何文本编辑器创建一个.cfg或者.txt文件,并将其命名为你喜欢的名称,比如config.cfg。 接下来,我们可以使用Unity的Asset Store中的Simple File Browser插件来让用户选择配置文件。该插件可以方便地让用户在文件系统中选择文件,并获取文件的完整路径。 一旦我们有了配置文件的路径,我们就可以使用C#代码来读取它。我们可以使用Unity中的StreamReader类来读取文本文件的内容。下面是一个示例代码: ``` using UnityEngine; using System.IO; public class ConfigReader : MonoBehaviour { void Start() { string filePath = "选择的配置文件路径"; // 读取配置文件 StreamReader reader = new StreamReader(filePath); string configData = reader.ReadToEnd(); reader.Close(); // 处理配置数据 ProcessConfigData(configData); } void ProcessConfigData(string data) { // 在这里编写处理配置数据的代码 } } ``` 在上面的代码中,我们使用StreamReader打开和读取文件的内容,然后将其保存到一个字符串变量中。一旦我们获得了配置数据,我们可以编写处理数据的代码,根据具体需求进行解析和使用。 读取配置文件后,我们可以使用Split函数等C#字符串操作方法将配置数据分割成适当的键值对或者其他数据结构,然后可以根据需要将其用于游戏的逻辑和功能。 请注意,在使用StreamReader读取文件后,我们应该调用Close方法关闭文件流,以释放资源并避免内存泄漏。 这就是使用Unity 3D读取配置文件的基本方法。根据具体的需求,我们可以根据配置文件的格式进行适当的解析和处理,以满足游戏的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值