UE4 Shipping下打开系统窗口崩溃问题 附插件下载地址

原创文章,转载请注明出处。

Shipping下打开系统窗口崩溃问题

插件下载链接

SelectDialog插件下载链接

前言

如果你遇到了正常开发(Debug/Develope)下调用打开系统窗口接口没问题,而Shipping下直接崩溃的话,不妨看看是不是一样的问题。

崩溃现象描述:调用FDesktopPlatformModule::Get()->OpenFileDialog来打开不同系统下的界面,比如要在运行时导入模型,导入图片视频音频等功能,你就会用到这个功能。
如下图,我要在程序中选择一个电脑上fbx格式模型导入进来。在dubug下正常,打出来的包确崩溃了。
怎么解决?什么原因呢?
在这里插入图片描述
你调用的代码应该是类似下面的(FDesktopPlatformModuleEx是我封装的一个shipping下用的插件。FDesktopPlatformModuleEx::Get()

/*
		打开系统文件夹路径
		参数1:文件绝对路径
		参数2:文件类型 TEXT("*.*")=全部
		记录:	TEXT("FBX,JPG,BMP,PNG files|*.fbx;*.jpg;*.png;*.bmp");
		TEXT("FBX Files|*.fbx");
		TEXT("JPG,BMP,PNG files|*.jpg;*.png;*.bmp");
		TEXT("(Image Files)|*.BMP;*.JPG;*.PNG;*.JPEG;)")
	*/
	UFUNCTION(BlueprintCallable, Category = "OpenWindowsFile")
	static TArray<FString> OpenWindowsFiles(const FString& sTitle, const FString& sYourFullPath, const FString& sExtensionStr = TEXT("*.*"));
TArray<FString> URegionRiskReadLibrary::OpenWindowsFiles(const FString& sTitle, const FString& sYourFullPath, const FString& sExtensionStr)
{
	//用户选择的文件列表
	TArray<FString> OpenFileNames;

	IDesktopPlatform* DesktopPlatform = FDesktopPlatformModuleEx::Get();
	if (DesktopPlatform)
	{
		void* ParentWindowHandle = GEngine->GameViewport->GetWindow()->GetNativeWindow()->GetOSWindowHandle();
		DesktopPlatform->OpenFileDialog(ParentWindowHandle, sTitle, sYourFullPath, TEXT(""), *sExtensionStr, EFileDialogFlags::Multiple, OpenFileNames);
	}
	return OpenFileNames;
}

崩溃原因

其实咱们在shipping下是不能引用Engine里Developer文件夹里面的任意模块内容的,这个只能在Debug和Develope下使用。
PS:Engine里Developer指的是下面这个图内Developer文件夹里面的所有模块。
这个文件夹下的所有模块都是不能在shipping下使用的,如果使用了,现象就是shipping下崩溃,相应的支持文件根本就没有打到包里。
在这里插入图片描述
看到这里你应该知道怎么回事了,其实就是由于你调用的打开系统窗口的API是属于DesktopPlatform模块,恰巧DesktopPlatform这个模块又在Developer范围内。

解决方案

其实也简单,就是将上面的Developer文件夹内的DesktopPlatform模块和它用到的 相关模块(在Developer范围) 拷贝出来,将类名模块名这些都修改一下。

看到这里,相信类似的问题你再遇到的话也知道怎么解决了。

所以我做了一个插件,测试过适用于4.25每个版本和4.26每个版本。其他版本的没有测试过。

插件怎么用

1>解压后放到你的工程的Plugins文件夹内;
2>在你的build.cs里面将DesktopPlatform模块的引用, 替换成DesktopPlatformEx模块的名称就好了;
3>去掉DesktopPlatform的头文件包含;
4>调用时候记住是FDesktopPlatformModuleEx::Get(); 将你的代码中的FDesktopPlatformModule替换成FDesktopPlatformModuleEx;

/*
		打开系统文件夹路径
		参数1:文件绝对路径
		参数2:文件类型 TEXT("*.*")=全部
		记录:	TEXT("FBX,JPG,BMP,PNG files|*.fbx;*.jpg;*.png;*.bmp");
		TEXT("FBX Files|*.fbx");
		TEXT("JPG,BMP,PNG files|*.jpg;*.png;*.bmp");
		TEXT("(Image Files)|*.BMP;*.JPG;*.PNG;*.JPEG;)")
	*/
	UFUNCTION(BlueprintCallable, Category = "OpenWindowsFile")
	static TArray<FString> OpenWindowsFiles(const FString& sTitle, const FString& sYourFullPath, const FString& sExtensionStr = TEXT("*.*"));
TArray<FString> URegionRiskReadLibrary::OpenWindowsFiles(const FString& sTitle, const FString& sYourFullPath, const FString& sExtensionStr)
{
	//用户选择的文件列表
	TArray<FString> OpenFileNames;

	IDesktopPlatform* DesktopPlatform = FDesktopPlatformModuleEx::Get();
	if (DesktopPlatform)
	{
		void* ParentWindowHandle = GEngine->GameViewport->GetWindow()->GetNativeWindow()->GetOSWindowHandle();
		DesktopPlatform->OpenFileDialog(ParentWindowHandle, sTitle, sYourFullPath, TEXT(""), *sExtensionStr, EFileDialogFlags::Multiple, OpenFileNames);
	}
	return OpenFileNames;
}

谢谢,创作不易,大侠请留步… 动起可爱的双手,来个关注再走呗
ღ( ´・ᴗ・` )比心<( ̄︶ ̄)>