簡體   English   中英

我可以檢測我的代碼是否在 Azure 輔助角色中執行嗎?

[英]Can I detect if my code is executing in an Azure worker role?

我有一些在 Winforms 應用程序、Windows 服務和 Azure 輔助角色中使用的共享程序集/項目。

如果我在 Azure 角色中運行,有什么方法可以在運行時檢測到。

我找到了如何檢測是否正在運行 Azure 模擬器:

 Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.IsEmulated

但這並不能滿足我的要求。 我也不想在我的共享程序集中添加對任何 Azure 程序集的引用。

理想情況下,我想要類似於我用來檢測是作為控制台還是作為服務運行的東西:

System.Environment.UserInteractive

有什么東西可以給我這個邏輯嗎?

對於任何感興趣的人,我想我會分享我是如何實施的,感謝@Sandrino Di Mattia 的回答:

您可以檢查 RoleRoot 環境變量是否存在(至少對於雲服務):

請注意,這並不適合 Winforms 應用程序,因為我實際上只在最后需要它用於服務 - 即檢測運行為

  • Azure 工作者角色
  • 視窗服務
  • 控制台應用程序

這是一個大綱:

public static class ServiceRunner
{
    private static bool IsAzureWorker
    { 
        get { return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("RoleRoot")); } 
    }

    public static void Run(string[] args)
    {
        if (IsAzureWorker)
        {
            //Running as Azure Worker
        }
        else if (Environment.UserInteractive) //note, this is true for Azure emulator too
        {
            //Running as Console App
        }
        else
        {
            //Running as Windows Service
        }
    }
}

您可以檢查 RoleRoot 環境變量是否存在(至少對於雲服務):

或者,為什么不簡單地在您的配置中添加一個設置(AppSettings 或 Service Configuration):

  <appSettings>
    ...
    <add key="AppEnvironment" value="Azure.CloudService|Azure.Website" />
  </appSettings>

然后您可以簡單地檢查該設置是否存在具有特定值以查看您正在運行的位置。 這也意味着在您的(自動)構建或部署過程中,您需要包含此設置(例如,這可以使用 XDT)。

我們通過批處理文件將環境變量(在本例中為 INAZURE)設置為啟動任務。

SetEnvVar.cmd 批處理文件的內容:

setx INAZURE True /M

配置批處理文件以通過您的 cscfg 文件啟動:

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

然后寫一些東西來讀取這個環境變量。 您可以使用 Azure SDK 中的靜態 RoleEnvironment 類,但這引用了令人討厭的非托管程序集,這些程序集使構建服務器配置成為 PITA。 在更新的 Azure SDK 版本中,情況可能變得更好。

我有一篇密切相關的博客文章: http : //adrianwithy.com/2012/02/06/remove-msshrtmi-dll-as-a-dependency-in-your-azure-project/

當我在 web 角色中嘗試“RoleRoot”環境變量時,它返回 null,不幸的是破壞了上面顯示的優雅解決方案。 也許微軟自 2013 年以來改變了一些東西,或者解決方案只對工人角色有效,而不是網絡角色。

我看到下面的替代方案適用於即用型配置的 webrole(未運行提升)。 盡管角色默認作為“網絡服務”運行,但它可以檢測到“f:\\RoleModel.xml”的存在。 這可能是必需的,因為配置文件包含角色啟動代碼中所需的信息。 請注意,代碼不依賴於實際的驅動器號,在未來的 Azure 映像中可能會發生變化:

/// <summary>
/// Returns true if the application is detected to be running in an Azure role (tested for web roles).
/// </summary>
public static bool RunningInAzure
{
  get
  {
    try
    {
      string sCurrentDrive = Path.GetPathRoot(AppDomain.CurrentDomain.BaseDirectory);
      if (!string.IsNullOrEmpty(sCurrentDrive))
        return File.Exists(Path.Combine(sCurrentDrive, "RoleModel.xml"));
    }
    catch { }
    return false;
  }
}

已針對 Web 角色進行測試,但我希望它對工作角色的工作方式相同(如果不是,請發表評論)。

就像您說的那樣,添加對所有最終產品的引用並不是要走的路。 我會說這是一個使用依賴注入很容易解決的問題。

定義產生此信息的接口(在共享程序集中):

public enum DeploymentType { WinForms, WinServices, Azure }

public interface IWhatDeploymentAmIUsing {
    DeploymentType DeploymentType { get; }
}

並創建一個實現此接口的類。

WinForms(在您的 winforms 項目中):

public class WinFormDeploymentType : IWhatDeploymentAmIUsing {
    public DeploymentType DeploymentType { get { return DeploymentType.WinForms; } }
}

WinServices(在您的 Windows 服務項目中):

public class WinServicesDeploymentType : IWhatDeploymentAmIUsing {
    public DeploymentType DeploymentType { get { return DeploymentType.WinServices; } }
}

Azure(在您的 azure 項目中):

public class AzureDeploymentType : IWhatDeploymentAmIUsing {
    public DeploymentType DeploymentType { get { return DeploymentType.Azure; } }
}

現在使用您最喜歡的 DI 工具將其連接起來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM