DocFX Version Used: 2.28.2
Template used: default
Steps to Reproduce:
<TargetFrameworks> tag to use multiple values like netstandard1.3;net452.docfx.console NuGet package to this project.docfx.json file to include the following information,{
"metadata": [
{
"src": [
{
"files": [
"*.csproj"
],
"exclude": [ "**/bin/**", "**/obj/**" ],
"cwd": "."
}
],
"properties": {
"TargetFrameworks": "net452"
},
"dest": "obj/10.0.2/api",
"shouldSkipMarkup": true
}
],
"build": {
"content": [
{ "files": [ "**/*.yml", "api/*.md" ], "src": "obj/10.0.2", "dest": "10.0.2" }
],
"globalMetadata": {
"_appTitle": "Some Documentation",
"_disableContribution": true,
"_appFooter": " ",
"_navRel": "../toc.html"
},
"template": [
"default",
"template"
],
"overwrite": [
{ "files": [ "obj/10.0.2/overwrite/*.md" ] }
],
"dest": "_site"
}
}
Expected Behavior:
The documentation should be generated without any error.
Actual Behavior:
docfx seemed to be called twice, and the second instance could not access the log file and crashed,
1>[17-12-10 04:36:38.791]Info:[MetadataCommand.ExtractMetadata]Using msbuild C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin as inner compiler.
1>[17-12-10 04:36:38.792]Error:System.IO.IOException: The process cannot access the file 'F:\sharpsnmplib\SharpSnmpLib\log.txt' because it is being used by another process.
1> at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
1> at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
1> at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
1> at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
1> at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
1> at System.IO.StreamWriter..ctor(String path, Boolean append)
1> at Microsoft.DocAsCode.Common.ReportLogListener..ctor(String reportPath, String repoRoot, String root)
1> at Microsoft.DocAsCode.SubCommands.CommandCreator`2.Create(String[] args, ISubCommandController controller, SubCommandParseOption option)
1> at Microsoft.DocAsCode.SubCommands.CompositeCommand..ctor(String[] args, ISubCommandController controller, CompositeOptions options)
1> at Microsoft.DocAsCode.SubCommands.CommandController.Create()
1> at Microsoft.DocAsCode.Program.ExecSubCommand(String[] args)
1>docfx 2.28.2.0
1>Copyright (C) 2017 Copyright c Microsoft docfx 2015-2017
1>This is open-source software under MIT License.
1>
1>
1> Usage1: docfx <docfx.json file path> [-o <output folder path>]
1>
1> Usage2: docfx <subcommand> [<args>]
1>
1>
1>
1>
1>
1>See 'docfx help <command> to read about a specific subcommand guide
1>
1>
1> build : Generate client-only website combining API in YAML files and conceptual files
1> dependency : Export dependency file
1> download : Download remote xref map file and create an xref archive in local.
1> help : Get an overall guide for the command and sub-commands
1> init : Generate an initial docfx.json following the instructions
1> merge : Merge .net base API in YAML files and toc files.
1> metadata : Generate YAML files from source code
1> pdf : Generate pdf file
1> serve : Host a local static website
1> template : List or export existing template
1>
1>
1>Build failed.
1>[17-12-10 04:36:38.830]Error:System.IO.IOException: The process cannot access the file 'F:\sharpsnmplib\SharpSnmpLib\log.txt' because it is being used by another process.
1> at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
1> at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
1> at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
1> at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
1> at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
1> at System.IO.StreamWriter..ctor(String path, Boolean append)
1> at Microsoft.DocAsCode.Common.ReportLogListener..ctor(String reportPath, String repoRoot, String root)
1> at Microsoft.DocAsCode.SubCommands.CommandCreator`2.Create(String[] args, ISubCommandController controller, SubCommandParseOption option)
1>[17-12-10 04:36:38.950]Info:[MetadataCommand.ExtractMetadata]Loading projects...
1> at Microsoft.DocAsCode.SubCommands.CompositeCommand..ctor(String[] args, ISubCommandController controller, CompositeOptions options)
1> at Microsoft.DocAsCode.SubCommands.CommandController.Create()
1> at Microsoft.DocAsCode.Program.ExecSubCommand(String[] args)
1> 0 Warning(s)
1> 1 Error(s)
1>[17-12-10 04:36:38.953]Verbose:[MetadataCommand.ExtractMetadata](F:/sharpsnmplib/SharpSnmpLib/SharpSnmpLib.csproj)Loading project F:/sharpsnmplib/SharpSnmpLib/SharpSnmpLib.csproj
1>C:\Users\lextm\.nuget\packages\docfx.console\2.28.2\build\docfx.console.targets(53,5): error MSB3073: The command ""C:\Users\lextm\.nuget\packages\docfx.console\2.28.2\build\..\tools\docfx.exe" "F:\sharpsnmplib\SharpSnmpLib\docfx.json" -o "" -l "log.txt" --logLevel "Verbose"" exited with code 1.
1>Done building project "SharpSnmpLib.csproj" -- FAILED.
I found that if I change the VS build settings to disable parallel builds I can get past the log.txt in use problem. However, there are still blocking issues. (The API YML files end up in an _Api folder despite having no mention of such a thing in the docfx.json file, so it gets warning that ti is unable to find the toc.yml or toc.md file and ends up with no docs in the final output...)
(DOCFX just seems like an alpha release all around, and ironically has very little in the way of basic usage documentation)
As an alternative to forcing single threaded builds I realized you can add the following property to your project:
<PropertyGroup>
<LogFile>Docfx-$(TargetFramework).log</LogFile>
</PropertyGroup>
This creates a unique log file name for each TargetFramework and therfore they don't collide. Still, a pretty
bad user experience but at least it works.
If you don't disable the default inclusion "globs" then the log files wll become part of your project in VS so you may want to add the following as well:
<ItemGroup>
<None Remove="Docfx-*.log" />
</ItemGroup>
@smaillet the toc warning you got is desired and not related to this file lock issue. That's caused by the "version" parts I used in the docfx.json. If you rip out all "version" related parts, then together with your workaround, the build can be successful.
@lextm - I don't follow that version comment, I'm not building your sample, I'm using my own and I do see that toc warning and the _api folder being generated despite not having any such references. So, yes the warning is legit, however the tool shouldn't be getting into a state where that warning triggers.
In your case you aren't doing a merge, in mine I am, following the comment on Github for handling multiple TargetFrameworks. That is supposed to generate a seperate set of YML files into two distinct temp locations and then merge the results of both into a single result set in the 'api' folder. But that's not at all what is happening
@smaillet Thanks for mentioning the merge operation. I did a quick test but hit another bug #2286 .
Overall, this tool can work in simplest setup, but can break if you really touch the edges. Not surprising, but just hope the issues can be fixed soon.
One of my projects is currently hitting this issue. Is there a workaround for this or is this still awaiting a fix?
What is the solution / work around here?
Is it to edit the proj file as mentioned by @smaillet on Dec 10, 2017? Or any fix expected?
As I found in the documentation, instead of:
"properties": {
"TargetFrameworks": "net452"
},
Should be
"properties": {
"TargetFramework": "net452"
},
As I found in the documentation, instead of:
...
Greetings all... I am investigating DocFX for https://github.com/ExtendedXmlSerializer/ExtendedXmlSerializer/issues/284
And right out of the gate I ran into this issue.
This is my metadata element from the generated docfx.json document after adding docfx.console v2.47.0.0 as a dependency and adding the properties as suggested above:
"metadata": [
{
"src": "*.csproj",
"dest": "api",
"properties": {
"TargetFramework": "netstandard2.0"
},
"disableGitFeatures": false,
"disableDefaultFilter": false
}
],
Perhaps there is something obvious I am missing? I am still getting errors about locked log.txt file. 😞
1>[19-11-16 10:39:35.922]Error:System.IO.IOException: The process cannot access the file '<...>\src\ExtendedXmlSerializer\log.txt' because it is being used by another process.
1> at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
1> at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
1> at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
1> at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
1> at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
1> at System.IO.StreamWriter..ctor(String path, Boolean append)
1> at Microsoft.DocAsCode.Common.ReportLogListener..ctor(String reportPath, String repoRoot, String root)
1> at Microsoft.DocAsCode.SubCommands.CommandCreator`2.Create(String[] args, ISubCommandController controller, SubCommandParseOption option)
1> at Microsoft.DocAsCode.SubCommands.CompositeCommand..ctor(String[] args, ISubCommandController controller, CompositeOptions options)
1> at Microsoft.DocAsCode.SubCommands.CommandController.Create()
1> at Microsoft.DocAsCode.Program.ExecSubCommand(String[] args)
1>docfx 2.47.0.0
This seems to do the trick:
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="docfx.console" Version="2.47.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
Not sure how that's going to work for updating to latest from Nuget, however. 🤷♂️
It would seem that for each TargetFramework defined in the .csproj file, a complete buildset is executing, meaning if you have two elements in your metadata element within your docfx.json (SO MUCH CONFIGURATION 😉) there are two threads working to each build their own sets of netstandard2.0 and net45 documentation.
Even after the logging hack that @smaillet provided, I was still getting lock exceptions on other files because of this.
From this, it would seem that DocFX simply needs to make sure that this build has occurred once per entire build and not once per TargetFrameworks as defined in the .csproj file.