简体   繁体   English

如何在Azure云服务上使用第三方DLL

[英]How to use 3rd party DLL on Azure Cloud Service

I'm creating a service for checking licenses. 我正在创建一个检查许可证的服务。 As part of this service we need to use a 3rd party DLL. 作为此服务的一部分,我们需要使用第三方DLL。 This service (WCF service, C#) is hosted on azure as a Cloud service. 此服务(WCF服务,C#)作为云服务托管在azure上。 After deployment i need to go to the Cloud service's VM to register the DLL manually and give the service the correct rights in IIS to use the 3rd party DLL. 部署之后,我需要转到Cloud服务的VM手动注册DLL,并在IIS中为服务提供正确的权限以使用第三方DLL。

I want to do this configuration in IIS by script/code. 我想通过脚本/代码在IIS中进行此配置。 Because if the cloudservces VM restarts for updates, the configuration is lost and has to be set manually again. 因为如果cloudservces VM重新启动以进行更新,则配置将丢失,必须再次手动设置。

The registration of the DLL itself is done by script (registerCOM.cmd), and is part of the servicedefinition.csdef. DLL本身的注册由脚本(registerCOM.cmd)完成,并且是servicedefinition.csdef的一部分。

<Startup>
  <Task commandLine="RegisterCOM.cmd" executionContext="elevated" taskType="simple" />      
</Startup>

This script contains one entry: 该脚本包含一个条目:

    start "" "lpregister410.EXE"

This script starts an executable and registers the 3rd party DLL. 此脚本启动可执行文件并注册第三方DLL。 So far everything works 到目前为止一切正常

But I cannot get the service to consume the DLL by script. 但我无法通过脚本获得服务DLL的服务。 That means I can get the service working, but I have to set the IIS manually. 这意味着我可以使服务正常工作,但我必须手动设置IIS。 I this case i have to set the Identity of this application in the application pool from "Network" to "LocalSystem". 在这种情况下,我必须在应用程序池中将此应用程序的标识从“网络”设置为“LocalSystem”。

I'm not an IIS expert, but seeing this option chosen many times and the solution works, I've tried to create this into a powershell script, which is then fired by a cmd (ConfigureIIS.cmd) script: 我不是IIS专家,但是看到这个选项被多次选择并且解决方案有效,我尝试将其创建为powershell脚本,然后由cmd(ConfigureIIS.cmd)脚本触发:

  <Startup>
  <Task commandLine="RegisterCOM.cmd" executionContext="elevated" taskType="simple" />
  <Task commandLine="ConfigureIIS.cmd" executionContext="elevated" taskType="simple" />
</Startup>

This ConfigureIIS.cmd script contains: 此ConfigureIIS.cmd脚本包含:

 PowerShell.exe -NoProfile -ExecutionPolicy Unrestricted  -Command "& '%~dpn0.ps1'"

The PowerShell script does this: PowerShell脚本执行此操作:

Import-Module WebAdministration
$applicationPools = Get-ChildItem IIS:\AppPools 

foreach($pool in $applicationPools)
{    
  If($pool.name.length -gt 32)
    {
        $pool.processModel.identityType = 0
        $pool | Set-Item
        $bool = $true
    }       
}

The idea behind this script is Azure gives random Guid name to the service. 这个脚本背后的想法是Azure为服务提供随机Guid名称。 This Guid contains at least 32 chars. 这个Guid包含至少32个字符。 If found, change the identityType to 0 (LocalSytem) (Only one service is hosted) 如果找到,请将identityType更改为0(LocalSytem)(仅托管一个服务)

Alright, so what is the problem. 好吧,那么问题是什么。 If I run this script manual on the Cloudservices VM, no problem. 如果我在Cloudservices VM上运行此脚本手册,没问题。 Works fine and IIS is correctly set. 工作正常,IIS设置正确。 But when i run a publish, IIS is not set. 但是当我运行发布时,IIS没有设置。 (I think because the service is not yet added to the applicationpool, is that a correct assumption?). (我认为因为服务尚未添加到应用程序池中,这是正确的假设吗?)。 When I fire the script from the application it tells me i don't have sufficient rights (I thought that a cloudservice is by default "administrator") 当我从应用程序触发脚本时,它告诉我我没有足够的权限(我认为cloudservice默认是“管理员”)

When I do all above in code like this: 当我在这样的代码中执行以上操作时:

{
                ServerManager serverManager = new ServerManager();                                
                sb.Append("ServerManager Created");
                ApplicationPoolCollection applicationPools = serverManager.ApplicationPools;
                sb.Append("Number of pools detected: " + applicationPools.Count.ToString());          
                foreach (ApplicationPool pool in applicationPools)
                {                   
                    sb.Append(pool.Name);
                    if (pool.Name.Length > 32) {
                        sb.Append(pool.Name + " has been found");                        
                        pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem;                       
                        sb.Append(pool.Name + " has identity been changed to " + pool.ProcessModel.IdentityType.ToString() + ", ");
                        sb.Append("Trying to commit changes, ");
                        serverManager.CommitChanges();
                        sb.Append("Changes Committed ! ");
                    }                       
                }                          
            }

It gives me a "not sufficient permissions" when saving changes at 保存更改时,它给了我“没有足够的权限”

serverManager.CommitChanges(); 

So there is a lot of tekst and explanation, sorry for that, but I hope that someone can give me a push in the right direction. 所以有很多tekst和解释,抱歉,但我希望有人可以给我一个正确的方向。 The main question is how can I use this 3rd party DLL, without manual interaction with the Cloud service. 主要问题是如何在不与云服务进行手动交互的情况下使用此第三方DLL。

According to the documentation : 根据文件

IS may not be fully configured during the startup task stage in the startup process, so role-specific data may not be available. 在启动过程的启动任务阶段,可能无法完全配置IS,因此特定于角色的数据可能不可用。 Startup tasks that require role-specific data should use Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.OnStart. 需要特定于角色的数据的启动任务应使用Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.OnStart。

If the OnStart method doesn't work for you, try to change the taskType of the ConfigureIIS.cmd to background (it will run asynchronously) and adopt the script to wait until the application pools are configured: 如果OnStart方法不适合您,请尝试将ConfigureIIS.cmdtaskType更改为background (它将异步运行)并采用脚本等待,直到配置应用程序池:

 <Startup>
  <Task commandLine="RegisterCOM.cmd" executionContext="elevated" taskType="simple" />
  <Task commandLine="ConfigureIIS.cmd" executionContext="elevated" taskType="background" />
</Startup>

PowerShell script: PowerShell脚本:

Import-Module WebAdministration
$applicationPools = Get-ChildItem IIS:\AppPools 
$yourExpectedAppliactionPoolCount = 1;

while ($applicationPools.Count -lt $yourExpectedAppliactionPoolCount)
{
    Sleep -Seconds 3
}

foreach($pool in $applicationPools)
{    
  If($pool.name.length -gt 32)
    {
        $pool.processModel.identityType = 0
        $pool | Set-Item
        $bool = $true
    }       
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM