Skip to main content
The 2024 Developer Survey results are live! See the results
deleted 5 characters in body
Source Link
Fred
  • 3.4k
  • 4
  • 37
  • 57

The program I am writing is using System.Management.Automation library to make use of powershellPowerShell classes and interfaces that are defined there. There are two versions of those libraries: 1.0.0.0 and 3.0.0.0. Windows Server 2008 has in its GAC version 1.0 and Windows Server 2012 has in its GAC both 1.0 and 3.0.

To be able to use this library in the VS project, I have to reference it. Now it is a decision to make, which one should I reference? Well, since both servers have 1.0 in their GAC, it should be safe to reference to the 1.0 one. Still, just in case, I'll copy it locally if there was some rare (or common?) case where it doesn't exist in the GAC.

Example code of using this library:

using (PowerShell PS = PowerShell.Create())
{

    PS.AddScript("Import-Module ServerManager")
        .Invoke();
}

The Import-Module Servermanager command causes powershellPowerShell to import another dll, Microsoft.Windows.ServerManager. Here the problem starts.

Windows Server 2008 has only version 6.1.0.0 of this library where Windows Server 2012 has version 6.3.0.0. I assume that Automation's 1.0 to 6.1 and 3.0 to 6.3 version similarity is not a coincidence.

When I'm using my program on Windows Server 2008, it works fine but when I am trying to use it on Windows Server 2012, this Automation 1.0 assembly is trying to load ServerManager assembly version 6.1 (!) which 2012 doesn't have. 2012 would prefer to use Automation assembly v3.0 and load ServerManager v6.3.

I assume there is some way to "tell" the program to load assembly X if server version Y and assembly A if server version B but where does it go? How can I be sure then that I wont encounter some server where there will be version 2.0 or 4.0 or whatever.

The problem is that I can't reference (copy locally) the ServerManager assembly because (I think) as long as I can "tell" my program where it should look for assemblies, I can't tell the Automation's assembly where to look for other assemblies. By analysis using procmon, I could see as it exactly knew where to look for because it instantly navigated to C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ServerManager to look for the ServerManager assembly.

