从 Visual Studio 运行时,PowerShell 脚本结果不同

2021-09-18 00:00:00 visual-studio powershell sql-server

我正在从 Visual Studio 2013 项目的 PostBuild 事件运行 PowerShell 构建脚本.
我为此使用的命令是(添加新行只是为了提高可读性):

I'm running a PowerShell build script from the PostBuild event of a Visual Studio 2013 project.
The command I'm using for that is (new-lines added only for readability):

PowerShell -ExecutionPolicy ByPass -File "$(SolutionDir)..\build\build.ps1" 
  -SolutionFolder "$(SolutionDir)." -ProjectName "$(ProjectName)" 
  -OutputFolder "..\build\output" -ConfigurationName "$(ConfigurationName)"

此脚本的任务之一是查找本地 SQL Server 实例,以允许用户附加所需的数据库(如果它们不存在).
我正在使用以下 PowerShell 代码来检索本地实例:

One of the tasks of this script is to find local SQL Server instances to allow the user to attach required databases if they don't exist.
I'm using the following PowerShell code to retrieve the local instances:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | out-null
$m = New-Object ("Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer") "."

if ($m.ServerInstances -eq $null -or $m.ServerInstances.Length -eq $null -or $m.ServerInstances.Length -eq 0)
{
    throw New-Object [System.Exception] "No instances found."
}

$instances = $m.ServerInstances | % { ($_.Parent.Name + "\" + $_.Name) }

当我从命令行执行脚本时,这工作得很好,但是当我从 PostBuild 事件运行脚本时 $m.ServerInstances 返回 $null.

This is working perfectly fine when I execute the script from the command-line, but when I run the script from the PostBuild event $m.ServerInstances returns $null.

首先想到的是用户权限,但我检查了哪个用户正在执行脚本,它在命令行和 VS PostBuild 中都是一样的.

First thing that came to mind was user rights, but I checked which user is executing the script and it's the same in both command-line and VS PostBuild.

我还尝试了一种从注册表中检索可用实例的不同方法(如此处),结果相同;从命令行运行时它工作正常,但从 VS PostBuild 运行时不返回任何实例.

I've also tried a different approach that retrieves the available instances from the registry (as described here), with the same result; it works fine when running from command-line, but returns no instances when running from VS PostBuild.

所以问题是,从命令行运行和导致这种不同行为的 VS PostBuild 有什么区别?

So the question is, what's the difference between running from command-line and VS PostBuild that is causing this different behaviour?

更新:
从 Visual Studio 运行时,脚本的其他部分会停止运行.
例如,从 cmd.exe 运行脚本时创建 IIS 网站工作正常,但从 VS PostBuild 运行时抛出异常:

UPDATE:
There are other parts of the script that stop functioning when running from Visual Studio.
For example creating an IIS website works fine when running the script from cmd.exe but throws an exception when ran from VS PostBuild:

Exception occurred while creating IIS site : 
  Retrieving the COM class factory for component with CLSID {688EEEE5-6A7E-422F-B2E1-6AF00DC944A6} 
  failed due to the following error : 
  80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

我尝试了各种疯狂的解决方法,例如使用 VS PostBuild 中的 cmd.exe/C 来执行 PowerShell 创建一个新的 PowerShell 脚本,该脚本调用 cmd.exe 来运行 PowerShell.
都给出相同的结果;该脚本在从命令提示符调用时有效,但在从 Visual Studio PostBuild 事件调用时无效.

I've tried all kinds of crazy workaround, like using cmd.exe /C from VS PostBuild to execute PowerShell create a new PowerShell script that calls cmd.exe to run PowerShell.
All give the same result; the script works when called from a command prompt, but not when called from a Visual Studio PostBuild event.

Visual Studio 本身以提升的权限运行.
也在没有提升权限的情况下尝试过,结果是同样的问题.

Visual Studio itself is running with elevated permissions.
Also tried it without elevated permissions and that results in the same issue.

更新 2:
当我从命令提示符使用 MSBuild 构建解决方案以触发调用脚本的 PostBuild 事件时,会出现同样的问题

UPDATE 2:
The same problem occurs when I build the solution with MSBuild from a command prompt to trigger the PostBuild event that calls the script

推荐答案

事实证明,Visual Studio 始终执行 32 位 PowerShell 而不是 64 位.
即使我在 PostBuild 事件中指定了 PowerShell 的完整路径,它仍然执行 32 位版本.

It turns out that Visual Studio always executes the 32-bit PowerShell instead of the 64-bit.
Even when I specified the full path to PowerShell in the PostBuild event, it still executed the 32-bit version.

这导致很多命令不起作用.
我通过使用以下命令调用 PowerShell 解决了这个问题:

That caused a lot of the commands not to work.
I solved it by calling PowerShell with this command:

%WINDIR%\SysNative\WindowsPowerShell\v1.0\PowerShell.exe

这会在我的机器上执行 64 位 PowerShell 并正常运行脚本.

That executes the 64-bit PowerShell on my machine and runs the script fine.

相关文章