大家好 今天,我们在测试中还有另一个Microsoft项目。 通过文章的标题,您可以猜测这次开发人员无法通过大量错误来取悦我们。 我们希望该名称的作者不会受到冒犯。 毕竟,少数错误是极好的,不是吗? 但是,在Azure PowerShell代码中发现了一些有趣的东西。 我们建议您熟悉该项目的功能,并查看PV#C分析仪PVS-Studio所发现的错误。
关于项目
Azure PowerShell是一个cmdlet,可让您直接从
PowerShell命令行管理
Azure资源。 该集合的主要目的是简化Azure的学习和开发的快速入门。 Azure PowerShell为管理员和开发人员提供了用于创建,部署和管理Microsoft Azure应用程序的强大功能。
Azure PowerShell在.NET Standard环境中开发,并且适用于Windows的PowerShell 5.1和适用于所有平台的PowerShell 6.x及更高版本。 GitHub上提供了Azure PowerShell
源代码 。
最近,Microsoft项目经常引起我的注意。 我认为这些项目的质量通常处于最佳状态。 当然,尽管并非没有例外,但文章“
WinForms:错误,福尔摩斯 ”也是如此。 但是,这次一切正常。 该项目很大:6845个.cs文件的源代码包含大约70万行,不包括空白(测试以及第三级可靠性的警告,我没有考虑在内)。 如此大量的代码很少有错误:不超过一百个。 有许多相同类型的情况,因此对于本文,我选择了最有趣的肯定。 正如我通常所做的那样,错误是通过PVS-Studio诊断编号进行排序的。
我还遇到了看起来像错误的代码片段,但是由于我对PowerShell的开发功能还不够熟悉,所以我无法对一个实际问题做出明确的结论。 我希望读者中将有这方面的专家,并将对我有所帮助。 关于它下面。
在“汇报”开始之前,我注意到该项目在结构上的特殊性。 Azure PowerShell源代码包含70多个Visual Studio解决方案。 一些解决方案包括其他解决方案中的项目。 这种结构使分析速度有所降低(不多)。 其余的验证没有造成困难。 为方便起见,在错误消息的行中(在括号中),我将指示检测到此错误的解决方案的名称。
验证结果
V3001在'||'的左侧和右侧有相同的子表达式'strTimespan.Contains(“ M”)'。 操作员。 AzureServiceBusCmdletBase.cs 187(事件网格)
public static TimeSpan ParseTimespan(string strTimespan) { .... if (strTimespan.Contains("P") || strTimespan.Contains("D") || strTimespan.Contains("T") || strTimespan.Contains("H") || strTimespan.Contains("M") || strTimespan.Contains("M")) .... }
一个相当明显的错误的示例,只有开发人员才能解决。 在这种情况下,我们是要处理不影响任何代码的重复代码,还是应该在最后两个检查之一中代替
“ M” ,这是完全无法理解的。
V3001在'&&'运算符的左侧和右侧有相同的子表达式'this.AggregationType!= Null'。 GetAzureRmMetricCommand.cs 156(监控器)
public AggregationType? AggregationType { get; set; } .... protected override void ProcessRecordInternal() { .... string aggregation = (this.AggregationType != null && this.AggregationType.HasValue) ? this.AggregationType.Value.ToString() : null; .... }
这里可能没有错误。 这是冗余代码的示例。 有时,此类代码可能表明开发人员知识水平不足。 事实是
this.AggregationType!= Null和
this.AggregationType.HasValue检查是相同的。 使用其中之一(任意)就足够了。 就个人而言,我更喜欢
HasValue选项 :
string aggregation = this.AggregationType.HasValue ? this.AggregationType.Value.ToString() : null;
V3003检测到使用'if(A){...} else if(A){...}'模式。 存在逻辑错误的可能性。 检查行:152,163。GetAzureRmRecoveryServicesBackupProtectionPolicy.cs 152(RecoveryServices)
public override void ExecuteCmdlet() { .... if( WorkloadType == Models.WorkloadType.AzureVM ) { .... } .... else if( WorkloadType == Models.WorkloadType.AzureFiles ) { if( BackupManagementType != Models.BackupManagementType.AzureStorage ) { throw new ArgumentException( Resources.AzureFileUnsupportedBackupManagementTypeException ); } serviceClientProviderType = ServiceClientHelpers. GetServiceClientProviderType( Models.WorkloadType.AzureFiles ); } else if( WorkloadType == Models.WorkloadType.AzureFiles ) { if( BackupManagementType != Models.BackupManagementType.AzureStorage ) { throw new ArgumentException( Resources.AzureFileUnsupportedBackupManagementTypeException ); } serviceClientProviderType = ServiceClientHelpers. GetServiceClientProviderType( Models.WorkloadType.AzureFiles ); } .... }
else两个
if块绝对相同,包括块的条件和主体。 在工作中使用复制粘贴方法时,通常会发生此类错误。 再次的问题是此错误的严重性。 如果这不是简单的代码重复,那么我们可以谈谈缺少必要的验证和相应的操作集。 作者需要编辑代码。
V3005已将 “ this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent”变量分配给它自己。 SetAzureVMOperatingSystemCommand.cs 298(计算)
public override void ExecuteCmdlet() { ....
该属性的值已分配给自身。 看一下他的广告:
[JsonProperty(PropertyName = "provisionVMAgent")] public bool? ProvisionVMAgent { get; set; }
JsonProperty描述说:“指示Newtonsoft.Json.JsonSerializer始终序列化具有指定名称的成员”。 似乎一切都很简单,并且有明显的错误。 同样令人困惑的是,此方法显式地使用来访问属性。 也许是由于错误而未指定其他变量来代替
this 。 但是目前,我们不会得出结论。 事实是,在Azure PowerShell代码中,我遇到了很多此类分配(该属性已分配给自身)。 这是与错误非常相似的分配的另一个示例:
V3005将'this.LastHeartbeat'变量分配给它自己。 PSFabricDetails.cs 804(RecoveryServices)
public ASRInMageAzureV2SpecificRPIDetails( InMageAzureV2ReplicationDetails details) { this.LastHeartbeat = this.LastHeartbeat;
注意第二和以后的作业。 在表达式的右侧,根本没有出现,而是出现了
细节 。 看一下
this.LastHeartbeat属性的声明:
public DateTime? LastHeartbeat { get; set; }
最后,在
InMageAzureV2ReplicationDetails类中查找具有相同名称的
属性 。 在那里声明了这样的属性:
public class InMageAzureV2ReplicationDetails : ReplicationProviderSpecificSettings { .... [JsonProperty(PropertyName = "lastHeartbeat")] public DateTime? LastHeartbeat { get; set; } .... }
好吧,在这种情况下,我准备承认该操作是一个真正的错误。 但是,如何处理以下触发器? 在它们中,与前两个代码片段不同,它们具有多个属性分配。 这已经不像是一个错误:
- V3005将'this.ResourceGroupName'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionCommand.cs 84(CognitiveServices)
- V3005将'this.ExpressRouteGatewayName'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionConnectionCommand.cs 85(CognitiveServices)
- V3005将'this.Name'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionCommand.cs 86(CognitiveServices)
[Cmdlet(VerbsCommon.Remove, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ExpressRouteConnection", DefaultParameterSetName = CortexParameterSetNames.ByExpressRouteConnectionName, SupportsShouldProcess = true), OutputType(typeof(bool))] public class RemoveExpressRouteConnectionCommand : ExpressRouteConnectionBaseCmdlet { [Parameter( Mandatory = true, ParameterSetName = CortexParameterSetNames.ByExpressRouteConnectionName, HelpMessage = "The resource group name.")] [ResourceGroupCompleter] [ValidateNotNullOrEmpty] public string ResourceGroupName { get; set; } .... public override void Execute() { if (....) { this.ResourceGroupName = this.ResourceGroupName; this.ExpressRouteGatewayName = this.ExpressRouteGatewayName; this.Name = this.Name; } .... } .... }
Execute方法包含三个连续的属性分配给自己。 为了以防万一,我给出了
RemoveExpressRouteConnectionCommandCommand类的完整声明及其所有属性,以及
ResourceGroupName属性的声明(其他两个属性以相同的方式声明)。 正是这种触发使我想到了一个问题:“这是一个错误吗?” 我怀疑PowerShell开发会在某种程度上发生内部魔术。 我希望读者中有一些对此事有知识的专家。 我不准备在这种情况下下任何结论。
V3006已创建对象,
但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 259(RecoveryServices)
private void StartRPITestFailover() { .... if (....) { .... } else { new ArgumentException( Resources .UnsupportedDirectionForTFO);
跳过
throw关键字。 而且,评论说应该抛出异常。 在
RecoveryServices解决方案中,我遇到了更多类似的错误:
- V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 305(RecoveryServices)
- V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 278(RecoveryServices)
- V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 322(RecoveryServices)
- V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 421(RecoveryServices)
- V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 452(RecoveryServices)
V3022表达式“ apiType.HasValue”始终为false。 ApiManagementClient.cs 1134(ApiManagement)
private string GetApiTypeForImport(...., PsApiManagementApiType? apiType) { .... if (apiType.HasValue) { switch(apiType.Value) { case PsApiManagementApiType.Http: return SoapApiType.SoapToRest; case PsApiManagementApiType.Soap: return SoapApiType.SoapPassThrough; default: return SoapApiType.SoapPassThrough; } } return apiType.HasValue ?
工作逻辑被违反。 如果
apiType包含一个值,则控件将不会在方法末尾到达
return表达式(所有
switch分支均包含
return )。 否则,该方法将始终分别返回
PsApiManagementApiType.Http.ToString(“ g”)和
apiType.Value.ToString(“ g”) 。
V3022表达式'automationJob!= Null && automationJob == null'始终为false。 NodeConfigurationDeployment.cs 199(自动化)
public NodeConfigurationDeployment( ...., Management.Automation.Models.Job automationJob = null, ....) { .... if (automationJob != null && automationJob == null) return; .... }
矛盾的代码。 两项相互矛盾的检查。 可能第二个
空相等检查包含错误的变量。
V3022表达式始终为假。 DataFactoryClient.Encrypt.cs 37(DataFactory)
public virtual string OnPremisesEncryptString(....) { .... if ( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService && linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService && linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService && (value == null || value.Length == 0)) { throw new ArgumentNullException("value"); } .... }
检查是没有意义的,并且永远不会引发异常。 该条件需要将
linkedServiceType变量同时等同
于三个不同的值。 &&和||运算符可能会混淆。 更正的代码:
if (( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService || linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService || linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService) && (value == null || value.Length == 0)) ....
V3022表达式'Ekus == null'始终为false。 PSKeyVaultCertificatePolicy.cs 129(KeyVault)
internal CertificatePolicy ToCertificatePolicy() { .... if (Ekus != null) { x509CertificateProperties.Ekus = Ekus == null ? null : new List<string>(Ekus); } .... }
Ekus变量是否相等的多余检查。 可能没有错,但是代码看起来很丑。
V3023考虑检查此表达式。 表达式过多或打印错误。 PolicyRetentionObjects.cs 207(RecoveryServices)
public virtual void Validate() { if (RetentionTimes == null || RetentionTimes.Count == 0 || RetentionTimes.Count != 1) { throw new ArgumentException( Resources.InvalidRetentionTimesInPolicyException); } }
检查过多或状态错误。 检查
RetentionTimes.Count == 0毫无意义,因为在那之后检查
RetentionTimes.Count!= 1 。
V3025格式错误。 调用“格式”功能时,期望格式项目的数量不同。 未使用的参数:this.ResourceGroupName。 NewScheduledQueryRuleCommand.cs 117(监控器)
protected override void ProcessRecordInternal() { .... if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {0}", this.Name, this.ResourceGroupName))) { .... } .... }
格式字符串错误。
{0}限定符使用两次,两个参数传递给
Format方法。 正确的选项:
if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {1}", this.Name, this.ResourceGroupName))) ....
另一个类似的错误:
- V3025格式错误。 调用“格式”功能时,期望格式项目的数量不同。 未使用的参数:this.ResourceGroupName。 RemoveScheduledQueryRuleCommand.cs 88(监视器)
V3042可能为NullReferenceException。 '?。' 和“。” 运算符用于访问“ imageAndOsType”对象VirtualMachineScaleSetStrategy.cs 81(计算)的成员
internal static ResourceConfig<VirtualMachineScaleSet> CreateVirtualMachineScaleSetConfig(...., ImageAndOsType imageAndOsType, ....) { .... VirtualMachineProfile = new VirtualMachineScaleSetVMProfile { OsProfile = new VirtualMachineScaleSetOSProfile { ...., WindowsConfiguration = imageAndOsType.CreateWindowsConfiguration(),
创建
VirtualMachineScaleSetVMProfile对象时,使用
imageAndOsType变量而不检查
null 。 但是,然后,在创建
VirtualMachineScaleSetStorageProfile时 ,已使用条件访问运算符对该变量进行了两次检查。 该代码看起来不安全。
V3042可能为NullReferenceException。 '?。' 和“。” 运算符用于访问“ existingContacts”对象的成员RemoveAzureKeyVaultCertificateContact.cs 123(KeyVault)
public override void ExecuteCmdlet() { .... List<PSKeyVaultCertificateContact> existingContacts; try { existingContacts = this.DataServiceClient. GetCertificateContacts(VaultName)?.ToList(); } catch (KeyVaultErrorException exception) { .... existingContacts = null; } foreach (var email in EmailAddress) { existingContacts.RemoveAll(....);
与正常执行的情况一样,由于处理了异常,
现存的Contacts变量可以为
null ,之后将继续工作。 在代码中,此变量无需任何验证即可使用。
V3066传递给“ PersistSyncServerRegistration”方法的参数的可能错误顺序:“ storageSyncServiceUid”和“ discoveryUri”。 EcsManagementInteropClient.cs 364(StorageSync)
public class EcsManagementInteropClient : IEcsManagement { .... public int PersistSyncServerRegistration(....) { return m_managementObject.PersistSyncServerRegistration( serviceUri, subscriptionId, storageSyncServiceName, resourceGroupName, clusterId, clusterName, storageSyncServiceUid,
分析器怀疑将参数传递给
PersistSyncServerRegistration方法的顺序
混乱 。 方法声明:
public interface IEcsManagement : IDisposable { .... int PersistSyncServerRegistration( [In, MarshalAs(UnmanagedType.BStr)] string serviceUri, [In, MarshalAs(UnmanagedType.BStr)] string subscriptionId, [In, MarshalAs(UnmanagedType.BStr)] string storageSyncServiceName, [In, MarshalAs(UnmanagedType.BStr)] string resourceGroupName, [In, MarshalAs(UnmanagedType.BStr)] string clusterId, [In, MarshalAs(UnmanagedType.BStr)] string clusterName, [In, MarshalAs(UnmanagedType.BStr)] string discoveryUri,
确实,这里有些东西与参数7和8混在一起。 作者需要验证代码。
V3077 “ GetGuid”属性的设置器未使用其“值”参数。 RecoveryServicesBackupCmdletBase.cs 54(RecoveryServices)
public abstract class RecoveryServicesBackupCmdletBase : AzureRMCmdlet { .... static string _guid; protected static string GetGuid { get { return _guid; } set { _guid = Guid.NewGuid().ToString(); } } .... }
设置器不使用传输的参数。 相反,他们获得了一个新的GUID,并将其分配给
_guid字段。 我认为大多数读者都会同意这样的代码看起来至少很难看。 使用这样的构造不是很方便:要(重新)初始化
GetGuid属性,必须为它分配一些假值,这是完全不明显的。 但是,当作者自己如何使用这种构造的那一刻,我感到最开心的是。 在代码中,只有一个地方可以使用
GetGuid 。 看一下:
public override void ExecuteCmdlet() { .... var itemResponse = ServiceClientAdapter.CreateOrUpdateProtectionIntent( GetGuid ?? Guid.NewGuid().ToString(), ....); .... }
太好了!
V3091实证分析。 字符串文字中可能存在拼写错误:“管理组ID”。 “ Id”一词可疑。 Constants.cs 36(资源)
public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id";
分析器在为
GroupName常量分配的字符串中指示可能的错误。 结论是基于对其他分配的实证分析,并考虑了变量名。 我认为在这种情况下,分析器是正确的,
GroupName常量的值应为“ Management Group name”。 该错误可能是由于
复制了
GroupId常量的值而导致的,但是他们忘记更改了它。
另一个类似的错误:
- V3091实证分析。 字符串文字中可能存在错字。 “名称”一词可疑。 ParamHelpMsgs.cs 153(RecoveryServices)
V3093 '|' 运算符同时计算两个操作数。 也许是短路“ ||” 应该使用运算符代替。 PSKeyVaultCertificatePolicy.cs 114(KeyVault)
internal CertificatePolicy ToCertificatePolicy() { .... if (!string.IsNullOrWhiteSpace(SubjectName) || DnsNames != null || Ekus != null || KeyUsage != null |
有人怀疑发生了错误,并且在
if块的最后一个条件之间也应使用||运算符。 经常发生的确切答案只能由开发人员提供。
V3095在对null进行验证之前,已使用“证书”对象。 检查行:41,43。CertificateInfo.cs 41(自动化)
public CertificateInfo( ...., Azure.Management.Automation.Models.Certificate certificate) { .... this.Name = certificate.Name; if (certificate == null) return; .... }
经典版 首先使用该对象,然后才检查该链接是否为
null 。 我们
经常遇到这样的错误。 考虑另一个类似的错误。
V3095在对null进行验证之前,已使用'clusterCred'对象。 检查行:115、118。InvokeHiveCommand.cs 115(HDInsight)
public override void ExecuteCmdlet() { .... _credential = new BasicAuthenticationCloudCredentials { Username = clusterCred.UserName, Password = clusterCred.Password.ConvertToString() }; if (clusterConnection == null || clusterCred == null) .... }
还有更多类似的错误:
- V3095在验证是否为null之前,已使用'_profile'对象。 检查行:47,49。RMProfileClient.cs 47(帐户)
- V3095在对null进行验证之前,已使用'this.LoadBalancer.BackendAddressPools'对象。 检查行:56,63。AddAzureRmLoadBalancerBackendAddressPoolConfigCommand.cs 56(CognitiveServices)
- 通常,在Azure PowerShell代码中,我遇到了很多V3095错误。 但是它们都非常相似,因此我将不作更详细的介绍。
V3125在验证了null之后使用了“ startTime”对象。 检查行:1752、1738。AutomationPSClientDSC.cs 1752(自动化)
private string GetNodeReportListFilterString( ...., DateTimeOffset? startTime, ...., DateTimeOffset? lastModifiedTime) { .... if (startTime.HasValue) { odataFilter.Add("properties/startTime ge " + this.FormatDateTime(startTime.Value));
这也是一种相当常见的错误类型。 首次使用时
,检查了
startTime变量的值。 下次使用时,请不要使用。 但是情况可能更糟。 看一下第二个
if块。 我认为根本不应该有一个
startTime变量。 这可以通过在使用前不检查其值是否存在以及为传递给
Add方法而形成的字符串来表明。 该行的第一部分提到另一个变量(
lastModifiedTime )。
V3125在验证了null之后使用了“ firstPage”对象。 检查行:113、108。IntegrationAccountAgreementOperations.cs 113(LogicApp)
public IList<IntegrationAccountAgreement> ListIntegrationAccountAgreements(....) { var compositeList = new List<IntegrationAccountAgreement>(); var firstPage = this.LogicManagementClient. IntegrationAccountAgreements.List(....); if (firstPage != null) { compositeList.AddRange(firstPage); } if (!string.IsNullOrEmpty(firstPage.NextPageLink))
另一个明显的错误。 变量
firstPage的使用不安全,尽管在代码的较早版本中,已将此变量与对
null的初步检查一起使用。
Azure PowerShell代码中的
V3125比
之前描述的
V3095更
成功 。 它们也都是同一类型。 我认为我们可以将自己限制在我们所研究的两个方面。
V3137分配了'apiVersionSetId'变量,但未在函数末尾使用。 GetAzureApiManagementApiVersionSet.cs 69(ApiManagement)
public String ApiVersionSetId { get; set; } .... public override void ExecuteApiManagementCmdlet() { .... string apiVersionSetId; if (ParameterSetName.Equals(ContextParameterSet)) { .... apiVersionSetId = ApiVersionSetId; } else { apiVersionSetId = ....; } if (string.IsNullOrEmpty(ApiVersionSetId))
分析器报告本地变量
apiVersionSetId已初始化,但尚未使用。 通常,这种模式表示错误。 考虑到局部变量
apiVersionSetId的名称和属性
ApiVersionSetId的名称仅在首字母不同的情况下,我认为在这种情况下出错的可能性很高。 看一下代码。 初始化
apiVersionSetId (以一种或另一种方式)后,在代码中仅使用
ApiVersionSetId属性。 非常非常可疑。
V3137分配了'cacheId'变量,但在函数末尾未使用该变量。 RemoveAzureApiManagementCache.cs 94(ApiManagement)
public String CacheId { get; set; } .... public override void ExecuteApiManagementCmdlet() { .... string cacheId; if (....) { .... cacheId = InputObject.CacheId; } else if (....) { .... cacheId = cache.CacheId; } else { .... cacheId = CacheId; } var actionDescription = string.Format(...., CacheId);
这种情况几乎完全重复了先前考虑的情况。 初始化后不使用局部变量
cacheId 。 而是使用名称非常相似的属性
CacheId 。 我不知道,也许在Azure PowerShell开发人员中就是这种模式。 但这似乎是一个错误。
V3143 '值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountPartnerCommand.cs 67(LogicApp)
[Parameter(Mandatory = false, HelpMessage = "The integration account partner type.", ValueFromPipelineByPropertyName = false)] [ValidateSet("B2B", IgnoreCase = false)] [ValidateNotNullOrEmpty] public string PartnerType { get { return this.partnerType; } set { value = this.partnerType; }
partnerType字段
的声明如下:
与检测到此错误的解决方案的名称(LogicApp)相反,我在这里看不到逻辑。 在设置器中使用
值进行记录的情况并不罕见,但是在这种情况下,我们正在谈论丢失原始值。 看起来很奇怪。 该代码对该属性具有单个读取访问权限。 也许您应该再次寻求专家的建议。 也许我听不懂。 事实是,我遇到了更多完全相同的模式:
- V3143'值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountSchemaCommand.cs 79(LogicApp)
- V3143'值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountSchemaCommand.cs 87(LogicApp)
- V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountPartnerCommand.cs 67(LogicApp)
- V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountSchemaCommand.cs 80(LogicApp)
- V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountSchemaCommand.cs 88(LogicApp)
结论
这就是在Azure PowerShell代码中发现的所有有趣的错误。 热心者和有兴趣的人,我建议对这个(或任何其他)项目的代码中的错误进行独立研究。
我可能会错过其他有趣的事情。为此,只需下载并安装PVS-Studio即可。感谢您的阅读。无代码的代码!
如果您想与说英语的读者分享这篇文章,请使用以下链接:Sergey Khrenov。
Azure PowerShell:几乎无害。