Nunit has a path length limitation? - msbuild

Running Nunit console inside a MSBuild project a command is built in order to execute the tests, that command includes about 90 paths, each one is the full path of a compiled test project (.test.dll) and contains at least 100 characters but no more than 150.
When the script run I got the following error:
NUnit version 2.5.10.11092
Copyright (C) 2002-2009 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.
Runtime Environment -
OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
CLR Version: 2.0.50727.5485 ( Net 2.0 )
ProcessModel: Default DomainUsage: Multiple
Execution Runtime: Default
Unhandled Exception:
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Builds\123\XXXX\XXX.Build.Sonar\srcDroplocation\Build\x86\Release\xxxxx.xxxx.CustomTypes.Test.dll'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
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, Boolea
n bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
at NUnit.Core.AssemblyReader.CalcHeaderOffsets()
at NUnit.Core.AssemblyReader..ctor(String assemblyPath)
at NUnit.Util.RuntimeFrameworkSelector.SelectRuntimeFramework(TestPackage package)
at NUnit.Util.DefaultTestRunnerFactory.GetTargetProcessModel(TestPackage package)
at NUnit.Util.DefaultTestRunnerFactory.MakeTestRunner(TestPackage package)
at NUnit.ConsoleRunner.ConsoleUi.Execute(ConsoleOptions options)
at NUnit.ConsoleRunner.Runner.Main(String[] args)
the original path of this file is 'C:\Builds\123\XXXX\XXX.Build.Sonar\src\Droplocation\Build\x86\Release\xxxxx.xxxx.CustomTypes.Test.dll'. The file exists, and I notice that in the exception there is a missing backslash in the path between src and Droplocation.
This issue happens in my build server, in my local machine works, the difference is that in my local machine the folder is not so deep : 'C:\T\XXX\Droplocation\Build\x86\Release\xxxxx.xxxx.CustomTypes.Test.dll'
Is there any restriction regarding the paths for the use of NUnit?
I also try to create a .nunit file in order to put all the references on it but it lead to another issue

Indeed it is bug in NUnit version 2.5.10.11092.
Create a drive unit pointing to C:\Builds\123\XXXX\XXX.Build.Sonar\src\Droplocation
subst t: C:\Builds\123\XXXX\XXX.Build.Sonar\src\Droplocation
change the $(OutDir) from C:\Builds\123\XXXX\XXX.Build.Sonar\src\Droplocation to t:

The missing slash in the middle of your path is caused by your build script, not NUnit. My guess is that the build script is appending two strings together, neither of which have the necessary slash. If the same build script is working on your box, it may be a global variable on the server has no begin/end slash where the variable on your machine does.
Edit: Based on your comment above, you may be running into a Windows limitation. According to this support page, the command prompt is limited to 8191 characters. This limitation is after any environment variables are expanded. You may need to reduce the number of arguments or have the build server compile to a shorter path.

Related

Dotfuscator says "was expecting one of:" when building in Visual Studio

I've got a solution in Visual Studio that includes a Dotfuscator project. The exact same code base builds and obfuscates correctly on another machine (my old laptop), but not on my newly setup laptop. Of course we let our support contract expire since this is used on a legacy project.
The output during the build is:
8>Compiling Project MyAppObfuscation ...
8>Dotfuscator Professional Version 4.41.1.9417-95d9eec7a
8>Copyright 2002-2019 PreEmptive Solutions, LLC All Rights Reserved.
8>Use of this software implies acceptance of accompanying license agreement.
8>Build machine license. This software may be used on binaries for general release.
8>
8>Your protection is out of date. Learn more at https://www.preemptive.com/keep-your-protection-up-to-date?product=dotfuscator&sku=pro&version=4.41.1.9417. Upgrade at https://www.preemptive.com/products/dotfuscator/downloads.
8>
8>Loading Assemblies...
---several of these lines---
8>Running ...\ildasm.exe /OUT=...\MyApp.exe.il /TEXT /NOBAR /RAWEH /QUOTEALLNAMES /UTF8 /LINENUM /FORWARD "...\MyApp.exe"
8>
--- immediately followed by: ---
8>Encountered - at line 18065, column 26.
8>Was expecting one of:
8> <FLOAT64> ...
8> "float64" ...
8> "float32" ...
8> <INT> ...
8> "(" ...
8>
8>Build Error.
8>MyAppObfuscation build failed.
Has anyone encountered this? I'm inclined to believe it's something on the new machine, but if anyone has tips about diagnosing this I would appreciate it.
Thanks!
Edit: Just wanted to add the same error happens in Visual Studio and the Dotfuscator Professional Config Editor.
Edit 2: Upon further inspection, the folder listed in the /OUT parameter of ildasm doesn't contain a .il file for the last ildasm command. The output folder for the assemblies prior to the .exe DO have a .il file. So, I thought ildasm might be failing on the .exe, but I can copy the command into a command prompt and it runs correctly and creates an .il file as expected. So, why would ildasm not work when run from Visual Studio, but would work from the command line -- and only for one assembly / exe in the project?
The mystery grows...
Solved it! I opened Visual Studio Installer on both the old and new machine to compare what features were installed on the old one vs the new one. Most notably, one of the missing features on the Individual components tab was an older .NET Framework SDK (4.6.1 in my case) and an older Windows 10 SDK (10.0.17763.0 in my case).
I hope someone else finds this helpful.

dnu publish, The process cannot access the file

