简体   繁体   English

Windows 服务上传到 AWS S3

[英]Windows Service Upload to AWS S3

I am attempting to create a windows service that periodically checks a folder and uploads any new files that were created into an S3 bucket.我正在尝试创建一个 Windows 服务,该服务会定期检查文件夹并将创建的任何新文件上传到 S3 存储桶中。

It seems that the code is not finding my app.config file and thus not locating the AWSProfileName or any other values.代码似乎没有找到我的 app.config 文件,因此没有找到 AWSProfileName 或任何其他值。

 private bool Upload(List<string> files,string bucketname, RegionEndpoint bucketRegion)
    {
        IAmazonS3 S3Client = new AmazonS3Client(bucketRegion);
        TransferUtility tranUtil = new TransferUtility(S3Client);
        foreach (string file in files)
        {
            tranUtil.Upload(file, bucketname, file.Replace(configFolderPath, ""));
        }
        return true;
    }

Throws me this exception抛出这个异常

System.NullReferenceException: 'Object reference not set to an instance of an object.'

here's my app config too (with values removed)这也是我的应用程序配置(删除了值)

 <?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
  <appSettings>
    <!--AWSProfileName is used to reference an account that has been registered with the SDK.
If using AWS Toolkit for Visual Studio then this value is the same value shown in the AWS Explorer.
It is also possible to register an account using the <solution-dir>/packages/AWSSDK-X.X.X.X/tools/account-management.ps1 PowerShell script
that is bundled with the nuget package under the tools folder.
-->
    <add key="AWSProfileName" value="******" />
    <add key="profile" value="******" />
    <add key="region" value="******" />
    <add key="configuration" value="******" />
    <add key="framework" value="netcoreapp2.1" />
  </appSettings>
</configuration>

I can run the exact same code & app.config in a console app and it will upload the files without any trouble.我可以在控制台应用程序中运行完全相同的代码和 app.config,它将毫无问题地上传文件。

I have also tried to break out the credentials:我还试图打破凭据:

private bool Upload(List<string> files,string bucketname, RegionEndpoint bucketRegion)
        {
            AWSCredentials creds = new StoredProfileAWSCredentials("My AWS Profile Name");
            IAmazonS3 S3Client = new AmazonS3Client(creds, bucketRegion);
            TransferUtility tranUtil = new TransferUtility(S3Client);...

only to get this exception:只是为了得到这个例外:

System.ArgumentException: 'App.config does not contain credentials information. Either add the AWSAccessKey and AWSSecretKey properties or the AWSProfileName property.'

But I DO have the AWSProfileName in the config...但我确实在配置中有 AWSProfileName ......

What's going on with the Windows service that breaks this?打破这一点的 Windows 服务是怎么回事?

Workaround Found找到解决方法

I was following this example我正在关注这个例子

After properly setting up a user's IAM policies you can manually set the access key and secret yourself using an overload of the S3 client constructor.正确设置用户的 IAM 策略后,您可以使用 S3 客户端构造函数的重载自己手动设置访问密钥和机密。 Obviously would want to load that from a file outside of the project.显然想从项目外部的文件中加载它。

        IAmazonS3 S3Client = new AmazonS3Client("IAM USER ACCESS KEY ID", "IAM USER ACCESS KEY SECRET", bucketRegion);

When you build a Windows Service in release mode your app.config file is converted by Visual Studio into a file called yourprogram.exe.config.在发布模式下构建 Windows 服务时,Visual Studio 会将 app.config 文件转换为名为 yourprogram.exe.config 的文件。 Check that this config file contains the connection information.检查此配置文件是否包含连接信息。 This file must be in the same location as the exe.此文件必须与 exe 位于同一位置。

Your config is specifying a profile contained in the SDK Store.您的配置正在指定 SDK Store 中包含的配置文件。 SDK Store profiles are specific to a particular user within a particular host. SDK Store 配置文件特定于特定主机中的特定用户。

When you run the app in a console, you are running it under your user account.当您在控制台中运行该应用程序时,您是在您的用户帐户下运行它。 The app will be able to look in your SDK Store and find the profile and the associated credentials.该应用程序将能够在您的 SDK 商店中查找并找到配置文件和关联的凭据。

When you run the app as a service it will be using a different user account;当您将应用程序作为服务运行时,它将使用不同的用户帐户; it will therefore not be able to find the profile in the SDK Store and so will not be able to connect.因此,它将无法在 SDK Store 中找到配置文件,因此将无法连接。

You could create a credentials file and link that eg:您可以创建一个凭据文件并链接,例如:

    <configuration>
      <appSettings>
        <add key="AWSProfileName" value="xxxxxx"/>
        <add key="AWSProfilesLocation" value="C:\aws_service_credentials\credentials"/>
      </appSettings>
    </configuration>

You use a text editor to manage the profiles in a credentials file.您可以使用文本编辑器来管理凭证文件中的配置文件。 The file should be named credentials and stored in the location you specify in AWSProfilesLocation该文件应命名为凭证并存储在您在 AWSProfilesLocation 中指定的位置

Each profile has the following format:每个配置文件具有以下格式:

[{profile_name}]
aws_access_key_id = {accessKey}
aws_secret_access_key = {secretKey}

More Information:更多信息:
https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/net-dg-config-creds.html https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/net-dg-config-creds.html

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

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