65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Windows Azure 的 WebRole 中运行 EXE

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (4投票s)

2012 年 2 月 21 日

CPOL

6分钟阅读

viewsIcon

59842

downloadIcon

3

在 Windows Azure 的 WebRole 中运行 EXE

引言

Azure 是微软的云计算操作系统,它支持在云中托管和运行应用程序。云只不过是微软的数据中心。应用程序以角色的形式托管在云中。角色主要有两种:Web 角色和工作角色。这两种角色有不同的目的。

Web 角色:应用程序中托管在 IIS 中的部分,在云中托管时应创建为 Web 角色。例如:WCF、ASP.NET、Silverlight 等。Web 角色直接接受来自客户端的请求并响应。Web 角色充当应用程序用户和工作角色之间的桥梁。

工作角色:顾名思义,工作角色完成 Web 角色分配的任务。它在云中持续运行,异步处理任务。

注意:有关 Web 角色和工作角色的更多信息,请参阅以下链接

目标

我们这个小练习的目的是展示如何在 Windows Azure Web 角色中执行非 .NET EXE。我们将构建一个 WCF 服务,它将处理 Dicom 图像,并根据输入是单帧还是多帧 Dicom 图像,将其转换为 .jpeg 图像或图像。为了简单起见,我们将假设 Dicom 图像已存储在 Windows Azure Blob 存储中(或者,另一个应用程序模块可以实现将 Dicom 文件上传到 Windows Azure Blob 存储的功能)。转换后的 JPEG 图像将存储在本地存储或 Blob 中,并可通过 REST API 访问。

框图

创建我们的示例应用程序将涉及以下步骤

  1. 将 EXE 作为项目的一部分包含在内
  2. 获取 EXE 路径和参数
  3. 将 Dicom 文件从 Azure Blob 存储下载到本地存储或 Azure 驱动器
  4. 在 Web 角色(WCF 服务)中运行 EXE

1) 将 EXE 作为项目的一部分包含在内

将 EXE 包含在 Web Role 项目中,并更改 EXE 的属性,如下图所示

pic1.jpg

pic2.jpg

2) 获取 EXE 路径和参数

EXE 的输入和输出参数以字符串格式指定,如下所示。

我们需要指定输入的 Dicom 图像路径以及要存储转换后的 JPEG 图像的输出文件夹。

