Как использовать 32-битную DLL в среде x64? Это не позволит мне скомпилировать x86! - PullRequest
0 голосов
/ 08 февраля 2011

VC ++ 2008, консольное приложение CLR, разрабатываемое под win7 x64.

Я использую .net с MS Office v.12 PIA для автоматизации Excel, которая идет довольно неплохо. Но теперь я начинаю следующую часть кода, которая включает в себя выполнение некоторых простых транзакций электронной почты, поэтому я пытаюсь заставить MAPI работать в моем коде. По сути, он читает соответствующий раздел реестра, чтобы получить полный путь к файлу OLMAPI32.DLL, а затем пытается загрузить LoadLibrary / GetProcAddress из этой библиотеки DLL.

Вот фрагмент:


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 и на платформе Active Solution я выбираю только Win32, New и Edit. Поэтому я нажимаю «Создать», введите «x86» в разделе «Введите или выберите новую платформу» и нажмите «Копировать настройки из», чтобы выбрать «Любой процессор» или что-то подходящее, но мой единственный выбор - Win32, и! Я подумал, может быть, это потому, что я уже нацеливался на .net, поэтому, чтобы проверить эту теорию, я начал новый проект, на этот раз как консольное приложение Win32. Даже при таком типе проектов мой единственный выбор - Win32. X86, x64, любой процессор и Itanium, о которых я слышал, не существуют в моем VS2008!

Так что я в растерянности. Как заставить VS скомпилировать мой exe-файл как x86, чтобы я мог использовать интерфейс mapi? Или я могу использовать 64-разрядную версию OLMAPI32.DLL? Как, черт возьми, я могу заставить MAPI работать в моем коде, если для него нет 64-битной библиотеки и VS дает мне дорогой свет, когда я пытаюсь настроить свою среду для x86? Я просто не могу поверить, что моя 64-битная среда автоматически лишает меня права использовать MAPI.

Спасибо

Ответы [ 4 ]

1 голос
/ 08 февраля 2011

Вы можете использовать 32-битный CLR, используя corflags .например, CorFlags.exe /32bit+ file.exe

1 голос
/ 08 февраля 2011

Я считаю, что Win32 - это x86 в Visual Studio C ++

0 голосов
/ 10 февраля 2011

Итак, для наставления тех, кто помог мне, а также тех, у кого могут быть подобные проблемы и которые могут возникнуть в этой теме, вот что я в итоге сделал ...

Я выбил из себячистый маршрут 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;
}

Теперь, когда я знаю, как войти, я могу продолжить и закончить свой проект!Спасибо всем за помощь, всем!

Ура!д

0 голосов
/ 08 февраля 2011

Существует 64-разрядная версия MAPI, которая поставляется вместе с 64-разрядной версией MS Outlook. Эта статья MSDN описывает ее подробно.

...