Skip to content

//css_resource fails to resolve relative paths #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
maettu-this opened this issue Mar 7, 2018 · 13 comments
Closed

//css_resource fails to resolve relative paths #107

maettu-this opened this issue Mar 7, 2018 · 13 comments

Comments

@maettu-this
Copy link
Collaborator

Here's the situation using standard settings:

cscs.exe .\ProjectWithResources\MyScripts\Script.cs
Error: Specified file could not be compiled.

System.ApplicationException: Cannot compile resources: ResGen : error RG0000: Couldn't find input file "C:\Users\<User>\AppData\Local\Temp\CSSCRIPT\Cache\-1741293711\.\FormWithResources.resx"
1 error(s).

   at csscript.CSSUtils.CompileResource(String file, String out_name)
   at csscript.CSExecutor.Compile(String scriptFileName)
   at csscript.CSExecutor.ExecuteImpl()

Same situation when explicitly compiling to a .dll file:

cscs.exe -c:0 -out:.\ProjectWithResources\MyScripts\Script.dll .\ProjectWithResources\MyScripts\Script.cs
Error: Specified file could not be compiled.

System.ApplicationException: Cannot compile resources: ResGen : error RG0000: Couldn't find input file "C:\Users\<User>\AppData\Local\Temp\CSSCRIPT\Cache\-1741293711\.\FormWithResources.resx"
1 error(s).

   at csscript.CSSUtils.CompileResource(String file, String out_name)
   at csscript.CSExecutor.Compile(String scriptFileName)
   at csscript.CSExecutor.ExecuteImpl()

Here's the project:
ProjectWithResources.zip

