php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #55847 DOTNET .NET 4.0 GAC new location
Submitted: 2011-10-04 16:23 UTC Modified: 2020-08-06 17:05 UTC
Votes:30
Avg. Score:4.9 ± 0.2
Reproduced:28 of 28 (100.0%)
Same Version:18 (64.3%)
Same OS:8 (28.6%)
From: cosmin dot nicula at gmail dot com Assigned: cmb (profile)
Status: Closed Package: COM related
PHP Version: 5.3.8 OS: Windows XP SP3
Private report: No CVE-ID: None
 [2011-10-04 16:23 UTC] cosmin dot nicula at gmail dot com
Description:
------------
The DOTNET class in PHP seems to "look" only for CLR 2.0 assemblies and not for 
CLR 4.0 assemblies.

Since with .NET Framework 4.0, GAC was split in two, one for each CLR. The CLR 
for both .NET Framework 2.0 and .NET Framework 3.5 is CLR 2.0, and the CLR for 
.NET Framework 4.0 stands separately, not allowing CLR 2.0 applications to see 
CLR 4.0 assemblies.

The CLR 2.0 assemblies directory is located in: %windir%\assembly, whereas the 
CLR 4.0 assemblies directory is located in: %windir%\Microsoft.NET\assembly.

After installing an assembly in the GAC, if the targeted .NET Framework is 2.0 
or 3.5, the DOTNET constructor correctly identifies the Strong Named assembly. 
If the targeted .NET Framework is 4.0, the DOTNET constructor throws an 
exception "PHP Fatal error:  Uncaught exception 'com_exception' with message 
'Failed to instantiate .Net object [CreateInstance] [0x80070002] The system 
cannot find the file specified.", although the assembly is correctly installed 
in the GAC under %windir%\Microsoft.NET\assembly directory with the gacutil 
tool.

Test script:
---------------
Test case1: install an assembly mylibrary.dll in the GAC with targeted .NET Framework 2.0 or 3.5.
%ProgramFiles%\Microsoft SDKs\Windows\v7.0A\bin\gacutil.exe C:\mylibrary.dll
The following PHP snippet (replace ... with relevant info) correctly identifies the Strong Named assembly MyLibrary located in the %windir%\assembly folder.
<?php $myDotNetObject = new DOTNET('MyLibrary, Version=..., Culture=neutral, PublicKeyToken=...', 'MyLibrary.MainFunction'); ?>

Test case2: install an assembly mylibrary.dll in the GAC with targeted .NET Framework 4.0.
%ProgramFiles%\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\gacutil.exe C:\mylibrary.dll
The following PHP snippet (replace ... with relevant info) does not identifies the Strong Named assembly MyLibrary located in the %windir%\Microsoft.NET\assembly folder.
<?php $myDotNetObject = new DOTNET('MyLibrary, Version=..., Culture=neutral, PublicKeyToken=...', 'MyLibrary.MainFunction'); ?>

Expected result:
----------------
The following PHP snippet (replace ... with relevant info) should correctly 
indentify the Strong Named assembly MyLibrary located in the 
%windir%\Microsoft.NET\assembly folder.
<?php $myDotNetObject = new DOTNET('MyLibrary, Version=..., Culture=neutral, 
PublicKeyToken=...', 'MyLibrary.MainFunction'); ?>

Actual result:
--------------
The DOTNET constructor throws an exception "PHP Fatal error:  Uncaught exception 
'com_exception' with message 'Failed to instantiate .Net object [CreateInstance] 
[0x80070002] The system cannot find the file specified."

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-02-17 13:59 UTC] user at kkdf2 dot sakura dot ne dot jp
Is it a problem on php settings, or need an extension to php dotnet?

If it is as a new feature, 
how about access to the newer .NET runtime?

new DOTNET4("...")

or

com.dotnet_runtime = "v4.0.30319" ; in php.ini

new DOTNET("...")

Have a good idea?

Thanks
 [2013-02-18 12:34 UTC] user at kkdf2 dot sakura dot ne dot jp
Hmm, regasm and using COM instead of DOTNET may be likely workaround to solve CLR version issue.
Check the note at dotnet_load function:
http://www.php.net/manual/en/function.dotnet-load.php
 [2013-02-19 11:20 UTC] user at kkdf2 dot sakura dot ne dot jp
I'v tested regasm.

The class library built on .NET 4.0 can be loaded and accessed via "new COM".

Also it seems that .NET runtime 2.0 and 4.0 can work separately in one process memory.

t.php
---
<?php

$v20 = new COM("ClassLibrary1.Class1");
print $v20->Hello();
print "\n";

$v40 = new COM("ClassLibrary40.Class1");
print $v40->Hello();
print "\n";

?>
---

Output of t.php
---
Hello from v2.0.50727 with System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Hello from v4.0.30319 with System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
---

Class1.cs in ClassLibrary1(.NET 3.5)
---
using System;
using System.Runtime.InteropServices;

namespace ClassLibrary1 {
    [ComVisible(true), Guid("ddfe022c-eaf7-4a6a-9429-0f1846af7be7")]
    public class Class1 {
        public string Hello() { return "Hello from " + System.Reflection.Assembly.GetExecutingAssembly().ImageRuntimeVersion + " with " + typeof(String).AssemblyQualifiedName; }
    }
}
---

Class1.cs in ClassLibrary40(.NET 4.0)
---
using System;
using System.Runtime.InteropServices;

namespace ClassLibrary40 {
    [ComVisible(true), Guid("ebd2758d-96b9-4b20-afaa-d67c2c99998f")]
    public class Class1 {
        public string Hello() { return "Hello from " + System.Reflection.Assembly.GetExecutingAssembly().ImageRuntimeVersion + " with " + typeof(String).AssemblyQualifiedName; }
    }
}
---
 [2020-08-06 17:05 UTC] cmb@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2020-08-06 17:05 UTC] cmb@php.net
> Hmm, regasm and using COM instead of DOTNET may be likely
> workaround to solve CLR version issue.

Indeed, a viable workaround.

> com.dotnet_runtime = "v4.0.30319" ; in php.ini

I think an INI setting would be the best solution, because it
might be impossible to detect which version to use.
 [2020-08-06 17:07 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #55847: DOTNET .NET 4.0 GAC new location
On GitHub:  https://github.com/php/php-src/pull/5949
Patch:      https://github.com/php/php-src/pull/5949.patch
 [2020-08-22 10:42 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e6044d4455d7fbaced7f3a6ac28172d963017e51
Log: Fix #55847: DOTNET .NET 4.0 GAC new location
 [2020-08-22 10:42 UTC] cmb@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 11:01:30 2024 UTC