我们有一个MSBuild进程,当前执行一组脚本,其中一个是Powershell脚本,它使用了powershell中的一些SMO工具。如果我将MSBuild打印的行复制并粘贴到命令提示符中,它可以正常工作,但无论何时运行MSBuild都无法找到程序集。
我有打印的环境变量,它们是相同的,所以我假设它是.targets
中的属性但是对于我的生活我无法找到一种方法来打印变量&& #39;扫描或知道它的位置。
Could not load file or assembly 'Microsoft.SqlServer.BatchParser, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.]
任何想法或解决方案都有帮助,我很难过?
答案 0 :(得分:5)
我在版本14中遇到了完全相同的问题。我已经编辑了这个答案,因为我发现了我的问题的本质:msbuild正在产生32位PowerShell,就像我从&#34运行PowerShell一样;运行& #34;或快捷方式是64位。
这是手动复制的问题:
PS C:\Windows\SysWOW64\WindowsPowerShell\v1.0> [Environment]::Is64BitProcess
False
PS C:\Windows\SysWOW64\WindowsPowerShell\v1.0> Invoke-Sqlcmd
Invoke-Sqlcmd : Could not load file or assembly 'Microsoft.SqlServer.BatchParser, Version=14.100.0.0, Culture=neutral,
PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.
At line:1 char:1
+ Invoke-Sqlcmd
+ ~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Invoke-Sqlcmd], FileNotFoundException
+ FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
PS C:\Windows\SysWOW64\WindowsPowerShell\v1.0>
当我运行64位版本时, Invoke-Sqlcmd 正常工作:
PS C:\Windows\System32\WindowsPowerShell\v1.0> [Environment]::Is64BitProcess
True
PS C:\Windows\System32\WindowsPowerShell\v1.0> Invoke-Sqlcmd
PS C:\Windows\System32\WindowsPowerShell\v1.0>
如上所述,调用Invoke-Sqlcmd正在工作(不会导致异常)。 在这个阶段,我不知道为什么Sqlcmd缺少一些32位组件。
这就是我调用我的msbuild项目的方式:
msbuild -version 2>NUL || CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat"
CALL msbuild build-MYPROJECT.proj /Target:Build
我在msbuild项目中的一个目标是通过 Exec 标记调用powershell.exe:
<Exec ContinueOnError="False" Command="$(PowerShellExe) .\Scripts\upgrade-projects.ps1 $(SqlServer) '$(TempPath)\$(TemplateProjDb)_$(AssemblyVersion).sql' $(AssemblyVersion)" />
$(PowerShellExe)的定义如下:
<PowerShellExe>powershell.exe -NonInteractive -ExecutionPolicy Bypass</PowerShellExe>
我假设msbuild会产生默认的64位PowerShell。但它没有(出于某种原因)。
整个混乱;整个星期六花费了我的成本;)是msbuild项目,脚本在我的Windows 10笔记本电脑和我使用的其中一台VM机器上运行得非常好。当我试图在不同的开发机器(也是Windows 10,VS2017,相同的扩展包,所有更新等等)上运行时,我确实提出了上述问题。
所以我尝试将PowerShellExe更改为
<PowerShellExe>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy Bypass .\Scripts\concat-scripts.ps1 </PowerShellExe>
但它仍然执行32位版本。
现在我必须找到msbuild在其他机器上产生32位PowerShell的原因,而在我的笔记本电脑和vm上它是默认的64位。
或者只是...... 如何强制32位msbuild产生64位PowerShell?
此时我已尝试运行64位msbuild(我不喜欢完整路径):
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\amd64\msbuild.exe" build-MYPROJECT.proj
它正在产生64位PowerShell。
如果
那将是我的解决方案VsDevCmd.bat -arch=amd64 -host_arch=amd64
会自动指向msbuild 64bit ...不知怎的,它没有。
问题仍然是为什么在一台机器32bit msbuild产生64位PowerShell而在另一台机器上没有(甚至我提供64位的完整路径)?
答案 1 :(得分:2)
事实证明,微软在两个目录中都意外地包含了32位软件包。
请参阅Microsoft的Charles Gagnon的以下主题,声称这将在更新中尽快修复: https://social.technet.microsoft.com/Forums/office/en-US/7a71121c-83b1-49b4-ad30-3a5f20e7afbf/smo-2017-microsoftsqlserverbatchparserdll-load-error?forum=sqlsmoanddmo
虽然还没有看到修复。这似乎是环保的。这对我的所有环境都没有影响。
答案 2 :(得分:0)
仅供参考:我遇到了同样的问题,但无法通过以下建议步骤进行修复:
就我而言,我有一台新PC(W7-> W10)和新VS(2017-> 2019),更新了SSMS,同时数据库服务器也进行了更新(2016-> 2019)。因此,我没有尝试摆脱依赖关系的方法,而是手动添加了依赖关系,并放置了以下二进制文件:
我通过反复尝试迅速找到了正确的文件(在Program Files文件夹中找到的已安装dll中),并且该应用现在可以正常工作。如果它是生产应用程序,那么下一步将是根据工作的dll来源添加适当的引用。
答案 3 :(得分:0)
当尝试从Visual Studio生成后事件在PowerShell脚本内执行Invoke-Sqlcmd时,我们遇到了相同的问题。在脚本中从x86切换到x64解决了问题:
if ($env:PROCESSOR_ARCHITEW6432 -eq "AMD64") {
Write-Warning "Switching from 32bit to 64bit PowerShell"
$powershell = Join-Path $PSHOME.ToLower().Replace("syswow64","sysnative").Replace("system32","sysnative") powershell.exe
if ($myInvocation.Line) {
&"$powershell" -NonInteractive -NoProfile -ExecutionPolicy Bypass $myInvocation.Line
} else {
&"$powershell" -NonInteractive -NoProfile -ExecutionPolicy Bypass -file "$($myInvocation.InvocationName)" $args
}
exit $lastexitcode
}
积分转到此blogpost