Note that \Properties\Resources.resx is properly compiled into \Properties\Resources.resources (//css_resource ..\Properties\Resources.resx, ..\Properties\Resources.resources; in \MyScripts\Script.cs).

But compilation of FormWithResources.resx failes. Looks like //css_resource path resolution has an issue with redirection from \MyScripts\Script.cs to \MyForms\FormWithResources.cs to FormWithResources.resx.

@oleg-shilo
Copy link
Owner

oleg-shilo commented Mar 8, 2018

Yes this is a problem. //css_resource does not seem to handle '.' as expected.
The defect is fixed now.

Though in your sample there are some other inconsistencies that prevent it from working. The fix instructions below is also a work around for you until the release is out:

In 'Script.cs' replace

//css_resource ..\Properties\Resources.resx, ..\Properties\Resources.resources;

with

//css_resource ..\MyForms\FormWithResources.resx, ..\MyForms\FormWithResources.resources;

Remove //css_resource .\FormWithResources.resx, .\FormWithResources.resources;
from 'FormWithResources.cs' as it is a duplication. Both 'Scrip.cs' and 'FormWithResources.cs' reference the same resource file.

You can also omit 'FormWithResources.resources;' part. It is optional:

//css_resource ..\MyForms\FormWithResources.resx

@maettu-this
Copy link
Collaborator Author

Thanks for quick evaluation and fix! Also thanks for the hint on the optional second part of the //css_resource directive. By the way, CSScript.chm section Using Resources simply states //css_resource <file>; though it rather is //css_resource <resourceFile>[ <compiledFile>];.

Regarding the inconsistencies:

The attached reduced project may not require ..\Properties\Resources.resx, but if a project contains overall resources (icons, strings,...) it does require it.

Also, my project requires that the compiled resource file name explicitly contains the <FullNamespace>, i.e.:
//css_resource ..\Properties\Resources.resx, ..\Properties\<Project>.Properties.Resources.resources;

Otherwise a runtime error will be thrown:

    System.Resources.MissingManifestResourceException: Für die angegebene Kultur oder die neutrale Kultur konnten keine Ressourcen gefunden werden. Stellen Sie sicher, dass <FullNamespace>.FormWithResources.resources beim Kompilieren richtig in die Assembly Script eingebettet wurde, oder dass die erforderlichen Satellitenassemblys geladen werden können und vollständig signiert sind.
    Stack:
        bei System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
        bei System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
        bei System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
        bei System.Resources.ResourceManager.GetObject(String name, CultureInfo culture, Boolean wrapUnmanagedMemStream)
        bei <FullNamespace>.FormWithResources.InitializeComponent() in <Workspace>\FormWithResources.Designer.cs:Zeile 74.
        bei <FullNamespace>.FormWithResources..ctor() in <Workspace>\FormWithResources.cs:Zeile 81.
        bei <Project>.Script.Main() in <Workspace>\Script.cs:Zeile 118.

The message says something like "Could not find resources for the given or neutral culture. Ensure that <FullNamespace>.FormWithResources.resources has been correctly embedded into the assembly script, or the required satalite assemblies have been loaded and are properly signed.".

Seems as if the Visual Studio Designer has some additional requirements or constraints regarding the resource file names.

@oleg-shilo
Copy link
Owner

Yes it does.
But in my test that ambiguous Could not find resources for the given or neutral culture... has gone after the proper fix (or even work around) has been applied.
I am marking it now as ready for the release.

@oleg-shilo
Copy link
Owner

I have also updated the documentation with the //css_resource <resourceFile>[ <compiledFile>];.
Thank you.

oleg-shilo added a commit that referenced this issue Mar 15, 2018
* CS-Script.Core
- Issue #106: Fix netstandard2 version to work in 4.6.1 and fix ReferenceDomainAssemblies
- Fix netstandard2 version to work in 4.6.1 and fix ReferenceDomainAssemblies

* CS-Script
- Issue #108: Option to no longer suppress TargetInvocationException in AsmBrowser
- Fixed problem with `cscs -config:get` not handling the properties containing '_'
- Issue #107: //css_resource fails to resolve relative paths
- Solved problem with `MarshalByRefObjectWithInfiniteLifetime` being defined in both cscs and CSScriptLibrary
- Renamed MarshalByRefObjectWithInfiniteLifetime -> CSScriptLibrary.MarshalByRefObjectWithInfiniteLifetime
- Processing feedback on #98 fixes.
@maettu-this
Copy link
Collaborator Author

maettu-this commented Mar 15, 2018

I confirm that the previously supplied sample now works. But in my environment I have one more indirection (once more related to NUnit testing), and I still get an error indicating that something is wrong with handling indirections:

Cannot compile resources: ResGen : error RG0000: Couldn't find input file "<ScriptDirectory>\.\SomeInfoForm_WithResources.resx"

...if I specify...

//css_resource .\SomeInfoForm_WithResources.resx, .\<Namespace>.SomeInfoForm_WithResources.resources;

...and...

Cannot compile resources: ResGen : error RG0000: Couldn't find input file "<ScriptDirectory>\SomeInfoForm_WithResources.resx"

...if I specify...

//css_resource SomeInfoForm_WithResources.resx, .\<Namespace>.SomeInfoForm_WithResources.resources;

...i.e. without preceeding ".\".

Problem:
It must not be "<ScriptDirectory>\SomeInfoForm_WithResources.resx" but rather "<FormDirectory>\SomeInfoForm_WithResources.resx"!

I have tried to reproduce this issue with this modified sample that has an additional indirection:
ProjectWithResources.zip

However, the error I get now is different:

cscs.exe .\ProjectWithResources\MyScripts\Script.cs
Error: Specified file could not be compiled.

System.IO.FileNotFoundException: Cannot import "..\MyLibrary\Scriptlets\View.cs" from the "<Root>\ProjectWithResources\MyScripts\Script.cs" script. --->
System.IO.FileNotFoundException: Cannot import "..\Forms\FormWithResources.cs" from the "<Root>\ProjectWithResources\MyLibrary\Scriptlets\View.cs" script. --->
System.IO.FileNotFoundException: Could not find file "..\Forms\FormWithResources.cs".
Ensure it is in one of the CS-Script search/probing directories.
   at CSScriptLibrary.FileParser.ResolveFilesDefault(String file, String[] extraDirs, Boolean throwOnError)
   at CSScriptLibrary.FileParser.ResolveFile(String file, String[] extraDirs, Boolean throwOnError)
   at CSScriptLibrary.FileParser..ctor(String fileName, ParsingParams prams, Boolean process, Boolean imported, String[] searchDirs, Boolean throwOnError)
   at CSScriptLibrary.ScriptParser.ProcessFile(ScriptInfo fileInfo)
   at CSScriptLibrary.ScriptParser.ProcessFile(ScriptInfo fileInfo)
   at CSScriptLibrary.ScriptParser.ProcessFile(ScriptInfo fileInfo)
   at CSScriptLibrary.ScriptParser.ProcessFile(ScriptInfo fileInfo)
   at CSScriptLibrary.ScriptParser.Init(String fileName, String[] searchDirs)
   at csscript.CSExecutor.Compile(String scriptFileName)
   at csscript.CSExecutor.ExecuteImpl()

When executing this script from my hosting application, everything works fine.

So, there must still be something wrong in handling the current directory or the directory path of an indirected scriptlet.

Again, no need to hurry, it's just some of my NUnit generated test cases that throw an exception (due to the additional indirection). Running the scripts manually works fine (one indirection less).

@oleg-shilo
Copy link
Owner

I guess that in this case if you have Cannot import "..\MyLibrary\Scriptlets\View.cs" erro and since the path is relative analyzing Environment.CurrentDirectory befoe the csscript.CSExecutor.Compile call can give you a clue.

One of the things that I really disliked about MSTest and NUnit (though in less degree) is that they always insist on performing the test outside of the project file structure. I appreciate their motivation, but the file structure may also be a reflection of the production runtime conditions. May be if you force NUnit to perform the test ion the solution location instead of the temp dirs the problem will be solved.

@maettu-this
Copy link
Collaborator Author

I fully agree that the file structure matters, actually I consider it the only truth. That's also the reason why I insisted on proper resolution of relative paths, and that relative paths should be considered relative to the file where the path is stated.

I will debug the NUnit case at a later moment. (As mentioned, I can live with the issue for the moment.) But I ask you to also take a look at the modified sample, since that issue is not related to NUnit. I think it's something not 100% proper in CSScript relative path resolution, unless it is the designed/desired behavior. (And again, no need to hurry.)

@oleg-shilo
Copy link
Owner

I actually had a look at your modified sample and got an impression that the problem with it was detected only during NUnit run.

The sample itself was a ClassLibrary so I assumed you were interacting with it under NUnit runtime.
Changing the project type to Console Application showed no problems at all:

image

Is there something that needs to be done with the code to trigger the problem. Or... may be just the sample package was incomplete...

@oleg-shilo
Copy link
Owner

OK. I guessed.
One needs to run Script.cs outside of VS.
Correct me if I am wrong.

@oleg-shilo
Copy link
Owner

oleg-shilo commented Mar 21, 2018

OK. All sorted....

You may remember one of our earlier discussions that //css_include relative path is always resolved with respect to the process current directory. You convinced me that having the possibility to resolve it with respect to the file containing the '//css_' directive is beneficial. But you may also remember that I considered completely abandoning current directory as reference point for relative paths being too unorthodox.

That's why CS-Script implements a compromised solution. Thus:

  • ..\test.cs. Will be resolved as <current_dir>\..\test.cs
  • .\..\test.cs. Will be resolved as <file_with_directive_dir>\..\test.cs

I will need to write a dedicated Wiki for the referencing path algorithm.

Anyway, your solution can be easily fixed with the following modification:
Before:

//css_import ..\Forms\FormWithResources.cs;
//css_import ..\..\Properties\Resources.Designer.cs;

After:

//css_import .\..\Forms\FormWithResources.cs;
//css_import .\..\..\Properties\Resources.Designer.cs;

Alternative approach is to configure CS-Script to ALWAYS resolve ALL relative paths with respect to script file (seems like your preferred approach). You can do it as this:

cscs -config:set:ResolveRelativeFromParentScriptLocation=true

Then, your code will work without any modification.

@oleg-shilo
Copy link
Owner

I have just added a dedicated section in the https://github.com/oleg-shilo/cs-script/wiki/CLI---User-Guide#hints-and-tips.

@maettu-this
Copy link
Collaborator Author

Yes, this explains it. My hosting application does use ResolveRelativeFromParentScriptLocation=true and thus works, whereas the provided sample couldn't run with the default setting of ResolveRelativeFromParentScriptLocation=false of cscs.exe.

Thanks for adding it to the wiki. I have also improved the comments where I set ResolveRelativeFromParentScriptLocation=true for later reference. Hope I don't fall into this pit again ;-)

From my side, you can close this issue now. One less in the backlog :-))

@oleg-shilo
Copy link
Owner

Great. Everyone is happy. :)

BTW I a back to empty the backlog. Finally :)

Will be engaged mainly with CS-Script.VSCode now. At least for a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants