前因
因为ILRuntime热更项目直接打包出来的DLL不能放置到AssetBundle里面打包 所以我看网上的代码都是读取DLL的bytes然后放置到一个text文件里面后缀是bytes
public class DefaultPath
{
public static string ProjectRootPath = Environment. CurrentDirectory;
public static string ReadOnlyStreamingPath = Application. streamingAssetsPath;
public static string ReadAndWritePath = Application. persistentDataPath;
public static string AssetFolderPath = Application. dataPath;
public static string OutputPath = DefaultPath. AssetFolderPath + "/AddressableFiles/TransformDLL" ;
public static string LoadDllPath = OutputPath + "/HotFix_Project_DLL.bytes" ;
public static string LoadPDBPath = OutputPath + "/HotFix_Project_PDB.bytes" ;
static DefaultPath ( )
{
Debug. Log ( $"ProjectRootPath_ { ProjectRootPath } \n { nameof ( ReadOnlyStreamingPath) } _ { ReadOnlyStreamingPath } \n { nameof ( ReadAndWritePath) } _ { ReadAndWritePath } \n { nameof ( AssetFolderPath) } _ { AssetFolderPath } " ) ;
}
}
public class ILRuntimeHelper
{
const string srcKey = "SrcDLLPath" ;
public static string TargetDll => PathUtility. GetRootPath ( srcKey) + "/HotFix_Project.dll" ;
public static string TargetPDB => PathUtility. GetRootPath ( srcKey) + "/HotFix_Project.pdb" ;
public static string OutputPath => DefaultPath. OutputPath;
public static string LoadDllPath => DefaultPath. LoadDllPath;
public static string LoadPDBPath => DefaultPath. LoadPDBPath;
public const string Symbol = "TestRemoteLoadCode" ;
[ MenuItem ( "Tools/指定加載DLL的文件夾" ) ]
private static void SetDLLPath ( )
{
PathUtility. SetRootPath ( srcKey) ;
}
[ MenuItem ( "Tools/DllToByte" ) ]
private static void DLLToBytes ( )
{
if ( ! File. Exists ( OutputPath) )
{
Directory. CreateDirectory ( OutputPath) ;
}
void CheckFileValid ( string path, string loadPath)
{
if ( ! File. Exists ( path) )
{
throw new Exception ( $"不存在指定文件 { path } " ) ;
}
File. WriteAllBytes ( loadPath, File. ReadAllBytes ( path) ) ;
}
CheckFileValid ( TargetDll, LoadDllPath) ;
CheckFileValid ( TargetPDB, LoadPDBPath) ;
AssetDatabase. Refresh ( ) ;
}
}
后果
但是这样就很麻烦,因为每次我要先点击热更项目的生成,在生成后再回到Unity里面点击DLLToByte按钮。 所以我在热更项目的生成事件里面加入了一个bat命令脚本,当热更项目生成后会自动执行这个命令,这个命令会执行一个程序自动把DLL转换为byte文件放置到Unity对应文件夹里
call 就是调用的意思,projectDir是内置宏,就是热更项目所在的文件夹
bat命令和转换的代码 bat文件的读取和输出文件夹需要自己改成需要的
:: 切换到bat文件所在的文件夹
cd / d % ~ dp0
:: % NAME% 可以引用变量
:: set 可以设置变量
set PROJECTNAME= HotFix_Project
set OUTDLLNAME= % PROJECTNAME% _DLL. bytes
set OUTPDBNAME= % PROJECTNAME% _PDB. bytes
set FROMDLLNAME= % PROJECTNAME% . pdb
set FROMPDBNAME= % PROJECTNAME% . dll
set curdir= % cd%
set EXENAME= % curdir% \TransformHotfixDLL. exe
set DLLPATH= % curdir% \bin\% FROMDLLNAME%
set PDBPATH= % curdir% \bin\% FROMPDBNAME%
cd ..
set curdir= % cd%
set OUTDLLPATH= % curdir% \Assets\AddressableFiles\TransformDLL\% OUTDLLNAME%
set OUTPDBPATH= % curdir% \Assets\AddressableFiles\TransformDLL\% OUTPDBNAME%
set OUTPUTPATH= % curdir% \Assets\AddressableFiles\TransformDLL
:: start是启动程序 后面的字符串是输入程序的参数
start % EXENAME% "%DLLPATH%|%PDBPATH%|%OUTPUTPATH%|%OUTDLLPATH%|%OUTPDBPATH%"
using System ;
using System. Collections. Generic ;
using System. IO ;
using System. Linq ;
using System. Net. Http. Headers ;
using System. Text ;
using System. Threading. Tasks ;
namespace TransformHotfixDLL
{
internal class Program
{
static void Main ( string [ ] args)
{
var paths = args[ 0 ] . Split ( '|' ) ;
var fromDLLPath = paths[ 0 ] ;
var fromPDBPath = paths[ 1 ] ;
var targetPath = paths[ 2 ] ;
var LoadPDBPath = paths[ 3 ] ;
var LoadDllPath = paths[ 4 ] ;
if ( ! File. Exists ( targetPath) )
{
Directory. CreateDirectory ( targetPath) ;
}
void CheckFileValid ( string path, string loadPath)
{
if ( ! File. Exists ( path) )
{
throw new Exception ( $"不存在指定文件 { path } " ) ;
}
File. WriteAllBytes ( loadPath, File. ReadAllBytes ( path) ) ;
}
CheckFileValid ( fromDLLPath, LoadDllPath) ;
CheckFileValid ( fromPDBPath, LoadPDBPath) ;
}
}
}
新的发现
在参考别人的代码的时候发现别人是直接把热更代码写在unity项目里 并且定义一个asdemf
程序集定义文件 这样就相等于定义了一个程序集,又可以方便引用unity的模块。 就很方便。