Skip to main content
 首页 » 编程设计

image之Powershell将图像上传到https://www.artstation.com/

2025年02月15日23powertoolsteam

内容

  • 问题
  • 问题信息
  • 背景/研究
  • 代码块
  • 资源



  • 题:

    如何使用Powershell 编程/自动将图像上传到Artstation \ Project-页面

    上传过程中无需人工输入即可选择文件。仅预定义的媒体数据。如果可以通过Powershell的内置功能来完成,那是首选。

    (请参见下面的网页引用图片“ArtStation上传页面”)



    问题信息:

    环境背景:
  • 操作系统:Windows 10,V:1803,Build:17134.165
  • 平台: PC
  • Powershell: V:5.1.17134.165(桌面版),内部版本:10.0.17134.165,(runas Admin,ExecutionPolicy RemoteSigned)
  • InternetExplorer11: V:11.165.17134.0,UpdateV:11.0.75(KB4339093)
  • 网站: https://www.artstation.com/myartstation/projects/new

  • Artstation的'拖放'部分在中间带有'上传按钮',可打开文件浏览器。 (参见图片ArtStation Upload Page)。

    我看到一些选择。
  • 模拟文件拖动到拖动区域(似乎最简单)
  • 将文件上传到文件浏览器,而无需使用button.click()
  • Button.click()打开文件浏览器,使用单独的Powershell进程捕获文件浏览器,然后导航到并选择要上传的文件。
  • 手动在项目页面上创建/添加新的子级“Art-Work”元素



  • 背景研究:

    嘿,我的第一篇文章。

    我是新的Powershell用户和新程序员。我试图修改生活质量的应用程序,以通过Powershell将图像上传到Artstation。

    我一直在努力寻找解决方法,现在已经有大约两个星期(80多个小时),着眼于数百个无 yield 的孔和部位。也许我不知道我在寻找什么,或者不使用会使我接近答案的查询。因此,我认为是时候该排队了,看看我是否可以得到一些帮助。请像我是个白痴一样向我解释一下。

    我还没有找到有关如何通过Powershell上传图像的任何信息。或至少我听不懂。

    到目前为止,我查看过的所有内容(可能都可以正常运行)都要求我知道将文件发送到哪里。 Invoke-WebRequest / Invoke-RestMethod,Copy-item -sessionDrag-drop javaScript。唯一的问题是我不知道。我唯一拥有的是一个InternetExplorer.application ComObject,其中包含用于“拖放区域”对象和“文件上传按钮”对象的变量。它们都具有我不确定如何设置或需要什么数据结构的方法和属性。

    过去查询:(MFF,IE和Chrome;)

    (我在很多次 session 中都使用过的单词)
    “powershell”,v5,https,上传,图像,文件,artstation,数据传输,onDropEvent,复制项,html标记,html,javascript,拖放功能,输入功能,定义,ondrop,对象格式,https文件传输,转换,图像到叮咬,包,对象,$ ie.document.getelementId('image-input-upload')。value =“。\ $ myImage”,检测,捕获,捕获,跟踪,查找,新的,子的,过程,文件资源管理器,浏览器,导航,选择文件,分配,CTS,上传器,dllhost,sendkeys,AssemblyName,System.Windows.Forms,microsoft.VisualBasic,multiPartContent,设置剪贴板,get-clipboard,fileAsBinaryString



    代码块:

    抱歉,这很难看或没有意义。一个简单的答案是,我不知道我在做什么。我只是在凑巧一些东西,希望它们能起作用。
    #< START_GLOBAL-VARIABLES ># 
     
    #< Secure Document ># 
        #TODO: Clean up memory before setting to null 
        #If Either list exists on script run set to null 
        if($CredList.Keys){$CredList = $null} 
        if($keyWord.Count){$keyWord = $null} 
     
        $CredList = @{} 
        #TODO: remove debug elements 
        #Debug Variable 'easy select has key' 
        $keyWord = @() 
     
        #Pull and Parse Security Data from file 
        $CredBody = Get-Content $CertFile 
        $CredBody | ForEach-Object { 
            $s = $_ -split ", " 
            $keyWord += [REGEX]::Match($s[0], "(?<=www.).*?(?=.com)").groups[0].value 
            $CredList.add($s[0],($s[1],$s[2])) 
        } 
     
    #TODO: remove debug elements 
    #< Debug Option ># 
        #Split security file data and repack in hashtable 
        $keyWord = $keyWord.GetEnumerator() | Sort-Object 
        $httpHost = ($CredList.Keys -imatch $keyWord[0]) 
        $ActiveKey = ($CredList[$CredList.Keys -imatch $keyWord[0]]) 
     
    ###< END_GLOBAL-VARIABLES >### 
     
     
    ###< START_ARTSTATION >### 
     
     
    if($httpHost -imatch 'artstation') 
    { 
        #Todo: Move this to a global scope to reuse for other art sites. 
            #Or create once and use navigate? More/less secure? 
     
        #< Create IE window and poit at Artstation ># 
            $ie = New-Object -ComObject 'InternetExplorer.Application' 
            $ie.visible=$true 
            $ie.navigate($httpHost) 
     
            while($ie.ReadyState -ne 4) {start-sleep -m 100} 
     
     
        ##< START_LOGIN >## 
     
        if($ie.Document.location.href -eq 'https://www.artstation.com/users/sign_in') 
        { 
            #Todo: Encrypt Data Source + pass information securly to webpage 
                #Pass data through windows security window? 
     
            #< Find Desired Cert Elements ># 
                $forms = $ie.Document.forms | ForEach-Object { $_ | ForEach-Object { if($_.id -imatch 'email'-or $_.id -imatch 'password'){return $_ } } } 
     
            # UserName 
                $UserForm = $forms | Where-Object {$_.id -imatch 'email'} 
                $UserForm[0].focus() 
                $ie.Document.activeElement.value = $ActiveKey[0][0] 
     
            # Password 
                $PassForm = $forms | Where-Object {$_.id -imatch 'password'} 
                $PassForm[0].focus() 
                $ie.Document.activeElement.value = $ActiveKey[0][1] 
     
            #Submit Form 
                $submitForm = $ie.Document.forms[1].elements | Where-Object { $_.name -imatch 'button'} 
                $submitForm.focus() 
                $submitForm.click() 
     
                while($ie.ReadyState -ne 4) {start-sleep -m 100} 
        } 
     
        ##< END_LOGIN >## 
     
        #TODO: remove debug elements 
        #< Debug Option ># 
            #Navigate to an Existing or New project page 
            $result = UserPrompt $ie 'Is this a new project?' 'Project Setup' 'Question' {$ie.navigate("https://www.artstation.com/myartstation/projects/new")} {$ie.navigate("https://www.artstation.com/marketplace/manage/products/new")} {$null} 
            while($ie.ReadyState -ne 4) {start-sleep -m 100} 
     
     
        ##< START_UPLOAD >## 
     
     
        #"Drag & Drop Rect" 
            #<div class="well drop-files text-center hidden-sm hidden-xs" id="dropzone"><label class="btn btn-default" for="upload-image-input"><i class="far fa-arrow-from-bottom fa-pad-right"></i>Upload your images</label><div class="separator-sm"></div><div class="text-muted">Upload or drag &amp; drop images</div></div> 
        #Pictures: 
            #<input accept="image/jpeg,image/png,image/gif" id="upload-image-input" multiple="multiple" name="asset[image][]" type="file"> 
        #Video: 
            #<a class="btn btn-default" id="project-add-video-btn" data-toggle="modal" data-target="#add-video-modal" href="#"><i class="far fa-film fa-pad-right"></i>Add Video</a> 
        #SketchFab 
            #<a class="btn btn-default" id="project-add-3dmodel-btn" data-toggle="modal" data-target="#add-3dmodel-modal" href="#"><i class="far fa-cube fa-pad-right"></i>Add Sketchfab</a> 
        #Marmoset 
            #<input multiple="multiple" name="asset[image][]" type="file"> 
        #Pano 
            #<a class="btn btn-default" id="project-add-pano-btn" href="#"><i class="far icon-pano fa-pad-right"></i>Add 360 Pano</a> 
        #ProjectThumbnail 
            #<label class="upload-thumbnail-placeholder" for="upload-thumbnail"><i class="far fa-image fa-2x"></i><div class="small">Upload or drag &amp; drop image</div></label> 
     
     
        ##< START_POPULATE-FIELDS >## 
     
            #< Art-Image ># 
                #Image 
                #Upload 
                #Captions 
                #ImageFitting 
     
            #< Thumbnail-Image ># 
                #Image 
                #Upload 
     
            #< VARIABLES ># 
                $fielfToken = 'title','description', 'medium','Matter', 'adult','albmus','portfolio', 'software', 'Tags' 
                $Values = 'This is my title', 
                          'This painting was done for my Twitch stream! come stop on by some time.', 
                          'digital 3d' 
     
            #< TITLE ># 
                #Text Field [a-z,0-9] 
                $titleToken = $ie.Document.forms | ForEach-Object{ $_ | Where-Object {$_.id -imatch $fielfToken[0]} } 
                $titleToken[0].value = $Values[0] 
     
            #< DESCRIPTION ># 
                #Text Field [a-z,0-9] 
                $descriptionToken = $ie.Document.forms | ForEach-Object{ $_ | Where-Object {$_.id -imatch $fielfToken[1]} } 
                $descriptionToken.value = $Values[1] 
     
            #< MEDIUM ># 
                #dropdown[v] 
                #Pull dropdown choices 
                $mediumToken = $ie.Document.forms | ForEach-Object{ $_ | Where-Object {$_.id -imatch $fielfToken[2]} } 
                #Set medium dropdown to $mediumToken.tostring() 
     
            #< SUBJECT-MATTERr ># 
                #dropdown[v] 
                #Pull dropdown choices 
                #$subjectToken 
                #$subjectToken 
     
            #< ADULT-CONTENT ># 
                #checkbox[x] 
                $adultToken = $ie.Document.forms | ForEach-Object{ $_ | Where-Object {$_.id -imatch $fielfToken[4]} } 
                $adultToken.click() 
     
            #< SOFTWARE ># 
                #Dropdown[v] 
                #Pull software list 
                #$softwareToken 
                #$softwareToken 
     
            #< START_TAGS ># 
                #Option 1: Previous[] pr Previous[X] 
                #Option 2:  'tag1' 'tag2' 'tag3'. . . 
     
                #if Previous ticked checkbox[x] 
                #$foundToken[1].click() 
     
                #if extra Tags = @() 
                #$foundToken[0].length 
     
            #< END_TAGS ># 
     
            #< ALBUMS ># 
                #checkbox[x] list ( AlbumsA[], AlbumsB[], AlbumsC[] ) 
                #Get list of available albums 
                $albumsToken = $ie.Document.forms | ForEach-Object{ $_ | Where-Object {$_.classname -imatch 'col-md-3'} } 
                $albumsToken.click() 
     
            #< START_PORTFOLIO ># 
     
                #ArtStation.com checkbox[x] 
                #$adultToken = $ie.Document.forms | ForEach-Object{ $_ | Where-Object {$_.id -imatch $fielfToken[4]} } 
                #$adulToken.click() 
     
                #MyWebsite checkbox[x] 
                #$adultToken = $ie.Document.forms | ForEach-Object{ $_ | Where-Object {$_.id -imatch $fielfToken[4]} } 
                #$adulToken.click() 
     
            #< END_PORTFOLIO ># 
     
            #< Review ># 
                #click ok when done reviewing 
                #Edit text 
                #Re-upload media 
     
            #< Publish ># 
                #Save.click() 
                #Publish.click() 
     
     
        ##< END_POPULATE-FIELDS >## 
     
     
        #< Logout ># 
     
        #$signOut = $ie.Document.all | Where-Object {$_.classname -imatch 'far fa-sign-out fa-fw fa-pad-right-x2'} 
        #$signOut.focus() 
        #$signOut.click() 
     
        ###< END_ARTSTATION >### 
    } 
    



    资源:

    链接:
    * community.box.com/t5/Platform-and-Development-Forum/Upload-a-file-using-API-in-PowerShell/td-p/35660
    * app.box.com/s/46hwgi48n31g42vuqjk67d01abceypij
    * stackoverflow.com/questions/23059945/upload-a-file-to-box-com-using-powershell
    * get-powershellblog.blogspot.com/2017/09/multipartform-data-support-for-invoke.html
    * blog.majcica.com/2016/01/13/powershell-tips-and-tricks-multipartform-data-requests/
    * blog.majcica.com/2016/01/15/uploading-xl-deploy-dar-package-via-powershell/
    * github.com/react-dropzone/react-dropzone

    请您参考如下方法:

    我知道您很久以前就发布了这个问题,但是您可以通过某种方式使用这种可能的方法。

    function Click-DragControl 
    { 
    Param( 
        [Parameter(Position=0,Mandatory=$TRUE)] 
        [UIAutomation.UiElement] 
        $ObjectDragFrom, 
     
        [Parameter(Position=1,Mandatory=$TRUE)] 
        [UIAutomation.UiElement] 
        $ObjectDragTo 
        ) 
     
    $newX=[Int]($ObjectDragFrom.Current.BoundingRectangle.X+($ObjectDragFrom.Current.BoundingRectangle.Width/2)) 
    $newY=[Int]($ObjectDragFrom.Current.BoundingRectangle.Y+($ObjectDragFrom.Current.BoundingRectangle.Height/2)) 
     
    # In the event the object is inside a collapsible window, or is otherwise off-screen, the pixels we get back will be <0,0>. 
    # So we'll revert to our older method of clicking, because it can crawl through the control and still obtain the item. 
    if ($newX -eq 0 -and $newY -eq 0) 
    { 
        $ObjectDragFrom.Mouse.LeftButtonClick() 
        return $true 
    } 
     
    [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($newX,$newY) 
    $signature= 
    @' 
    [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] 
    public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo); 
    '@ 
    $SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru 
    Try 
    { 
        $SendMouseClick::mouse_event(0x00000002, 0, 0, 0, 0); # Left Mouse Down 
    } 
    Catch 
    { 
        Write-Host("ERROR: Caught an Unhandled Exception in Click-Control. Originating Error:`n$Global:Error[0]") 
        return $FALSE 
    }    
     
    $newX=[Int]($ObjectDragTo.Current.BoundingRectangle.X+($ObjectDragTo.Current.BoundingRectangle.Width/2)) 
    $newY=[Int]($ObjectDragTo.Current.BoundingRectangle.Y+($ObjectDragTo.Current.BoundingRectangle.Height/2)) 
     
    # In the event the object is inside a collapsable window, or is otherwise off-screen, the pixels we get back will be <0,0>. 
    # So we'll revert to our older method of clicking, because it can crawl through the control and still obtain the item. 
    if($newX -eq 0 -and $newY -eq 0){ 
        $ObjectDragTo.Mouse.LeftButtonClick() 
        return $TRUE 
    } 
     
    [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($newX,$newY) 
    $signature= 
    @' 
    [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] 
    public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo); 
    '@ 
    $SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru 
    Try 
    { 
        $SendMouseClick::mouse_event(0x00000004, 0, 0, 0, 0); # Left Mouse Up 
        return $TRUE 
    } 
    Catch 
    { 
        Write-Host("ERROR: Caught an Unhandled Exception in Click-DragControl. Originating Error:`n$Global:Error[0]") 
        return $FALSE 
    } 
    

    }