0

VC++ 2008、CLR コンソール アプリ、win7 x64 で開発中。

私は MS Office v.12 PIA で .net を使用して Excel の自動化を行っていますが、これは非常にうまくいっています。しかし今、単純な電子メール トランザクションを実行するコードの次の部分を開始しているので、コードで MAPI を動作させようとしています。基本的に、適切なレジストリ キーを読み取って OLMAPI32.DLL ファイルへのフル パスを取得し、その dll 内から LoadLibrary/GetProcAddress を試みます。

ここにスニペットがあります:


using namespace System;
using namespace Microsoft::Office::Interop;
using namespace Microsoft::Win32;

int main(array<System::String ^> ^args)
{
    RegistryKey^ subK = Registry::LocalMachine->OpenSubKey("SOFTWARE\\Clients\\Mail\\Microsoft Outlook");
    String^ mailDll = safe_cast<String^>(subK->GetValue("DLLPathEx"));
    CStringW cStrMailDll = mailDll; //Just to put mailDll in a format that LoadLibrary() can read.

    LPMAPIINITIALIZE mapiInit = NULL;

    HMODULE mapiLib = LoadLibrary(cStrMailDll); // This Returns NULL
    if(mapiLib == NULL)
    {
        printf("\nError: %d\n", GetLastError()); // System Error 193 - ERROR_BAD_EXE_FORMAT
        return 1;
    }

    ...(more code)
    ...

LoadLibrary がシステム エラー 193「%1 は有効な Win32 アプリケーションではありません。」いくつかの調査を行った後、x86 コンパイルを強制するだけでよいことがわかりました。そこで、Configuration Manager に移動し、[アクティブなソリューション プラットフォーム] で、[Win32]、[新規]、および [編集] のみを選択します。そこで、[新規] をクリックし、[新しいプラットフォームを入力または選択] の下に「x86」と入力し、[設定のコピー元] をクリックして [任意の CPU] または適切なものを選択しますが、私の唯一の選択肢は Win32 です。すでに .net をターゲットにしていたためかもしれないと考えたので、その理論をテストするために、今回は Win32 コンソール アプリとして新しいプロジェクトを開始しました。そのタイプのプロジェクトでも、私の唯一の選択肢は Win32 です。私が聞いた x86、x64、Any CPU、および Itanium は、私の VS2008 には存在しません!

だから私はここで途方に暮れています。mapi インターフェイスを使用できるように、VS に exe を x86 としてコンパイルさせるにはどうすればよいですか? または、使用できる OLMAPI32.DLL の 64 ビット バージョンはありますか? MAPI 用の 64 ビット ライブラリがなく、x86 用に環境をセットアップしようとすると VS がヘッドライトを提供する場合、コードで MAPI を動作させるにはどうすればよいでしょうか。私の 64 ビット環境が自動的に MAPI の使用資格を失うとは信じられません。

ありがとう

4

4 に答える 4

1

corflagsを使用して 32 ビット CLR を強制できます。例えばCorFlags.exe /32bit+ file.exe

于 2011-02-08T06:31:14.337 に答える
1

Win32 は Visual Studio C++ の x86 だと思います

于 2011-02-08T06:24:43.020 に答える
0

64 ビット バージョンの MS Outlook に付属する 64 ビット バージョンの MAPI があります。この MSDN の記事では、詳細について説明しています。

于 2011-02-08T06:27:10.883 に答える
0

それで、私を助けてくれた人たち、そして同様の問題を抱えていてこのスレッドに遭遇した可能性のある人たちの啓発のために、これが私がやったことです...

私は純粋な MAPI ルートから抜け出し、代わりに Outlook PIA を使用することにしました。だから今私のコードは次のようになります:

#define nul Reflection::Missing::Value
#include "stdafx.h"
using namespace System;
using namespace Microsoft::Office::Interop;

int main(array<System::String ^> ^args)
{
    // Create the outlook object
    Outlook::Application^ olApp = gcnew Outlook::Application();

    // Get an instance of the MAPI namespace via the outlook object
    Outlook::NameSpace^ olNs = olApp->GetNamespace("MAPI");

    // Log this instance into the MAPI interface
    // Note that this will cause the user to be prompted for which profile
    // to use. At least, it prompts me, and I only have one profile anyway. Whatever.
    // Change the first argument to the name of the profile you want it to use (String)
    // to bypass this prompt. I personally have mine set to "Outlook".
    olNs->Logon(nul, nul, true, true);

    // Get my Inbox
    Outlook::Folder^ defFolder = safe_cast<Outlook::Folder^>(olNs->GetDefaultFolder(Outlook::OlDefaultFolders::olFolderInbox));

    // Get all of the items in the folder (messages, meeting notices, etc.)
    Outlook::Items^ fItems = defFolder->Items;

    // Sort them according to when they were received, descending order (most recent first)
    fItems->Sort("[ReceivedTime]", true);

    // Show me the folder name, and how many items are in it
    printf("\n%s: %d\n", defFolder->Name, fItems->Count);

    // Make an array of _MailItems to hold the messages.
    // Note that this is a _MailItem array, so it will only hold email messages.
    // Other item types (in my case, meeting notices) cannot be added to this array.
    array<Outlook::_MailItem^>^ mail = gcnew array<Outlook::_MailItem^>(fItems->Count);

    int itemNum = 1;
    int offset = 0;

    // If there's anything in my Inbox, do the following...
    if(fItems->Count)
    {
        // Try to grab the first email with "fItems->GetFirst()", and increment itemNum.
        try
        {
            mail[itemNum++] = safe_cast<Outlook::_MailItem^>(fItems->GetFirst());
        }
        // If it threw an exception, it's probably because the item isn't a _MailItem type.
        // Since nothing got assigned to mail[1], reset itemNum to 1
        catch(Exception^ eResult)
        {
            itemNum = 1;
        }

        // Ok, now use "fItems->GetNext()" to grab the rest of the messages
        for(; itemNum <= (fItems->Count-offset); itemNum++)
        {
            try
            {
                mail[itemNum] = safe_cast<Outlook::_MailItem^>(fItems->GetNext());
            }
            // If it puked, then nothing got assigned to mail[itemNum]. On the next iteration of
            // this for-loop, itemNum will be incremented, which means that *this* particular index
            // of the mail array would be left empty. To prevent this, decrement itemNum.
            // Also, if itemNum ever gets decremented, then that will ultimately cause this loop
            // to iterate more times than fItems->Count, causing an out-of-bounds error. To prevent
            // that, increment "offset" each time you decrement "itemNum" to compensate for the
            // offset.
            catch(Exception^ eResult)
            {
                itemNum--;
                offset++;
            }
        }

        // Show me the money!
        for(int i=1; i <= (fItems->Count-offset); i++)
            printf("%d - %s\n", i, mail[i]->Subject);
    }

    olNs->Logoff();
    return 0;
}

入る方法がわかったので、先に進んでプロジェクトを完了できます。助けてくれてありがとう、みんな!

乾杯!d

于 2011-02-10T16:26:38.977 に答える