//Get EXE path
Exe in a web role :  EXEPath = Path.Combine(Environment.GetEnvironmentVariable
        ("RoleRoot") + @"\", @"approot\bin\dcm2jpg.EXE");
Exe in a worker  role :  :   EXEPath = Path.Combine
    (Environment.GetEnvironmentVariable("RoleRoot") + @"\", @"approot\dcm2jpg.exe");    
//and arguments

EXEArguements = @"arguments " + output file path + " " + input file path;

Pic3.jpg

非 .NET 和 .NET EXE

我们可以在云中运行任何类型的 EXE。

  1. 非 .NET EXE:C、C++ 等。如果是 C++ EXE,我们需要添加 C++ 运行时库,如 msvcp100.dllmsvcr100.dll
  2. .NET EXE:C#、VB 等。无需添加任何库。

3) 将文件下载到本地存储或 Azure 驱动器

Dicom 到 JPEG 转换器 EXE 将本地文件系统的路径作为输入 Dicom 文件路径

Example: C:\DicomFiles\image1.dcm. 

但是,我们所有的 Dicom 图像都存储在 Azure Blob 存储中。图像只能通过 REST API 或 Blob URL 访问,而我们的 EXE 无法将其识别为有效路径。

我们有两种选择来解决这个问题

  1. 将 Dicom 图像下载到本地存储
  2. 将 Dicom 图像下载到 Azure 驱动器

本地存储

本地存储资源是角色实例正在运行的虚拟机文件系统中的一个预留目录。角色实例中的代码在需要读写文件时可以写入本地存储资源。例如,本地存储资源可以用于缓存服务在 Windows Azure 中运行时可能需要再次访问的数据。本地存储资源在服务定义文件中声明。我们可以在服务定义文件中声明本地存储资源。

要指定本地存储大小,请右键单击角色 -> 属性 -> 本地存储 -> 添加 localStorage。

您可以指定所需的存储空间大小。您可以分配的最大空间是该角色正在运行的虚拟机的大小。

Pic4.jpg

在服务定义文件中,

pic5.jpg

Local storage 元素有 3 个属性

  • 名称
  • sizeInMB:指定此本地存储资源的所需大小
  • cleanOnRoleRecycle:指定当角色实例回收时是否应清除本地存储资源,还是应在角色生命周期中持久化。默认值为 true

在运行时访问本地存储

  1. RoleEnvironment.GetLocalResource 方法返回一个指向已命名 LocalResource 对象的引用。

    代码片段

    //Get local storage path
    LocalResource locRes;
    locRes = RoleEnvironment.GetLocalResource("LocalImageStore");
  2. 要确定本地存储资源目录的路径,请使用 LocalResource.RootPath 属性
    localStoragePath = string.Format(locRes.RootPath);
  3. 如果您的服务在开发环境中运行,本地存储资源将在您的本地文件系统中定义,并且 RootPath 属性将返回一个类似于以下的值

当我们的应用程序在本地运行时,本地存储路径指向我们的文件系统,例如 C:\User\MyApp\localstorage\.

当您的服务部署到 Windows Azure 时,本地存储资源的路径将包含部署 ID,并且 RootPath 属性将返回一个类似于以下的值

C:\Resources\directory\f335471d5a5845aaa4e66d0359e69066.MyService_WebRole.localStoreOne\ 

将图像从 Blob 下载到本地存储的代码是

//get the dcm  file from blob storage into local storage
pic6.jpg

在本地存储中创建一个目录来存储转换后的 JPEG 文件

//Create a new folder for storing converted jpeg files
//Folder name is just a Dicom Image name . Removed .dcm file extension.
pic7.jpg

Azure 驱动器

Windows Azure 驱动器充当本地 NTFS 卷,该卷挂载在服务器的文件系统上,并且可以被运行在角色中的代码访问。写入 Windows Azure 驱动器的数据存储在 Windows Azure Blob 服务中定义的页 blob 中,并在本地文件系统上缓存。由于写入驱动器的数据存储在页 blob 中,因此即使角色实例被回收,数据也会被保留。因此,Windows Azure 驱动器可用于运行必须维护状态的应用程序,例如第三方数据库应用程序。

Windows Azure 管理库提供了 CloudDrive 类来挂载和管理 Windows Azure 驱动器。CloudDrive 类属于 Microsoft.WindowsAzure.StorageClient 命名空间。

一旦 Windows Azure 驱动器被挂载,您就可以通过现有的 NTFS API 访问它。您的 Windows Azure 服务可以通过映射的驱动器号(例如 X:\)读写 Windows Azure 驱动器。

通过 Windows Azure Drive,您在云中运行的 Windows Azure 应用程序可以使用现有的 NTFS API 访问持久化驱动器。这可以大大简化现有 Windows 应用程序向云的迁移。Windows Azure 应用程序可以读写驱动器号(例如 X:\)。

将驱动器挂载为页 blob

  1. 定义文件
    <ConfigurationSettings>
          <Setting name="DicomDriveName"/>
    </ConfigurationSettings>
  2. 配置文件
    <ConfigurationSettings>
               <Setting name="DicomDriveName" value="dicomDrivePageBlob" />
    </ConfigurationSettings>
  3. 创建并挂载驱动器
    CloudDrive drive = null;
                string drivePath = string.Empty;
                CloudPageBlob pageBlob = null;
    
    pageBlob = cloudBlobContainer.GetPageBlobReference
        (RoleEnvironment.GetConfigurationSettingValue("DicomDriveName"));
  4. // Return a reference to the drive backed by the specified page blob. 
    drive = new CloudDrive(pageBlob.Uri, storageAccount.Credentials);
  5. //Creating drive and mounting it.                           
    drive.CreateIfNotExist(2048);
    drivePath = drive.Mount(0, DriveMountOptions.None);
        
    //Gets the name of the drive and path 
    IDictionary<string, Uri> drives = CloudDrive.GetMountedDrives();

4) 在 Web 角色(WCF 服务)中运行 EXE

要运行 EXE,我们需要调用一个新进程。Exepath 作为输入提供以运行 EXE,正如我们已经看到的,EXE 以 Dicom 文件路径作为输入,转换后的 JPEG 图像将存储在指定位置。下面显示了详细的语法

pic8.jpg

结论

我们可以执行任何接受不同输入和输出参数的 EXE。

在工作角色的情况下,队列将发挥作用,因为工作角色需要与 webRole 通信以获取输入。Windows Azure 提供了在 WebRoleWorkerRole 中执行 .NET 或非 .NET EXE 的功能。

参考文献

© . All rights reserved.