The possible solutions I know are:

  1. I could try to dynamically load the assemblies without referencing to them in visual studionstudio using Assembly.Load() and dynamic object for which using, as someone suggested, I should burn in fiery hell (I assume that person referred to that it's extremely bug prone).

  2. I can add the assemblies I need to GAC but this may lead to some dependency hell because the both Automation and ServerManager may have lots of other dependencies and I only right now discovered two of them.

What other options do I have?

The program I am writing is using System.Management.Automation library to make use of powershell classes and interfaces that are defined there. There are two versions of those libraries: 1.0.0.0 and 3.0.0.0. Windows Server 2008 has in its GAC version 1.0 and Windows Server 2012 has in its GAC both 1.0 and 3.0.

To be able to use this library in the VS project, I have to reference it. Now it is a decision to make, which one should I reference? Well, since both servers have 1.0 in their GAC, it should be safe to reference to the 1.0 one. Still, just in case, I'll copy it locally if there was some rare (or common?) case where it doesn't exist in the GAC.

Example code of using this library:

using (PowerShell PS = PowerShell.Create())
{

    PS.AddScript("Import-Module ServerManager")
        .Invoke();
}

The Import-Module Servermanager command causes powershell to import another dll, Microsoft.Windows.ServerManager. Here the problem starts.

Windows Server 2008 has only version 6.1.0.0 of this library where Windows Server 2012 has version 6.3.0.0. I assume that Automation's 1.0 to 6.1 and 3.0 to 6.3 version similarity is not a coincidence.

When I'm using my program on Windows Server 2008, it works fine but when I am trying to use it on Windows Server 2012, this Automation 1.0 assembly is trying to load ServerManager assembly version 6.1 (!) which 2012 doesn't have. 2012 would prefer to use Automation assembly v3.0 and load ServerManager v6.3.

I assume there is some way to "tell" the program to load assembly X if server version Y and assembly A if server version B but where does it go? How can I be sure then that I wont encounter some server where there will be version 2.0 or 4.0 or whatever.

The problem is that I can't reference (copy locally) the ServerManager assembly because (I think) as long as I can "tell" my program where it should look for assemblies, I can't tell the Automation's assembly where to look for other assemblies. By analysis using procmon, I could see as it exactly knew where to look for because it instantly navigated to C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ServerManager to look for the ServerManager assembly.

The possible solutions I know are:

  1. I could try to dynamically load the assemblies without referencing to them in visual studion using Assembly.Load() and dynamic object for which using, as someone suggested, I should burn in fiery hell (I assume that person referred to that it's extremely bug prone).

  2. I can add the assemblies I need to GAC but this may lead to some dependency hell because the both Automation and ServerManager may have lots of other dependencies and I only right now discovered two of them.

What other options do I have?

The program I am writing is using System.Management.Automation library to make use of PowerShell classes and interfaces that are defined there. There are two versions of those libraries: 1.0.0.0 and 3.0.0.0. Windows Server 2008 has in its GAC version 1.0 and Windows Server 2012 has in its GAC both 1.0 and 3.0.

To be able to use this library in the VS project, I have to reference it. Now it is a decision to make, which one should I reference? Well, since both servers have 1.0 in their GAC, it should be safe to reference to the 1.0 one. Still, just in case, I'll copy it locally if there was some rare (or common?) case where it doesn't exist in the GAC.

Example code of using this library:

using (PowerShell PS = PowerShell.Create())
{

    PS.AddScript("Import-Module ServerManager")
        .Invoke();
}

The Import-Module Servermanager command causes PowerShell to import another dll, Microsoft.Windows.ServerManager. Here the problem starts.

Windows Server 2008 has only version 6.1.0.0 of this library where Windows Server 2012 has version 6.3.0.0. I assume that Automation's 1.0 to 6.1 and 3.0 to 6.3 version similarity is not a coincidence.

When I'm using my program on Windows Server 2008, it works fine but when I am trying to use it on Windows Server 2012, this Automation 1.0 assembly is trying to load ServerManager assembly version 6.1 (!) which 2012 doesn't have. 2012 would prefer to use Automation assembly v3.0 and load ServerManager v6.3.

I assume there is some way to "tell" the program to load assembly X if server version Y and assembly A if server version B but where does it go? How can I be sure then that I wont encounter some server where there will be version 2.0 or 4.0 or whatever.

The problem is that I can't reference (copy locally) the ServerManager assembly because (I think) as long as I can "tell" my program where it should look for assemblies, I can't tell the Automation's assembly where to look for other assemblies. By analysis using procmon, I could see as it exactly knew where to look for because it instantly navigated to C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ServerManager to look for the ServerManager assembly.

The possible solutions I know are:

  1. I could try to dynamically load the assemblies without referencing to them in visual studio using Assembly.Load() and dynamic object for which using, as someone suggested, I should burn in fiery hell (I assume that person referred to that it's extremely bug prone).

  2. I can add the assemblies I need to GAC but this may lead to some dependency hell because both Automation and ServerManager may have lots of other dependencies and I only right now discovered two of them.

What other options do I have?

Notice removed Authoritative reference needed by CommunityBot
Bounty Ended with no winning answer by CommunityBot
Notice added Authoritative reference needed by Mike
Bounty Started worth 100 reputation by Mike
changed tag [assembly] to [.net-assembly]
Link
rkhb
  • 14.3k
  • 7
  • 35
  • 60
Source Link
Mike
  • 863
  • 1
  • 11
  • 34

Cross platform system libraries reference for PowerShell and Server Manager module

The program I am writing is using System.Management.Automation library to make use of powershell classes and interfaces that are defined there. There are two versions of those libraries: 1.0.0.0 and 3.0.0.0. Windows Server 2008 has in its GAC version 1.0 and Windows Server 2012 has in its GAC both 1.0 and 3.0.

To be able to use this library in the VS project, I have to reference it. Now it is a decision to make, which one should I reference? Well, since both servers have 1.0 in their GAC, it should be safe to reference to the 1.0 one. Still, just in case, I'll copy it locally if there was some rare (or common?) case where it doesn't exist in the GAC.

Example code of using this library:

using (PowerShell PS = PowerShell.Create())
{

    PS.AddScript("Import-Module ServerManager")
        .Invoke();
}

The Import-Module Servermanager command causes powershell to import another dll, Microsoft.Windows.ServerManager. Here the problem starts.

Windows Server 2008 has only version 6.1.0.0 of this library where Windows Server 2012 has version 6.3.0.0. I assume that Automation's 1.0 to 6.1 and 3.0 to 6.3 version similarity is not a coincidence.

When I'm using my program on Windows Server 2008, it works fine but when I am trying to use it on Windows Server 2012, this Automation 1.0 assembly is trying to load ServerManager assembly version 6.1 (!) which 2012 doesn't have. 2012 would prefer to use Automation assembly v3.0 and load ServerManager v6.3.

I assume there is some way to "tell" the program to load assembly X if server version Y and assembly A if server version B but where does it go? How can I be sure then that I wont encounter some server where there will be version 2.0 or 4.0 or whatever.

The problem is that I can't reference (copy locally) the ServerManager assembly because (I think) as long as I can "tell" my program where it should look for assemblies, I can't tell the Automation's assembly where to look for other assemblies. By analysis using procmon, I could see as it exactly knew where to look for because it instantly navigated to C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ServerManager to look for the ServerManager assembly.

The possible solutions I know are:

  1. I could try to dynamically load the assemblies without referencing to them in visual studion using Assembly.Load() and dynamic object for which using, as someone suggested, I should burn in fiery hell (I assume that person referred to that it's extremely bug prone).

  2. I can add the assemblies I need to GAC but this may lead to some dependency hell because the both Automation and ServerManager may have lots of other dependencies and I only right now discovered two of them.

What other options do I have?