繁体   English   中英

如何在installshield中传递托管代码dll的参数?

[英]How to pass parameters for a managed code dll in installshield?

我有一个dotnet脚本,用于加密和解密。 我必须在installshield中传递setvalues函数的参数。 我该如何实现? 点网代码如下。 我有程序集(.dll)文件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Security;
using System.Xml;
using System.Collections.Specialized;

namespace EncryptionDecryption
{
    public class EncrptionHelper
    {
        #region Member variables      
        static byte[] entropy = { 0, 8, 2, 3, 5 };
        #endregion

        #region Public Methods

        public static void SetValue(string configFilePathName, string appSettingKey, string appSettingValue)
        {
            appSettingValue = EncryptString(ToSecureString(appSettingValue));
            SetSetting(appSettingKey, appSettingValue, configFilePathName);
        }

        public static string GetValue(string configFilePathName, string appSettingKey)
        {
            string value = GetSetting(appSettingKey, configFilePathName);           
            value = ToInsecureString( DecryptString(value));
            return value;
        }

        #endregion

        #region Private Methods
        private static bool SetSetting(string Key, string Value, string configFilePath)
        {
            bool result = false;
            try
            {
               // System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(configFilePath);
              //  config.AppSettings.File = configFilePath;
               // config.AppSettings.Settings[Key].Value = Value;     
               // config.Save(ConfigurationSaveMode.Modified);

                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(configFilePath);
                xmlDoc.SelectSingleNode("//appSettings/add[@key='" + Key +"']").Attributes["value"].Value = Value;
                xmlDoc.Save(configFilePath);

                ConfigurationManager.RefreshSection("appSettings");

                result = true;
            }
            finally
            { }
            return result;
        }

        private static string GetSetting(string Key, string configFilePath)
        {
            string result = null;
            try
            {
                XmlDocument appSettingsDoc = new XmlDocument();
                appSettingsDoc.Load(configFilePath);
                XmlNode node = appSettingsDoc.SelectSingleNode("//appSettings");
                XmlElement value = (XmlElement)node.SelectSingleNode(string.Format("//add[@key='" + Key + "']"));
                result = (value.GetAttribute("value").ToString());
            }
            finally
            { }
            return result;
        }

        private static SecureString ToSecureString(string input)
        {
            SecureString secure = new SecureString();
            foreach (char c in input)
            {
                secure.AppendChar(c);
            }
            secure.MakeReadOnly();
            return secure;
        }

        private static string ToInsecureString(SecureString input)
        {
            string returnValue = string.Empty;
            IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(input);
            try
            {
                returnValue = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr);
            }
            finally
            {
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
            }
            return returnValue;
        }

        private static string EncryptString(System.Security.SecureString input)
        {
            byte[] encryptedData = System.Security.Cryptography.ProtectedData.Protect(
                System.Text.Encoding.Unicode.GetBytes(ToInsecureString(input)), entropy, System.Security.Cryptography.DataProtectionScope.CurrentUser);

            return Convert.ToBase64String(encryptedData);
        }

        private static SecureString DecryptString(string encryptedData)
        {
            try
            {
                byte[] decryptedData = System.Security.Cryptography.ProtectedData.Unprotect(
                    Convert.FromBase64String(encryptedData),
                    entropy,
                    System.Security.Cryptography.DataProtectionScope.CurrentUser);

                return ToSecureString(System.Text.Encoding.Unicode.GetString(decryptedData));
            }
            catch
            {
                return new SecureString();
            }
        }

        #endregion
    }
}







