- Home /
System.Windows.Forms.dll assembly is referenced by user code, but is not supported on StandaloneLinuxUniversal platform
I'm trying to build my Unity project on Linux (Ubuntu 16.04), using the command
Editor/Unity -batchmode -nographics -projectPath MyProjectPath -logFile mylog -buildLinuxUniversalPlayer MyProjectApp -enableIncompatibleAssetDowngrade -quit
...and it's not working. In the log file, I see the line:
System.Windows.Forms.dll assembly is referenced by user code, but is not supported on StandaloneLinuxUniversal platform. Various failures might follow.
Why is it even trying to apply a Windows dll when I'm building for Linux?
More importantly, how can I get around this?
.
EDIT: My project does include a Newtonsoft.Json.dll file, which references many System*.dll files, but... I find it 'a bit of a stretch' that Unity on Linux can't parse JSON without Windows-specific System driver files.
Answer by GabLeRoux · Jan 13, 2018 at 10:44 PM
Maybe you're missing the -buildTarget
parameter. Did you try building with the application first? It could be related to using command line to build. I personally had success building from the command line using something that looks like this:
export UNITY_PATH=/Applications/Unity/Unity.app/Contents/MacOS/unity
export BUILD_TARGET=StandaloneLinuxUniversal
export BUILD_TARGET_GROUP=Standalone
${UNITY_PATH} \
-projectPath $(pwd) \
-quit \
-batchmode \
-buildTarget ${BUILD_TARGET} \
-customBuildTarget ${BUILD_TARGET} \
-customBuildTargetGroup ${BUILD_TARGET_GROUP} \
-customBuildOptions AcceptExternalModificationsToPlayer \
-executeMethod BuildCommand.PerformBuild \
-logFile
I had to write my own build script Assets/Editor/BuildCommand.cs
with method PerformBuild
which sets BuildTarget
and BuildTargetGroup
taken from arguments. I mostly started from examples given in https://docs.unity3d.com/Manual/CommandLineArguments.html
It looks something like this:
using UnityEngine;
using UnityEditor;
using System.Linq;
using System;
static class BuildCommand
{
static string GetArgument (string name)
{
string[] args = Environment.GetCommandLineArgs ();
for (int i = 0; i < args.Length; i++) {
if (args [i].Contains (name)) {
return args [i + 1];
}
}
return null;
}
static string[] EnabledScenes ()
{
return (
from scene in EditorBuildSettings.scenes
where scene.enabled
select scene.path
).ToArray ();
}
static BuildTarget GetBuildTarget ()
{
string target = GetArgument ("customBuildTarget");
Console.WriteLine (":: Received customBuildTarget " + target);
return (BuildTarget)Enum.Parse (typeof(BuildTarget), target);
}
static BuildTargetGroup GetBuildTargetGroup ()
{
string targetGroup = GetArgument ("customBuildTargetGroup");
Console.WriteLine (":: Received customBuildTargetGroup " + targetGroup);
return (BuildTargetGroup)Enum.Parse (typeof(BuildTargetGroup), targetGroup);
}
static string GetBuildPath ()
{
string buildPath = GetArgument ("customBuildPath");
Console.WriteLine (":: Received customBuildPath " + buildPath);
if (buildPath == "") {
throw new Exception ("customBuildPath argument is missing");
}
return buildPath;
}
static BuildOptions GetBuildOptions ()
{
string buildOptions = GetArgument ("customBuildOptions");
return buildOptions == "AcceptExternalModificationsToPlayer" ? BuildOptions.AcceptExternalModificationsToPlayer : BuildOptions.None;
}
static string getEnv(string key, bool secret = false, bool verbose = true) {
var env_var = Environment.GetEnvironmentVariable(key);
if (verbose) {
if (env_var != null) {
if (secret) {
Console.WriteLine(":: env['" + key + "'] set");
} else {
Console.WriteLine(":: env['" + key + "'] set to '" + env_var + "'");
}
} else {
Console.WriteLine(":: env['" + key + "'] is null");
}
}
return env_var;
}
static void PerformBuild ()
{
Console.WriteLine (":: Preparing build");
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions ();
buildPlayerOptions.locationPathName = GetBuildPath ();
buildPlayerOptions.options = GetBuildOptions ();
buildPlayerOptions.scenes = EnabledScenes ();
buildPlayerOptions.target = GetBuildTarget ();
buildPlayerOptions.targetGroup = GetBuildTargetGroup ();
Console.WriteLine ("locationPathName: " + buildPlayerOptions.locationPathName);
Console.WriteLine ("target: " + buildPlayerOptions.target);
Console.WriteLine ("targetGroup: " + buildPlayerOptions.targetGroup);
Console.WriteLine ("scenes: " + buildPlayerOptions.scenes);
Console.WriteLine ("assetBundleManifestPath: " + buildPlayerOptions.assetBundleManifestPath);
Console.WriteLine (":: Performing build");
BuildPipeline.BuildPlayer (buildPlayerOptions);
Console.WriteLine (":: Done with build");
}
}
Thanks I'll give this a shot. Just adding buildTarget had no effect though. Not sure what you mean by " Did you try building with the application first?". If you mean, did I try building via the GUI, it gives me the error "Failed to initialize unity graphics" upon startup, presumably because I'm connected remotely via "ssh -X". That's why I was trying the command-line build. I can create a directory called Assets/Editor and put your text in there, but... how to get Unity to recognize its existence? ...alternatively, if there's a way to get the Unity GUI to stop crashing when forwarding X11, well, my numerous searches haven't found anything useful yet! (e.g. https://forum.unity.com/threads/running-a-linux-build-on-a-remote-x-server.466295/)
Oh I see, yes I meant building via the GUI. $$anonymous$$aybe you can setup a dual boot on your machine and try the project for linux there first. You'll at least have some clues of why your project isn't building correctly.
how to get Unity to recognize its existence?
From the above shell commands, it's the -execute$$anonymous$$ethod BuildCommand.PerformBuild
parameter that says execute PerformBuild
from BuildCommand
file. This file goes here: Assets/Editor/BuildCommand.cs
. I am personally creating builds from $$anonymous$$acOS and use the script to build for Windows, Linux and $$anonymous$$ac with only a few command lines, using same command, but with different environment variables each time.
Your answer
