Search Unity

Any way to tell Unity to generate the .sln file via script or command line?

Discussion in 'Editor & General Support' started by BenHymers, Mar 17, 2016.

  1. BenHymers

    BenHymers

    Joined:
    Dec 16, 2014
    Posts:
    30
    Is there any way to tell Unity to generate the solution files through script (perhaps some undocumented API) or through the command line?

    For context - I'd like to run some code analysis tools on my C# code, on a build machine, from the command line. Many of these tools operate on solution files rather than directories of source files.

    I don't want to check in the solution files - that way madness lies.

    As far as I can see they're only generated upon opening a script or the solution from within the Unity editor. Running a command line build doesn't seem generate any solution files, even in Library/ or Temp/.
     
  2. BenHymers

    BenHymers

    Joined:
    Dec 16, 2014
    Posts:
    30
    Bump!

    Isn't this something anyone else would find useful?
     
  3. Chippit

    Chippit

    Joined:
    Jun 21, 2014
    Posts:
    2
    It's a bit late for this reply, but I found this thread while investigating this problem for similar purposes here.

    It's a slightly hacky solution, but you can use EditorApplication.ExecuteMenuItem to call Assets/Create C# Project to create .sln and .csproj files.

    Code (csharp):
    1. EditorApplication.ExecuteMenuItem("Assets/Open C# Project");
    This works at least in 5.4.2f2, but it's likely it'll work in older versions of Unity. In much older versions, that same option was called something different, but it might work in those too.
     
    BenHymers and Dave-Carlile like this.
  4. BenHymers

    BenHymers

    Joined:
    Dec 16, 2014
    Posts:
    30
    That's a great idea Chippit, thanks! Do you know if this works from a build script called using batch mode and '-executeMethod'?

    I ended up writing a Python script to generate solution and project files - it's not perfect (as it requires some knowledge of the Unity project structure) but it's enough to generate a solution file that many command-line tools (e.g. ReSharper) are happy with.
     
  5. Chippit

    Chippit

    Joined:
    Jun 21, 2014
    Posts:
    2
    This is precisely how I have used it, so I can confirm that that works. Unlike when clicking the menu item from a normal running instance of Unity, it also does not attempt to shell execute the file so it won't open it in VS/Monodev/whatever editor you use when you do it from batch mode.
     
    BenHymers likes this.
  6. BenHymers

    BenHymers

    Joined:
    Dec 16, 2014
    Posts:
    30
    Incredible - thanks again, this is a great tip! I'll switch over to your method as soon as my Python version gets out of date as I'm certain it will :)
     
  7. mabakay

    mabakay

    Joined:
    Jun 10, 2016
    Posts:
    20
    It works! :D
     
  8. IvanRibakov

    IvanRibakov

    Joined:
    Jan 23, 2018
    Posts:
    4
    Could someone please elaborate on where does "EditorApplication.ExecuteMenuItem("Assets/Open C# Project");" need to go in order to generate solution file from command line?

    Also, has anyone tried this in headless Unix environment (I'm using docker image for builds)?
     
  9. benbenmushi

    benbenmushi

    Joined:
    Jan 29, 2013
    Posts:
    34
    Hi Ivan,

    You need to put this code in a static function inside a class then call it like so from your terminal:

    "/Applications/Unity2017.3.1p4/Unity.app/Contents/MacOS/Unity" -batchmode -logFile -quit -projectPath "/Users/Developer/Documents/MyUnityProject" -executeMethod "MyClass.MyFunction"
     
    hmird likes this.
  10. Water_SS

    Water_SS

    Joined:
    Aug 3, 2015
    Posts:
    1
    This generates a "Library" folder, but doesn't seem to be generating any .csproj or .sln files for me. I'm on Win10.

    I put this in a .cs class in my project:
    Code (CSharp):
    1. public static void createSLN()
    2.     {
    3.         UnityEditor.EditorApplication.ExecuteMenuItem("Assets/Open C# Project");
    4.     }
    and then used this to call the method:
    Code (CSharp):
    1. "C:\Program Files\Unity\Editor\Unity.exe" -batchmode -logFile -quite -projectPath <Project/Path>" -executeMethod "Game.createSLN"
     
    idbrii likes this.
  11. BenHymers

    BenHymers

    Joined:
    Dec 16, 2014
    Posts:
    30
    Is your class definitely called 'Game'? Is it available to the editor, i.e. in an 'Editor' folder? You've misspelled '-quit'.

    Also something catching me out recently is that sometimes VSTU doesn't connect properly; I had to hook it up by choosing the external script editor in the preferences screen of Unity (find and choose devenv.exe).
     
  12. PanayotCankov

    PanayotCankov

    Joined:
    May 28, 2018
    Posts:
    16
    On our CI we use the Unity Test Runner to run some tests:
    https://docs.unity3d.com/Manual/PlaymodeTestFramework.html

    Unity.exe -runTests -projectPath PATH_TO_YOUR_PROJECT -testResults C:\temp\results.xml -testPlatform editmode

    To run the tests Unity creates a .sln used to build the project code.
    I think it is pretty convenient to run CA&SA after that.

    I hope this may help someone.
     
  13. godszerg86

    godszerg86

    Joined:
    Dec 19, 2018
    Posts:
    10
    It seems like it doesn't generate solution file anymore. OR it generates it in Temp folder which is deleted after the test is done
     
  14. van800

    van800

    JetBrains Employee

    Joined:
    May 19, 2016
    Posts:
    73
    Last edited: Mar 4, 2019
  15. JanWosnitzaSAS

    JanWosnitzaSAS

    Joined:
    Jan 9, 2018
    Posts:
    1
    Turns out, you don't even need a wrapper function. You can directly call
    UnityEditor.SyncVS.SyncSolution()
    from commandline. :)

    Unity.exe -projectPath PROJECT_PATH -batchmode -quit -nographics -logFile - -executeMethod "UnityEditor.SyncVS.SyncSolution"
     
  16. mdab121

    mdab121

    Joined:
    May 28, 2018
    Posts:
    2
    This requires your project to compile. We have an issue with auto generated code (from Entitas). The auto-generated code is gitignored, so I wanted to generate it as the first step of my CI/CD build. However this requires a `.csproj` to be generated first.
    Unfortunately, running `UnityEditor.SyncVS.SyncSolution` from command line fails, as the project doesn't compile. This is strange, because it's possible from Unity's menu item `Assets/Open C# Project`.

    Any ideas?
     
  17. benbenmushi

    benbenmushi

    Joined:
    Jan 29, 2013
    Posts:
    34
    @mdab121 I suppose the correct workaround for this is to ensure you code compile when calling SyncSolution from command line.

    I purposely made a error in my c#:

    Aborting batchmode due to failure:
    Scripts have compiler errors.

    Unity wont even call SyncSolution from command line (so no .sln or .csproj will be generated).
    I dont know about any workaroud to avoid unity to abort batchmode.
     
  18. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    768
    Unity already has a suitable static method. Generating the solution is just this one command, no need to add editor script

    Code (CSharp):
    1. Unity.exe  -batchmode -nographics -logFile - -executeMethod UnityEditor.SyncVS.SyncSolution -projectPath . -quit
     
  19. xdegtyarev

    xdegtyarev

    Joined:
    Jul 2, 2012
    Posts:
    9
    But how to do it with already opened unity. I use sublime text and now 2019.3 ignores creation of sln files.
     
  20. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    109
    You can't unity can't have two open editor to the same project.
     
  21. xdegtyarev

    xdegtyarev

    Joined:
    Jul 2, 2012
    Posts:
    9
    I've actually made a symlink named code.exe that points to sublime text 3, which gave me a list of options to enable generation of .csproj (and .sln) files. upload_2020-3-19_12-49-10.png
     
    van800, BoteRock and benbenmushi like this.
  22. matkoniecz

    matkoniecz

    Joined:
    Feb 23, 2020
    Posts:
    170
    (1) Any idea how to do this on Linux? I am starting Unity via UnityHub, so I have no idea where Unity is installed, so solutions from https://forum.unity.com/threads/any...e-sln-file-via-script-or-command-line.392314/ are not applicable.

    (2)
    openingUnityHub
    selecting three dot menu of given project
    advanced project settings
    adding "-executeMethod UnityEditor.SyncVS.SyncSolution" as a parameter

    appears to be not working

    (3)
    I reviewed Edit | Project settings and see nothing applicable there.
     
    Last edited: Mar 21, 2020
  23. BoteRock

    BoteRock

    Joined:
    Jan 10, 2013
    Posts:
    9
    Brilliant! Thank you!
     
  24. Shouffee

    Shouffee

    Joined:
    Dec 29, 2021
    Posts:
    1
    At first I didn't catch "symlink" here so I didn't think to try this on Linux, but it absolutely works -- I just named my shell script to launch Neovim `code.exe` and now I get all the LSP goodies.
     
  25. Dream_Code_TM

    Dream_Code_TM

    Joined:
    Jul 19, 2013
    Posts:
    38
    Can someone help with settings for Windows .exe settings for neovim
    How properly set External Script Editor and External Script Editor Args
     
  26. nonemec

    nonemec

    Joined:
    Nov 13, 2018
    Posts:
    9
    Most of this has been said in some form before in this thread, here the reliably solution I created - explanation inline. Just drop into an Assets/Editor/ folder in your project and call via `Unity.exe -executeMethod "UnityEditor.SyncVS.SyncSolution"`

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEditor;
    4. using Unity.CodeEditor;
    5. using System.Reflection;
    6. using Microsoft.Unity.VisualStudio.Editor;
    7.  
    8. // The recommended way to create the VisualStudio SLN from the command line is a call
    9. // Unity.exe -executeMethod "UnityEditor.SyncVS.SyncSolution"
    10. //
    11. // Unfortunately, as of Unithy 2021.3.21f1 the built-in UnityEditor.SyncVS.SyncSolution internally calls
    12. // Unity.CodeEditor.CodeEditor.Editor.CurrentCodeEditor.SyncAll() where CurrentCodeEditor depends on the user preferences
    13. // which may not actually be set to VS on a CI machine.
    14. // (see https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/CodeEditor/SyncVS.cs)
    15. //
    16. // This routine provides an re-implementation that avoids reliability on the preference setting
    17. // Unity.exe -executeMethod "UnityEditor.SyncVS.SyncSolution"
    18. public static class SyncVS_Workaround
    19. {
    20.     public static void SyncSolution()
    21.     {
    22.         // Ensure that the mono islands are up-to-date
    23.         AssetDatabase.Refresh();
    24.  
    25.         List<IExternalCodeEditor> externalCodeEditors;
    26.  
    27.         // externalCodeEditors = Unity.CodeEditor.Editor.m_ExternalCodeEditors;
    28.         // ... unfortunately this is private without any means of access. Use reflection to get the value ...
    29.         externalCodeEditors = CodeEditor.Editor.GetType().GetField("m_ExternalCodeEditors", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(CodeEditor.Editor) as List<IExternalCodeEditor>;
    30.  
    31.         foreach (var externalEditor in externalCodeEditors)
    32.             if (externalEditor is VisualStudioEditor vse)
    33.             {
    34.                 vse.SyncAll();
    35.                 Debug.Log($"called {vse}.SyncAll");
    36.                 return;
    37.             }
    38.  
    39.         // When com.unity.ide.visualstudio is installed, we should never get here
    40.         Debug.LogError("no VisualStudioEditor registered");
    41.     }
    42. }
    43.  
     
    badomate likes this.