Update: Action start 14:31:36: Encryption.
MSI (c) (84:40) [14:31:36:525]: Invoking remote custom action. DLL: C:\Users\<username>\AppData\Local\Temp\MSIE259.tmp, Entrypoint: m1
InstallShield: Attempting to load through CLR 4 APIs...
InstallShield: Getting meta host...
InstallShield: Enumerating available runtimes...
InstallShield: Highest available runtime: v4.0.30319
InstallShield: Trying to use highest runtime...
InstallShield: Using highest version runtime...
InstallShield: Loading assembly Security.Encryption from resource 4097
InstallShield: Calling method with parameters [(System.String)C:\Program Files (x86)\<Installdir>\<configfilename>.config, (System.String)VWFPassword, (System.String)]
InstallShield: Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Program Files (x86)\<Installdir>\<configfilename>.config'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials, IWebProxy proxy, RequestCachePolicy cachePolicy)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
   at System.Threading.CompressedStack.runTryCode(Object userData)
   at 

System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
   at System.Xml.XmlTextReaderImpl.OpenUrl()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   at System.Xml.XmlDocument.Load(XmlReader reader)
   at System.Xml.XmlDocument.Load(String filename)
   at Security.Encryption.EncrptionHelper.SetSetting(String appSettingKey, String appsettingValue, String configFilePathName)
   at Security.Encryption.EncrptionHelper.SetValue(String configFilePathName, String appSettingKey, String appSettingValue)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
   at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at InstallShield.ClrHelper.CustomActionHelper.CallMethod(EntryPointInfo info)
   at InstallShield.ClrHelper.CustomActionHelper.RunAction(UInt32 installHandle, Int32 entryNumber, Int64 instanceHandle)
InstallShield: Managed code threw an unhandled exception.

这是我在执行以下屏幕快照中提到的所有步骤并进行一些研发之后收到的错误。 当调用加密管理动作时,提到的目录“ C:\\ Program Files(x86)\\\\。config”存在,但会引发异常。

是的,可以通过以下步骤完成:1-在c#安装程序类中编写所需的功能(确保您正在使用安装程序类)

2-编译并将您的dll添加到installshield(建议为此dll创建一个单独的组件)3-选择组件视图->选择上述组件,然后转到.Net设置部分,将“ .Net Installer类”设置为true。 设置“ .net安装程序类参数”

参数作为键/值对传递,例如

/targetDirectory="[INSTALLDIR]\"

所有步骤都相同,只是添加了屏幕截图。

  • 使用安装程序类和您的加密/解密类创建一个dll。
  • 将dll和配置文件添加到组件(如上所述),如果配置文件已经添加到其他组件,则可以。 无需再次添加。
  • 我已经添加并检索了INSTALLDIR变量作为预定义的参数。 如果要从用户(从某些自定义文本框)接收一些输入,则需要定义自己的变量来存储和传递值作为参数。

  • 使用安装程序类和其他任务所需的逻辑创建dll 安装程序类

  • 创建组件并添加文件 具有安装程序类和依赖项的组件
  • 将dll标记为安装程序类并传递参数 传递参数

这是安装程序类:

using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Configuration.Install;
using System.Collections.Generic;


namespace EncryptionDecryption
{
    [RunInstaller(true)]
    public class InstallerClassDemo : Installer
    {
        private string installationDirectory=string.Empty;
        private string testString=string.Empty ;

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);

            try
            {
                //For testing purpose only.. work only in debug mode when pdb files are deployed as well.
                //Debugger.Break();

                installationDirectory = Context.Parameters["INSTALLDIR"];

                //I believe, the config file must be located in the installation directory if so, then use the following way to compute path

                string configFilePath = Path.Combine(installationDirectory, "myConfigFile.config");
                EncrptionHelper.SetValue(configFilePath, "testKey", "testValue");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

        }

        protected override void OnCommitted(System.Collections.IDictionary savedState)
        {
            base.OnCommitted(savedState);
        }

        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            base.Uninstall(savedState);
        }


    }
}

我认为installshield无法(或需要额外的工作)来读取程序集,但是您可以运行简单的控制台应用程序,该程序会使用installscript消耗程序集,并通过installshield传递参数。

创建简单的控制台应用程序

在支持文件中包括控制台应用程序

复制到安装文件夹或程序集位置,以便控制台应用程序可以访问您的程序集

使用launchappandwait从installscript启动

如果consoleapp.exe不再使用,则将其删除。

暂无
暂无

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

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