So I'm working around a macro that should merge some pdf. The code is pretty simple and work well using a dll given by PDFCreator setup (pdfforge.dll), but only on Windows 32Bits (XP or 7).
Here is the code
Dim Pdf As Object
Set Pdf = CreateObject("pdfforge.pdf.pdf")
Pdf.MergePDFFiles_2 FR1, Target & "FusionFR1.pdf", True
Pdf.MergePDFFiles_2 FR2, Target & "FusionFR2.pdf", True
Pdf.MergePDFFiles_2 FR3, Target & "FusionFR3.pdf", True
Pdf.MergePDFFiles_2 FR4, Target & "FusionFR4.pdf", True
Note that FR1, FR2, FR3 and FR4 are just some array of string which contains the path of those pdf I'm trying to merge.
So as I said, this code work well on any computer with Windows 32 Bits, as long as the version of PDFCreator provide the pdfforge.dll. But on a Windows 64 Bits, I've got an "Excel Automation Error" on
Set Pdf = CreateObject("pdfforge.pdf.pdf")
I guess this is a dll which work only on a 32 bits system and by default, a windows 64 bits try to work through a 64 bits environment. So I tried to register this dll for the 32 bits environment through two methods without having satisfying result :
Register 32 bit COM DLL to 64 bit Windows 7
http://www.gfi.com/blog/32bit-object-64bit-environment/
Hope you guys could help me :)
PS: I'm working on Excel 2007
Well I managed to make it work !
I mainly use the Assembly Registration Tool, regasm.exe
First, I've made sure that the dll was not registered anywhere, that is to say both in Framework 32 Bits and 64 Bits, using regasm.exe with the /u argument.
Then I registered the dll in framework\v2.0.50727 using the /codebase argument (I've read from multiple source this argument is the key)
Finally, I've created a text file named excel.exe.config in the root of the excel directory which contains
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
This should force excel to use framework v2.
Hope this could help someone one day ;)
Related
I'm trying to read MachineGuid key from windows registry using QSettings.
The address to that key is
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography".
I'm using the QSettings with QSettings::Native flag as follows.
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography",QSettings::NativeFormat);
I can see all the subfolders and their keys and the value of MachineGuid from regedit.exe but the value function of QSettings does not seem to be working correctly.
the results are as follows:
settings.value("MachineGuid").toString();
returns empty QString.
settings.childGroups();
returns all the subfolders of Cryptography folder correctly.
settings.childKeys();
returns an empty QStringList
settings.allKeys();
returns all the keys inside Cryptography folder including the keys inside of all subfolders except for MachineGuid which is placed inside Cryptography.
I'm using Qt 5.7.1 built statically using Visual Studio 2015 on Windows 10.
I have tried codes that use Window.h header and I have successfully extracted the value but the problem with this approach is that I have to add lots of DLLs to my released software.
For accessing 64 Bit Windows OS with 32 Bit compiled code, the right format would be "Registry64Format" and if accessing 32 Bit OS from 64 compiler the the right format is "Registry32Format"
So, in my case, after setting format to 64 bit, the key could be fetched.
to read key "MachineGuid" on 64 bit OS with 32 bit Compiled code;
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography",
QSettings::Registry64Format);
auto key = settings.childKeys().at(0);
Can I set up a 64-bit registry key to refer to a 32-bit program files path using WiX?
I'm writing a plugin for another piece of software. I want my plugin dll to go in C:\Program Files (x86)\MyPlugin\MyPlugin.dll not in C:\Program Files\MyPlugin\MyPlugin.dll because the dll is 32-bit, not 64-bit.
However, I need the registry key to go in HKLM/Software/Company/Product/Etc.... not in HKLM/Wow6432Node/Software/Company/Product/Etc.... because the process that actually reads the registry key is 64-bit. That 64-bit process reads the registry and launches a 32-bit process to sandbox the dll.
Is there any way to do this? I've tried using different components with different Win64 attribute values, and even putting them in separate component groups. However, I keep getting these build errors (not warnings):
ICE80: This 64BitComponent RegistryComponent uses 32BitDirectory INSTALLFOLDER
A somewhat poor solution, but you could just a custom action to add registry entries, if you don't mind them sticking around after an uninstall.
If you write a custom action in C# you can just do something like this:
using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
// do it
}
If you support 32-bit and 64-bit machines you need two separate MSI setups:
http://blogs.msdn.com/b/heaths/archive/2008/01/15/different-packages-are-required-for-different-processor-architectures.aspx
So your 32-bit install creates any COM entries for any 32-bit Clients and the 64-bit setup has 32-bit and 64-bit components that write to the registry.
http://msdn.microsoft.com/en-us/library/aa367451(v=vs.85).aspx
A rather easy solution to only have one installer version for 32 and 64 bit is to export a .reg file with the keys you want to add (from regedit) and then run a custom action during install, ie:
<CustomAction Id='Add_Registry_Keys' Execute='deferred' Directory='DriverDir' Impersonate='no' ExeCommand='regedit.exe /s "[DriverDir]default.reg' Return='ignore' />
You can suppress ICE errors also, not just warnings. This means you can use Win64 attributes in your x86 msi.
The setting to ignore ICE validations is found in the Project Properties under the Tool Settings tab.
It might not be recommended, but if it works its still better than the alternative of a custom action.
I am a newbie to Windows device drivers. My immediate task is to take an existing 32 bit minifilter driver and port it to 64 bit Windows. My development environment is Windows 7/64 bit, Visual Studio 2012 Ultimate, DDK 7600.16385.1, and SDK 7.1A. The install package is a setup.exe created with InstallShield 2013.
I've found some doc on porting drivers to 64 bit, but it's all about code issues. I haven't been able to find an idiot's guide covering step-by-step instructions for everything else you might have to change, so I decided to take the naive try-it-and-see-what-happens approach and just recompile for 64 bit, with the one exception to that being code signing since I did read somewhere that Win64 requires signed drivers.
The pre-existing build for the driver project used DDKBuild.cmd, and I have modified the properties for the Win64 platform to specify ../scripts/build.cmd -WNETAMD64 free $(OutDir) on the build command line. The compile and link are successful. I've modified the InstallShield project to pull in the signed 64 bit code file instead of the 32 bit code.
The installation appears to run successfully on a 64 bit system (Win2008 R2). There's a two line script that runs during the install:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 .\xxxxxflt.inf
fltmc load xxxxxflt
The rest of our application is actually Java, which makes some JNI calls to a couple of DLLs, one of which calls FilterLoad(). (BTW, the JVM and the DLLs remain 32 bit, but my understanding is that 32 bit code should be able to load a 64 bit driver via FilterLoad(). Please correct me if I'm wrong.) The return from FilterLoad() was ERROR_FILE_NOT_FOUND, and that caused me to notice that, as stated above in the question, the xxxxxxflt.sys file had been copied into SysWOW64\drivers instead of System32\drivers.
I know this is wrong, because Win64 is oppositeland, so System32 is where 64 bit stuff should go and SysWOW64 is where 32 bit stuff should go. What I don't know is why it ended up there. Are there changes necessary in the .inf file in order to identify this as a 64 bit driver? Is there anything I might have to do in the InstallShield project to tell it to build a 64 bit installer or run scripts in a 64 bit engine? Does the script have to do something to force use of the 64 bit version of rundll32? Something else, perhaps?
I haven't seen this specific problem, but I've had issues with this type of "WOW64" thing before. It usually means there is something within your software that is 32-bit and is being run in that mode, so anything you do will end up in the a "Program Files (x86)" or "WOW64" type location. Here is what I think might be happening:
This could have something to do with the way you are calling rundll32.exe. See the following post:
rundll32.exe equivalent for 64-bit DLLs
It's possible that if your InstallSheild installation is creating a 32-bit executable then it is running in WOW mode already which means that it's probably choosing the rundll32.exe that is in the WOW directory, thus the reason your installation ends up there too.
You might look at modifying your script to call the specific one based on the platform, or see if you can change your InstallShield to run as a 64-bit application in non WOW64 mode.
The 32-bit version of our app is unable to send email using MAPISendMail with 64-bit Outlook installed. It returns an error 0x80004005, about which I can find little information beyond the fact that it seems to be a MAPI initialization error.
According to this MSDN document, MAPISendMail is the one exception to the rule that 32-bit apps can't use 64-bit MAPI. And yet it doesn't work (at least with XP and Vista--we haven't tested Win7/8 yet).
Can anyone shed any light on this?
TIA
There are no exceptions: a 32 bit process cannot load a 64 bit dll.
When you have the 64 bit version of Outlook, the 64 bit version of mapi32.dll contains the actual implementation. The 32 bit version of mapi32.dll is a stub that does nothing but return an error.
That's not completely true #DmitryStreblechenko, - at least not for the MAPISendMail function. For that, and only for that, it is possible to build a "Outlook64 Bridge". This will then redirect 32bit MAPISendMail calls to 64bit Outlook. That bridge may look like:
[HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail\Outlook64Bridge]
#="Outlook64Bridge"
"DLLPathEx"="c:\\Windows\\winsxs\\x86_microsof t-windows-mapi_31bf3856ad364e35_6.1.7600.16385_none_ab239772 7b134496\\MAPI32.DLL"
"DLLPath"="c:\\Windows\\winsxs\\x86_microsoft-windows-mapi_31bf3856ad364e35_6.1.7600.16385_none_ab239772 7b134496\\MAPI32.DLL"
IMPORTANT, - you have first check to correct path of your 32bit mapi32.dll!
After adding these lines to the reg you have to set the Outlook64Bridge as your default mail client by:
[HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail]
#="Outlook64Bridge"
It is confirmed to work for simple 32bit applications which use really only the MAPISendMail function.
More information can be found here
Years ago I'had the same problem. I tried and tried again, but no way ... Microsoft blocked some interactions between 32 bit and 64 bit application: you can't even use 64 bit OCX/OLE in a 32 bit application.
The Outlook Bridge solution above (#VMAtm), worked in the beginning, then Microsoft fixed it, and it stoppend working.
In the end I realized a 64 bit application, my bridge application, to connect main 32 bit application with 64 bit outlook:
Main 32 bit application is running ...
Main 32 bit call bridge 64 bit application; mail data (from, to, title, body ...) are stored in a xml-file. The xml file is passed via command-line.
64 bridge applicatio starts, and call MAPI functions.
64 bit outlook does the rest.
This solutions works fine, and I'm quite sure I don't have to struggle with MAPI libraries.
We have an application which, for various reasons, needs to be compiled as both a 32-bit and 64-bit app. The thing is, we want to distribute both setup files (msi) on a single CD. Is there a launch condition or autorun.inf entry that we can use to know which setup.exe to launch? Or do we need to write a separate little exe that gets called by autorun, and which determines the OS, and calls the appropriate setup.exe?
There does not appear to be any 32/64bit detection support inherent in autorun.inf files.
The convention that most applications which supply a 32 and 64 bit MSI follow is similar to the second option you mention.
Create a single 32bit setup.exe application (so that it will run on either platform). Ideally this will be written in C/C++ so that it is as small and quick as possible, and has no dependencies on other libraries/frameworks (eg. static linked).
Detect if you are running on 64bit or not (see sample code for Windows API IsWow64Process function
Execute the appropriate MSI
You can use a custom action to detect the OS, then call the right installer.
I've given an example here: Single MSI to install correct 32 or 64 bit c# application