When I publish my dnx web app via dnu publish to an IIS server, it works fine with a script that looks like this
dnu publish pathToLocalSource --out \\appserver\appuat --configuration DEBUG --no-source --runtime dnx-clr-win-x64.1.0.0-beta6
It works fine that is - until someone hits the website and then I can no longer publish due to a file lock
Microsoft .NET Development Utility CLR-x64-1.0.0-beta6-12256
Executing script 'prepare' in project.json
Copying to output path \\appserver\appuat
Using Package dependency Microsoft.AspNet.Mvc 6.0.0-beta6
Adding NuGet package C:\Users\[username]\.dnx\packages\Microsoft.AspNet.Mvc\6.0.0-
beta6\Microsoft.AspNet.Mvc.6.0.0-beta6.nupkg to \\appserver\appuat\approot\packages
Installing Microsoft.AspNet.Mvc.6.0.0-beta6
System.IO.IOException: The process cannot access the file '\\appserver\appuat\approot\packages\Microsoft.AspNet.Mvc\6.0.0-b
eta6\lib\dnx451\Microsoft.AspNet.Mvc.dll' because it is being used by another pr
ocess.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea
n useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share)
at Microsoft.Framework.PackageManager.Publish.PublishOperations.ExtractFiles(
ZipArchive archive, String targetPath, Func`2 shouldInclude)
at Microsoft.Framework.PackageManager.NuGetPackageUtils.ExtractPackage(String
targetPath, FileStream stream)
at Microsoft.Framework.PackageManager.NuGetPackageUtils.<>c__DisplayClass0_0.
<<InstallFromStream>b__0>d.MoveNext()
I can solve this by RDP'ing to the server and executing iisreset
What is the recommended way to get around this? Publish an app_offline.htm first?
app_offline.htm isn't supported by dnx at this time (issue #141) and has no effect.
Issue #141 talks about using WebDeploy to recycle the app pool. I really dislike webdeploy's fiddly setup with magic local security policy incantations and hope to avoid it.
So since this is a UAT box and I can be loose with security settings, I added this to my deploy script:
iisreset $targetMachine /restart
where the executor of the script needs to be a local admin of $targetMachine.

Apache/Perl Cannot Find MDAC without CommonProgramFiles(x86)

I am having a problem with using Apache/Perl to get access to Excel files using Microsoft Data Access Component (MDAC). Somehow I must set the "CommonProgramFiles(x86)" system environment variable in order to get this to work. Otherwise, I keep getting this error message:
System.InvalidOperationException: The .Net Framework Data Providers
require Microsoft Data Access Components(MDAC). Please install
Microsoft Data Access Components(MDAC) version 2.6 or later. --->
System.IO.FileNotFoundException: Retrieving the COM class factory for
component with CLSID {2206CDB2-19C1-11D1-89E0-00C04FD7A829} failed due
to the following error: 8007007e.
The server configuration is:
Windows Server 2008 R2 in 64-bit
Server is installed with Microsoft Access Database Engine 2010
Apache 2.2.25 (that is 32-bit)
Perl 5.12.3 v5 (that is also in 32-bit)
I have my Perl CGI script to call my C# program (that is built for "Any CPU").
The C# program uses MDAC to open and read Excel files (not trying to launch Excel, only try to read data from the Excel files).
I have verified that the server has the latest MDAC available in these 2 folders:
C:\Program Files\Common Files\System\Ole DB
C:\Program Files (x86)\Common Files\System\Ole DB
I have also checked the registries and they look fine. Anyway, I don't have any problem running my C# program directly at the command prompt (it can use MDAC to get access to Excel files). I only have the problem when I use Apache/Perl to use my Perl CGI script to call my C# program (that is when I get that error with MDAC).
I can work around this problem by specifying CommonProgramFiles(x86) in my Perl CGI script, like this:
$ENV{ "CommonProgramFiles(x86)" } = "C:\\Program Files (x86)\\Common Files";
I have this question:
Why do I have this problem? And why setting that CommonProgramFiles(x86) system environment variable can workaround this problem? Why that system environment variable is empty before I set it? Does this have to do with the fact that I am running 32-bit Apache/Perl in a Windows operating system that is 64-bit?
Please help me to understand this issue. Thanks in advance.
(The original version of this post had a question about a second problem. Turned out that problem had to do with an extra double quote in the string. I fixed this, and that problem has gone away. That's why I have removed that second question from the post)
Jay Chan
I did some more research and the issue is the following: until release 2.4.9, the Apache startup routines have mapped "commonprogramfiles(x86)" to "commonprogramfiles_x86_" and that variable does not exists in the environment unless you create it... I have not tested it, but creating that environment variable and making it point to the same location as commonprogramfiles(x86) would probably fix the issue too.
Since the compiled Apache distributions are only using up to version 2.4.46 as we speak, they don't have the fix that allows the parenthesis in environment variables. That's why you still need the PassEnv directive to ensure that Apache passes the correct values to 32-bit CGI scripts.
The following post has some useful details about this:
https://bz.apache.org/bugzilla/show_bug.cgi?id=46751
I used to have the same problem in with Apache 2.4 with dBase compiled apps using ADO-32 bit as dBase is 32-bit. Something has recently changed, possibly with Windows 10 2004 20H2. I needed this fix in July-Aug 2020 but now I don't, the environment variable already exists. Since my Apache version is dated April 2020, that cannot be the reason for the change.
I tried to do some research about this but all I could find is that those environment variables are system ones existing at least since 2017, so why I needed to set this var is a mystery to me, but I would like to understand this, so if you find something, post a follow-up...
https://learn.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables

How Do I Get The Resource DLL Code Samples In The Windows SDKs To Compile And Run?

I am currently trying to build a Resource DLL on on Windows Server 2003 and 2008. I am currently working with the Resource DLL code samples supplied with the Windows SDKs, and I can't get them to work.
On Windows Server 2008 I succeeded compiling the Windows 7 SDK ClipBook Server sample, but couldn't get it to properly work in the cluster. When I insert the resource as a resource type to the cluster using "cluster restype /create /dll" it works, but the resource is listed with an unknown type instead of a ClipBook Server type, as I think it should have as it is the type defined in the Resource DLL's code.
I also succeed in creating a resource of that type, but I can never get it to go Online. I always get the error:
System error 5079 has occurred (0x000013d7).
The specified node does not support a resource of this type. This may be due to version inconsistencies or due to the absence of the resource DLL on this node.
And this is despite the fact that the resource is located on all the nodes in the cluster including the one I try to start the resource on.
On Windows Server 2003, I'm working with the Platform SDK version 5.2, and I can't even get the ClipBook Server Resource DLL code sample to compile. I always get MIDL1001 Error saying that it cannot open the file cluscfgserver.idl. I added the path of the file's location to the include path of the project. That didn't work. When I tried to hard-code the path of the file, I got several linker errors when trying to link with this file.
If anyone knows anything about any of these problems, I would appreciate any input.
Those examples are old and busted. Here are a few things I had to go through to get the similar "File Share Sample" to work:
Convert the project to x64 (supposedly 32 bit resources still work, but I haven't been able to verify that)
Add the module definition file (.def) to the linker input property page so that the Startup function is exposed
There were several spots in code where CompareString is used to check the resource type name and 0 is expected on success, but it actually returns CSTR_EQUAL (3).
This is probably why you get the "(Unknown Type)" name.
To register the resource extension, cluster.exe won't accept spaces in the dll name, so in my case I had to use cluster /REGADMINEXT:'FILESH~2.dll'
Only the Property Sheet extension interface is supported, everything else (context menu, wizards) has been removed as of Server 2008
Check the extension DLL stdafx.cpp sources for the Resource Type "ClipBook Server". It should be "ClipBook Server Sample": const WCHAR g_wszResourceTypeNames[] = L"ClipBook Server Sample\0"

MSBuild "Unable to copy file" in CI environment

I'm using Hudson as a continuous integration server. The jobs ultimately kick off MSBuild. Everyone once in a while, my build fails with a non-code-compilation error out of MSBuild:
C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(2703,9): error MSB3021: Unable to copy file "..\Lib\Microsoft\Microsoft.Practices.Unity.Configuration.dll" to "bin\Debug\Microsoft.Practices.Unity.Configuration.dll". Access to the path 'bin\Debug\Microsoft.Practices.Unity.Configuration.dll' is denied.
When I examine 'bin\Debug\Microsoft.Practices.Unity.Configuration.dll', I find it to be a 0-byte file.
I'm at a loss for why this file is being problematic. Any ideas?
MS Build Copy task has undocumented feature, at least Google keeps silence.
If set system wide environment variable MSBUILDALWAYSRETRY=1
This task will retry to copy a file even it gets Access Denied exception during copy operation
Example of output
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3513): Got System.UnauthorizedAccessException: Access to the path 'C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)
at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
at Microsoft.Build.Tasks.Copy.CopyFileWithLogging(FileState sourceFileState, FileState destinationFileState)
at Microsoft.Build.Tasks.Copy.DoCopyWithRetries(FileState sourceFileState, FileState destinationFileState, CopyFileWithState copyFile) copying C:\Builds\8\28\Sources\Main\Solutions\packages\System.Spatial.5.2.0\lib
et40\fr\System.Spatial.resources.dll to C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll and HR is -2147024891
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3513): Retrying on ERROR_ACCESS_DENIED because MSBUILDALWAYSRETRY = 1
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3513): Could not copy "C:\Builds\8\28\Sources\Main\Solutions\packages\System.Spatial.5.2.0\lib
et40\fr\System.Spatial.resources.dll" to "C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll". Beginning retry 1 in 1000ms. Access to the path 'C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll' is denied.
Sounds like a process is holding bin\Debug\Microsoft.Practices.Unity.Configuration.dll open.
You can check that earlier by renaming 'bin' to something else, like 'bin-old' and then removing 'bin-old' If any process is holding the files in 'bin' open, the rename will fail.
Use Handle.exe from SysInternals (Microsoft) to see which files are being held open by which processes.
Run this at a cmd prompt when you get the error;
Handle.exe > OpenFile.txt
Notepad.exe OpenFile.txt
Then search OpenFile.txt for the file that is locked and you'll see the process.
Ryan
See also http://blogs.msdn.com/aaronhallberg/archive/2007/10/22/error-msb3021-and-team-build.aspx and MSBuild & TeamBuild - BuildInParallel failing because of MSB3021 file permission violation