在Azure上运行本机代码

在Azure上运行本机代码,azure,Azure,我正在尝试在Azure上运行C可执行文件。我有许多workerRoles,他们不断地检查作业队列。如果队列中有作业,工作角色将根据存储在作业类中的命令行参数以进程的形式运行C可执行文件的实例。C可执行文件通常会创建一些日志文件。我不知道如何访问这些创建的文件。背后的逻辑是什么?创建的文件存储在哪里?谁能给我解释一下吗?我是azure和C#的新手 另一个问题是C可执行文件的所有工作实例都需要读取数据文件。如何分发所需的文件?在Azure land中,您不应该写入文件系统。您应该写入SQLAzure

我正在尝试在Azure上运行C可执行文件。我有许多workerRoles,他们不断地检查作业队列。如果队列中有作业,工作角色将根据存储在作业类中的命令行参数以进程的形式运行C可执行文件的实例。C可执行文件通常会创建一些日志文件。我不知道如何访问这些创建的文件。背后的逻辑是什么?创建的文件存储在哪里?谁能给我解释一下吗?我是azure和C#的新手


另一个问题是C可执行文件的所有工作实例都需要读取数据文件。如何分发所需的文件?

在Azure land中,您不应该写入文件系统。您应该写入SQLAzure、表存储,或者在本例中最有可能写入Blob存储(基本上,我认为您应该将Blob存储视为旧的文件系统)

这是因为:

  • 您可能会有多个实例在运行,最终会在不同的实例(只是虚拟机)上有不同的文件

  • 您的实例可能随时被移动,并且您将丢失文件系统上的信息,因为它不是部署包的一部分


  • 使用这三种存储选项之一将为您的所有实例提供一个可访问的中央存储库,并将在重新部署时持久化

    首先,请意识到在Windows Azure中,您的工作角色只是在Windows 2008服务器环境(SP2或R2)中运行。当你部署你的应用程序时,你也会部署你的C可执行文件(或者从blob存储中获取它,但这要高级一点)。要找出应用程序在磁盘上的位置,请调用
    Environment.GetEnvironmentVariable(“RoleRoot”)
    ——返回路径。您的应用程序通常位于角色root下名为approt的文件夹中。你可以在那里找到你的C可执行文件

    接下来,您将希望应用程序将其文件写入在命令行上指定的输出目录。您可以使用角色的属性在本地VM中设置存储。查看“本地存储”选项卡,并配置命名的本地存储区域:

    现在,您可以在代码中获取该存储区域的路径,并将其作为命令行参数传递:

    var outputStorage = RoleEnvironment.GetLocalResource("MyLocalStorage");
    var outputFile = Path.Combine(outputStorage.RootPath, "myoutput.txt");
    var cmdline = String.Format("--output {0}", outputFile);
    
    以下是使用命令行参数启动myapp.exe进程的示例:

    var appRoot = Path.Combine(Environment.GetEnvironmentVariable("RoleRoot")
                + @"\", @"approot");
    
    var myProcess = new Process()
    {
       StartInfo = new ProcessStartInfo(Path.Combine(appRoot, @"myapp.exe"), cmdline)
       {
          CreateNoWindow = false,
          UseShellExecute = false,
          WorkingDirectory = appRoot
       }
    };
    myProcess.WaitForExit();
    
    通常情况下,您会将CreateNoWindow设置为true,但如果可以看到命令shell窗口,则调试会更容易

    最后一件事:应用程序创建完文件后,您需要:

    • 处理并删除它(它不在一个持久的地方,所以最终会消失)
    • 将存储更改为使用云驱动器(持久存储)
    • 将文件复制到blob(持久存储)
    在生产环境中,您需要添加异常处理,并且可以重新路由要捕获的stdout和stderr。但是这个示例代码应该足以让您开始

    OOPS-还有一个“还有一件事”:在将“myapp.exe”添加到项目中时,请确保转到其属性,并将“复制到输出目录”设置为“始终复制”-否则,myapp.exe文件将不会在Windows Azure中结束,并且您会纳闷为什么事情不起作用

    编辑:将结果推送到blob-一个快速示例

    首先设置一个存储帐户并添加到角色的设置中。假设您将其命名为“AzureStorage”-现在在代码中对其进行设置,获取对blob容器的引用,获取对该容器中blob的引用,然后将文件上载到blob:

            CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("AzureStorage");
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer outputfiles = blobClient.GetContainerReference("outputfiles");
            outputfiles.CreateIfNotExist();
    
            var blobname =  "myoutput.txt";
            var blob = outputfiles.GetBlobReference(blobname);
            blob.UploadFile(outputFile);
    

    那不是真的。您有非持久性和持久性文件存储要写入。有关更多详细信息,请参阅我的答案(稍后)。持久文件存储—是blob存储吗?是的—只需大约10行代码,就可以将NTFS卷装载为云驱动器。看起来就像你的应用程序的驱动器号。但是完全同意本地文件存储-这对于临时存储非常好。在我上面展示的示例中,我们的想法是让应用程序生成输出,然后对输出执行一些操作(将其复制到blob,处理/解析它,等等),而不是指望它永远留在本地存储中。我经常使用本地存储进行处理/输出-非常方便,并允许许多第三方应用程序不加更改地工作。谢谢。您还可以解释一下如何从本地存储中收集创建的文件吗?每个工人都可以将创建的文件复制到blob。然后,其他工作角色或客户端应用程序可以访问该blob,对吗?有关将输出文件推送到blob的快速示例,请参阅更新的答案。同样,您将需要异常处理等。我建议下载Windows Azure平台培训工具包以获得更多详细信息-优秀的教程和实践实验室。这是一个很好的答案,我从这篇文章中学到了很多;但我目前面临的一个问题是创建输出文件。在david的响应中,假设使用“-output”标志来指定输出文件。如果没有国旗呢?也可以使用process.standardoutput将输出作为流获取,但如果可能,我更喜欢使用命令输出重定向操作符“>”、“>>”等。所以问题是:使用cmd操作符可能吗?谢谢你的补充信息。